package RPS::Import::iTunes;

use strict;

use Date::Calc qw(Days_in_Month);

use lib '/app/tools/common/lib';
use Common::Util;
use Common::Consts;

use lib '/app/tools/data_classes/lib';

use lib '/app/tools/rps/lib';
use RPS::File::Sale;
use RPS::DB::Item::MediaType;
use Client::Service;

# map version num to the field order
my %fieldMap = (

# ['Start Date', 'End Date', 'UPC', 'ISRC', 'Vendor Identifier', 'Quantity', 'Royalty Price', 'Extended Price', 'Sale Or Return', 'Apple Identifier', 'Artist', 'Title', 'Label', 'Side', 'Song Or Playlist', 'Account Id', 'Country Of Sale']
    1 => {
        'dateBegin' => 0,
        'dateEnd'   => 1,
        'upc'       => 2,
        'isrc'      => 3,
        'clientID'  => 4,
        'units'     => 5,
        'price'     => 6,
        'vendorID'  => 9,
        'artist'    => 10,
        'title'     => 11,
        'label'     => 12,
        'prodType'  => 14,
        'country'   => 16,
    },

# ['Start Date', 'End Date', 'UPC', 'ISRC', 'Vendor Identifier', 'Quantity', 'Royalty Price', 'Extended Price', 'Currency', 'Sale Or Return', 'Apple Identifier', 'Artist', 'Title', 'Label', 'Side', 'Song Or Playlist', 'Account Id', 'Country Of Sale']
    2 => {
        'dateBegin' => 0,
        'dateEnd'   => 1,
        'upc'       => 2,
        'isrc'      => 3,
        'clientID'  => 4,
        'units'     => 5,
        'price'     => 6,
        'currency'  => 8,
        'vendorID'  => 10,
        'artist'    => 11,
        'title'     => 12,
        'label'     => 13,
        'prodType'  => 15,
        'country'   => 17,
    },

# ['Start Date', 'End Date', 'UPC', 'ISRC', 'Vendor Identifier', 'Quantity', 'Royalty Price', 'Extended Price', 'Currency', 'Sale Or Return', 'Apple Identifier', 'Artist', 'Title', 'Label', 'Side', 'Product Type', 'Account Id', 'Country Of Sale', 'Pre-order', 'Season Pass indicator', 'ISAN\/Other Content ID', 'CMA', 'Customer Price', 'Customer Currency']
    3 => {
        'dateBegin' => 0,
        'dateEnd'   => 1,
        'upc'       => 2,
        'isrc'      => 3,
        'clientID'  => 4,
        'units'     => 5,
        'price'     => 6,
        'currency'  => 8,
        'vendorID'  => 10,
        'artist'    => 11,
        'title'     => 12,
        'label'     => 13,
        'prodType'  => 15,
        'country'   => 17,
    },
    4 => {
        'dateBegin' => 0,
        'dateEnd'   => 1,
        'isrc'      => 2,
        'units'     => 3,
        'price'     => 4,
        'currency'  => 6,
        'artist'    => 7,
        'title'     => 8,
        'country'   => 9,
    },
    5 => {
        'dateBegin' => 0,
        'dateEnd'   => 1,
        'upc'       => 2,
        'isrc'      => 3,
        'clientID'  => 4,
        'units'     => 5,
        'price'     => 6,
        'currency'  => 8,
        'vendorID'  => 10,
        'artist'    => 11,
        'title'     => 12,
        'label'     => 13,
        'prodType'  => 15,
        'country'   => 17,
    },
);

use lib '/app/tools/rps/lib';
use RPS::Import::Importer;
use base 'RPS::Import::Importer';

#public methods

sub _importLines {
    my $self = shift;
    my %args = @_;

    my $retval  = undef;
    my $lines   = $args{lines};
    my $fileObj = $args{file};
    my $version = $fileObj->VersionNum;

    if ( $lines && $version ) {
        unless ( exists $fieldMap{$version} ) {
            $self->errstr('wrong version');
            return;
        }

        my $offsets = $fieldMap{$version};

        my $linenum = 1;
        foreach my $line (@$lines) {

            my ( $currCode, $dateBegin, $dateEnd ) = $self->_getCurrencyAndDates( $line, $offsets );
            unless ( $dateBegin && $dateEnd ) {
                $self->errstr("couldn't get dates");
                return;
            }

            if ( $linenum >= 1 ) {
                my $vendorID   = $line->[ $offsets->{vendorID} ];
                my $clientID   = $line->[ $offsets->{clientID} ];
                my $upc        = Common::Util::normalize_upc( $line->[ $offsets->{upc}   // '' ] );
                my $isrc       = Common::Util::normalize_isrc( $line->[ $offsets->{isrc} // '' ] );
                my $artist     = $line->[ $offsets->{artist} ];
                my $title      = $line->[ $offsets->{title} ];
                my $label      = $line->[ $offsets->{label} ];
                my $iTunesType = lc $line->[ $offsets->{prodType} ];

                my ( $mediatype, $prodtype, $format, $track, $album );

                if ( $iTunesType eq 'v' ) {
                    $prodtype  = RPS::File::Sale::TYPE_TRACK;
                    $format    = RPS::File::Sale::FORMAT_DOWNLOAD;
                    $mediatype = RPS::DB::Item::MediaType::kMediaTypeVideo;
                } elsif ( $iTunesType eq 'j' ) {
                    $prodtype  = ($isrc) ? RPS::File::Sale::TYPE_TRACK : RPS::File::Sale::TYPE_ALBUM;
                    $format    = RPS::File::Sale::FORMAT_DOWNLOADPREMIUM;
                    $mediatype = RPS::DB::Item::MediaType::kMediaTypeVideo;
                } elsif ( $iTunesType eq 'x' ) {
                    $prodtype  = RPS::File::Sale::TYPE_TRACK;
                    $format    = RPS::File::Sale::FORMAT_DOWNLOADUPGRADE;
                    $mediatype = RPS::DB::Item::MediaType::kMediaTypeVideo;
                } elsif ( $iTunesType eq 'p' ) {
                    $prodtype  = RPS::File::Sale::TYPE_ALBUM;
                    $format    = RPS::File::Sale::FORMAT_DOWNLOAD;
                    $mediatype = RPS::DB::Item::MediaType::kMediaTypeAudio;
                } elsif ( $iTunesType eq 's' ) {
                    $prodtype  = RPS::File::Sale::TYPE_TRACK;
                    $format    = RPS::File::Sale::FORMAT_DOWNLOAD;
                    $mediatype = RPS::DB::Item::MediaType::kMediaTypeAudio;
                } elsif ( $iTunesType eq 'h' ) {
                    $prodtype  = RPS::File::Sale::TYPE_TRACK;
                    $format    = RPS::File::Sale::FORMAT_DOWNLOADPREMIUM;
                    $mediatype = RPS::DB::Item::MediaType::kMediaTypeAudio;
                } elsif ( $iTunesType eq 'i' ) {
                    $prodtype  = RPS::File::Sale::TYPE_ALBUM;
                    $format    = RPS::File::Sale::FORMAT_DOWNLOADPREMIUM;
                    $mediatype = RPS::DB::Item::MediaType::kMediaTypeAudio;
                } elsif ( $iTunesType eq 'u' ) {
                    $prodtype  = RPS::File::Sale::TYPE_TRACK;
                    $format    = RPS::File::Sale::FORMAT_DOWNLOADUPGRADE;
                    $mediatype = RPS::DB::Item::MediaType::kMediaTypeAudio;
                } elsif ( $iTunesType eq 'w' ) {
                    $prodtype  = RPS::File::Sale::TYPE_ALBUM;
                    $format    = RPS::File::Sale::FORMAT_DOWNLOADUPGRADE;
                    $mediatype = RPS::DB::Item::MediaType::kMediaTypeAudio;
                } elsif ( $iTunesType eq 'r' ) {
                    $prodtype  = RPS::File::Sale::TYPE_TRACK;
                    $format    = RPS::File::Sale::FORMAT_RINGTONE;
                    $mediatype = RPS::DB::Item::MediaType::kMediaTypeAudio;
                } elsif ( $iTunesType eq 'e' ) {
                    $prodtype  = RPS::File::Sale::TYPE_ALBUM;
                    $format    = RPS::File::Sale::FORMAT_DOWNLOAD;            # Case 13085
                    $mediatype = RPS::DB::Item::MediaType::kMediaTypeVideo;
                } elsif ( $iTunesType eq 'f' ) {
                    $prodtype  = RPS::File::Sale::TYPE_ALBUM;
                    $format    = RPS::File::Sale::FORMAT_TETHERED;            # Case 13085
                    $mediatype = RPS::DB::Item::MediaType::kMediaTypeVideo;
                } elsif ( $iTunesType eq 'pr' ) {
                    $prodtype  = RPS::File::Sale::TYPE_TRACK;
                    $format    = RPS::File::Sale::FORMAT_RINGTONE;
                    $mediatype = RPS::DB::Item::MediaType::kMediaTypeAudio;
                } elsif ( $iTunesType eq 'm' ) {
                    $prodtype  = RPS::File::Sale::TYPE_ALBUM;
                    $format    = RPS::File::Sale::FORMAT_DOWNLOAD;
                    $mediatype = RPS::DB::Item::MediaType::kMediaTypeVideo;
                } elsif ( $iTunesType eq 'd' ) {
                    $prodtype  = RPS::File::Sale::TYPE_ALBUM;
                    $format    = RPS::File::Sale::FORMAT_TETHERED;
                    $mediatype = RPS::DB::Item::MediaType::kMediaTypeVideo;
                } elsif ( '' ne $iTunesType ) {
                    $self->errstr("Unknown iTunes type '$iTunesType' on line $linenum");
                    return undef;
                }

                if ( $version == 4 ) {
                    $prodtype = RPS::File::Sale::TYPE_TRACK if ( $line->[ $offsets->{price} ] < 1 );
                    $prodtype = RPS::File::Sale::TYPE_ALBUM if ( $line->[ $offsets->{price} ] > 1 );
                    $format   = RPS::File::Sale::FORMAT_DOWNLOAD;
                }

                if ( $prodtype eq RPS::File::Sale::TYPE_ALBUM ) {
                    $album = $title;
                } elsif ( $prodtype eq RPS::File::Sale::TYPE_TRACK ) {
                    $track = $title;
                }

                my ($units) = $line->[ $offsets->{units} ];
                my ($price) = $line->[ $offsets->{price} ];
                $price =~ s/\,//;

                my $countryCode;

                if ( $version == 5 ) {
                    $artist //= '';
                    $title //= '';
                }

                if ( $prodtype && $units && $price && defined $artist && defined $title ) {
                    my $f_country = $line->[ $offsets->{country} ];

                    if ( $Common::Consts::CODE_TO_COUNTRY{ uc $f_country } ) {
                        $countryCode = uc $f_country;
                    } else {
                        $countryCode = $Common::Consts::COUNTRY_CODE{ lc $f_country };
                    }

                    unless ($countryCode) {
                        $self->errstr("couldn't get country from $f_country on line $linenum");
                        return undef;
                    }

                    $price =~ s/,//g;
                    my $sale = RPS::Import::SaleRec->new();

                    $sale->serviceID( Client::Service::DSP_ITUNES );
                    $sale->productType($prodtype);
                    $sale->formatType($format);
                    $sale->mediaType($mediatype);
                    $sale->dateBegin($dateBegin);
                    $sale->dateEnd($dateEnd);
                    $sale->serviceProductID($vendorID) if ( defined $offsets->{vendorID} );
                    $sale->clientProductID($clientID)  if ( defined $offsets->{clientID} );
                    $sale->upc($upc)                   if ( defined $offsets->{upc} );
                    $sale->isrc($isrc);
                    $sale->artistName($artist);
                    $sale->albumName($album) if ( $album ne "" );
                    $sale->trackName($track);
                    $sale->labelName($label) if ( defined $offsets->{label} );
                    $sale->units($units);
                    $sale->price($price);
                    $sale->currencyCode($currCode);
                    $sale->conversionRate(0) if ( $currCode ne "USD" );
                    $sale->countryCode($countryCode);
                    $sale->lineNum($linenum);

                    $self->_insertSale( sale => $sale );
                } else {
                    print STDERR "SKIP LINE: $linenum\n";
                }

            }
            $linenum++;
        }
        $retval = $linenum;
    }

    return $retval;
}

#
# Private methods
#

sub _getCurrencyAndDates {
    my ($self, $line, $offsets) = @_;

    my ($currCode, $dateBegin, $dateEnd);

    # skip the "Total" lines at the bottom of the file.
    next if $line->[ $offsets->{dateBegin} ] !~ m/^\d/;

    my $euro = $line->[ $offsets->{dateBegin} ] =~ m/\d?\d\.\d?\d\.\d\d\d\d/;
    my $dateB = Common::Util::normalize_date( $line->[ $offsets->{dateBegin} ], $euro );
    $euro = $line->[ $offsets->{dateEnd} ] =~ m/\d?\d\.\d?\d\.\d\d\d\d/;
    my $dateE = Common::Util::normalize_date( $line->[ $offsets->{dateEnd} ], $euro );

    if ($dateB) {
        $dateBegin = $dateB if ( $dateB < $dateBegin || !$dateBegin );
    }
    if ($dateE) {
        $dateEnd = $dateE if ( $dateE > $dateEnd || !$dateEnd );
    }

   unless ($currCode) {
        if ( exists( $offsets->{currency} ) ) {
            if ( $line->[ $offsets->{currency} ] =~ /^[A-Z]{3}$/ ) {
                $currCode = $line->[ $offsets->{currency} ];
            }
        }
        elsif ( $line->[ $offsets->{country} ] =~ /usa/i ) {
            $currCode = "USD";
        }
        elsif ( $line->[ $offsets->{country} ] =~ /great britain/i ) {
            $currCode = "GBP";
        }
        elsif ( $line->[ $offsets->{country} ] =~ /canada/i ) {
            $currCode = "CAD";
        }
    }

    if ( !$currCode && !exists( $offsets->{currency} ) ) {
        $currCode = "EUR";
    }

    if ( $dateBegin && $dateEnd ) {
        ( $dateBegin, $dateEnd ) = Common::Util::normalize_sales_month_dates( $dateBegin, $dateEnd );
    }

    return ( $currCode, $dateBegin, $dateEnd );
}

###
1;    # Play nicely.
###
