package RPS::Import::eMusicData;

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';

# map version num to the field order
my %field_map = (
    4 => {
        'label'        => 2,
        'vendorid'     => 3,
        'track'        => 4,
        'artist'       => 5,
        'album'        => 6,
        'isrc'         => 7,
        'units'        => 10,
        'splitrevenue' => 12,
        'split'        => 13,
        'currency'     => 5,
    },

    5 => {
        'vendorid' => 0,
        'tracknum' => 1,
        'track'    => 2,
        'artist'   => 4,
        'upc'      => 5,
        'isrc'     => 6,
        'album'    => 7,
        'units'    => 8,
        'price'    => 9,
        'currency' => 5,
    },

    6 => {
        'label'    => 2,
        'vendorid' => 3,
        'track'    => 4,
        'artist'   => 5,

        # 'album' 		=> undef,
        'isrc'         => 6,
        'units'        => 9,
        'splitrevenue' => 11,
        'split'        => 12,
        'currency'     => 5,
    },
    7 => {
        'datasheet' => 1,
        'vendorid'  => 0,
        'isrc'      => 1,
        'upc'       => 2,
        'artist'    => 3,
        'album'     => 4,
        'tracknum'  => 5,
        'track'     => 6,
        'units'     => 8,
        'price'     => 12,
        'currency'  => 5,
    },
    8 => {    # same as version 5 with 2 unused columns prepended
        'vendorid' => 2,
        'tracknum' => 3,
        'track'    => 4,
        'artist'   => 6,
        'upc'      => 7,
        'isrc'     => 8,
        'album'    => 9,
        'units'    => 10,
        'price'    => 11,
        'currency' => 5,
    },
    13 => {    # same as v.7, but the file doesn't have the first (blank) tab
        'vendorid' => 0,
        'isrc'     => 1,
        'upc'      => 2,
        'artist'   => 3,
        'album'    => 4,
        'tracknum' => 5,
        'track'    => 6,
        'units'    => 8,
        'price'    => 12,
        'currency' => 5,
    },
    '13eu' => {    # european sub-version; too difficult to determine from File.pm
        'vendorid' => 0,
        'isrc'     => 1,
        'upc'      => 2,
        'artist'   => 3,
        'album'    => 4,
        'tracknum' => 5,
        'track'    => 6,
        'country'  => 8,
        'units'    => 9,
        'price'    => 11,
        'currency' => 5,
    },
    '13pd' => {    # sub-version with public domain stuff
        'vendorid' => 0,
        'isrc'     => 1,
        'upc'      => 2,
        'artist'   => 3,
        'album'    => 4,
        'tracknum' => 5,
        'track'    => 6,
        'country'  => 8,
        'units'    => 9,
        'price'    => 13,
        'currency' => 5,
    },
    '13tp' => {    # sub-version with total payable to be used in place of price
        'vendorid' => 0,
        'isrc'     => 1,
        'upc'      => 2,
        'artist'   => 3,
        'album'    => 4,
        'tracknum' => 5,
        'track'    => 6,
        'units'    => 8,
        'price'    => 13,
        'currency' => 5,
    },
    14 => {        # like 8 but with country
        'vendorid' => 2,
        'tracknum' => 3,
        'track'    => 4,
        'artist'   => 6,
        'upc'      => 7,
        'isrc'     => 8,
        'album'    => 9,
        'country'  => 10,
        'units'    => 11,
        'price'    => 12,
        'currency' => 5,
    },
    16 => {    # like 14 but with public domain
        'vendorid' => 2,
        'tracknum' => 3,
        'track'    => 4,
        'artist'   => 6,
        'upc'      => 7,
        'isrc'     => 8,
        'album'    => 9,
        'country'  => 10,
        'units'    => 11,
        'price'    => 13,
        'currency' => 5,
    },
    17 => {
        'vendorid' => 0,
        'tracknum' => 5,
        'track'    => 6,
        'artist'   => 3,
        'upc'      => 2,
        'isrc'     => 1,
        'album'    => 4,
        'units'    => 8,
        'price'    => 12,
        'currency' => 5,
    },
    18 => {
        'vendorid' => 2,
        'tracknum' => 4,
        'track'    => 5,
        'artist'   => 7,
        'upc'      => 8,
        'isrc'     => 9,
        'album'    => 10,
        'country'  => 11,
        'units'    => 12,
        'price'    => 18,
        'currency' => 5,
    },
    20 => {
        'vendorid' => 3,
        'tracknum' => 5,
        'track'    => 6,
        'artist'   => 8,
        'upc'      => 9,
        'isrc'     => 10,
        'album'    => 11,
        'country'  => 12,
        'units'    => 13,
        'currency' => 14,
        'price'    => 19,
    },

);

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

#public methods

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

    my $retval   = undef;
    my $fileObj  = $args{file};
    my $fileName = $fileObj->OrigFileName;
    my $version  = $fileObj->VersionNum;
    my $lines    = $args{sheets}->[ $field_map{$version}{datasheet} || 0 ];

    $version = $self->_isEuroFileV13($lines) if ( $version == 13 );

    return unless ( $lines && $fileName && $version );

    my ( $dateBegin, $dateEnd );

    ( $dateBegin, $dateEnd ) = $self->_getDates($fileName);

    unless ( $dateBegin && $dateEnd ) {
        $self->errstr("couldn't get dates");
        return;
    }

    my $country;

    if ( $version eq '13tp' ) {

        # No country column in this version.
        $country = $self->_getCountry($fileName);
        $country = 'FR' if ( $country eq 'FX' );    ## special french thing
        unless ($country) {
            $self->errstr("couldn't get country from filename");
            return;
        }
    }

    my $offsets;
    if ( $version && exists $field_map{$version} ) {
        $offsets = $field_map{$version};
    } else {
        $self->errstr("can't map version");
        return 0;
    }

    my $currencyCode;

    my $linenum = 1;
    foreach my $line (@$lines) {
        if ( $linenum > 1 ) {
            my $prodtype = RPS::File::Sale::TYPE_TRACK;
            my $format   = RPS::File::Sale::FORMAT_VPD;
            my $vendorID = $line->[ $offsets->{'vendorid'} ];

            my $isrc   = Common::Util::normalize_isrc( $line->[ $offsets->{'isrc'} ] );
            my $artist = $line->[ $offsets->{'artist'} ];
            my $album;
            $album = $line->[ $offsets->{'album'} ] if ( exists $offsets->{'album'} );
            my $track = $line->[ $offsets->{'track'} ];
            my ($units) = $line->[ $offsets->{'units'} ] =~ m/^(-?\d+)$/;

            $currencyCode = $line->[ $offsets->{'currency'} ]
              if ( defined $offsets->{'currency'} );

            my ( $label, $upc, $trackNum, $price );

            # !!! Here's a lovely hack.
            #
            if ( lc( $line->[ $offsets->{'currency'} ] ) eq 'all currency in euros' ) {
                $currencyCode = 'EUR';
            } elsif ( 20 != $version ) {
                $currencyCode = undef;
            }

            if ( $version =~ /^(13eu|13pd|14|16|18|20)$/ ) {
                $country = $line->[ $offsets->{'country'} ];
                $country = 'FR' if ( $country eq 'FX' );    ## special french thing
            }

            if ( $version =~ /^(5|7|8|13|13eu|13tp|13pd|14|16|17|18|20)$/ ) {
                $upc      = Common::Util::normalize_upc( $line->[ $offsets->{'upc'} ] );
                $trackNum = $line->[ $offsets->{'tracknum'} ];
                ($price) = $line->[ $offsets->{'price'} ] =~ m/^(-?\d*(\.\d*)?)$/;

                if ( $trackNum && $trackNum == -1 ) {
                    $prodtype = RPS::File::Sale::TYPE_ALBUM;
                }

                $price /= $units if ( $version =~ /^(7|13|13eu|13tp|13pd|17|18|20)$/ and $units > 0 );

                if ($price) {
                    $price = sprintf( "%.8f", $price );

                    # emusic reversed negative figures out of the total paid starting Q2 2004
                    if ( $price < 0 && $dateEnd ge '2004-04-01' ) {
                        if ( $units > 0 ) {

                            # Per FB13514, positive units with negative revenue is a return, so
                            # import the negative revenue as a positive number, and negate
                            # the units information.
                            #
                            $price *= -1;
                            $units *= -1;
                        } else {

                            # This shouldn't happen.
                            #
                            $self->errstr("Detected negative or zero units with negative revenue in line $linenum");
                            return undef;
                        }
                    }
                }
            } else {
                $label = $line->[ $offsets->{'label'} ];
                my ($splitRev) = $line->[ $offsets->{'splitrevenue'} ] =~ m/^(-?\d*(\.\d*)?)$/;
                my ($split)    = $line->[ $offsets->{'split'} ] =~ m/^(\d*\.\d*)$/;

                # emusic reversed negative figures out of the total paid starting Q2 2004
                if ( $units && ( $splitRev > 0 || $dateEnd lt '2004-04-01' ) ) {
                    $price = sprintf( "%.8f", ( $splitRev * $split ) / $units );
                } else {
                    $price = 0;
                }
            }

            if ( $units && defined($price) && $track ) {
                my $sale = RPS::Import::SaleRec->new();

                $sale->productType($prodtype);
                $sale->formatType($format);
                $sale->dateBegin($dateBegin);
                $sale->dateEnd($dateEnd);
                $sale->serviceProductID($vendorID);
                $sale->upc($upc);
                $sale->isrc($isrc);
                $sale->artistName($artist);
                $sale->albumName($album);
                $sale->trackName($track);
                $sale->labelName($label);
                $sale->trackNum($trackNum);
                $sale->units($units);
                $sale->price($price);

                if ( $version =~ /^(13eu|13pd|13tp|14|16|18|20)$/ ) {
                    $sale->countryCode($country);
                } else {
                    $sale->countryCode('US');
                }
                $sale->currencyCode($currencyCode) if ($currencyCode);
                $sale->lineNum($linenum);

                $self->_insertSale( sale => $sale );
            }
        }
        $linenum++;
    }
    $retval = $linenum;

    return $retval;
}

#
# Private methods
#

sub _getDates {
    my $self     = shift;
    my $fileName = shift;

    my $dateBegin;
    my $dateEnd;

    my ( $quarter, $year );
    my $numerical;
    if ( $fileName =~ m/Q([1234])(\d{2})/i ) {
        $quarter = $1;
        $year    = $2;
    } elsif ( $fileName =~ m/Q(1|2|3|4).?(\d+)/i ) {
        $quarter = $1;
        $year    = $2;
    } elsif ( $fileName =~ m/_(\d{4})Q([1234])/ ) {
        $quarter = $2;
        $year    = $1;
    } elsif ( $fileName =~ m/(\d{4}).([1234])\w\w.quarter/ ) {
        $quarter = $2;
        $year    = $1;
    } elsif ( $fileName =~ /Q(\d)(\d{2,4})/ ) {
        $quarter = $1;
        $year    = $2;
    } elsif ( $fileName =~ /(20\d\d)(\d\d)/ ) {
        $numerical = "$2" . "-" . "$1";
    } else {
        return undef;
    }

    if ( $quarter && $year ) {
        if ( $year < 2000 ) {
            $year += 2000;
        }

        ( $dateBegin, $dateEnd ) = $self->SUPER::_getDates( date_begin => "Q$quarter$year", type => "quarter" );
    } elsif ($numerical) {
        ( $dateBegin, $dateEnd ) = $self->SUPER::_getDates( date_begin => $numerical, type => "numerical" );
    }

    return ( $dateBegin, $dateEnd );
}

sub _getCountry {
    my $self     = shift;
    my $fileName = shift;

    my $country;

    if ( $fileName =~ /USD/ ) {
        return "US";
    } elsif ( $fileName =~ /CAD/ ) {
        return "CA";
    }

    #if (($fileName =~ m/(\D{3})_+Q(1|2|3|4)(\w+)/i) || (($fileName =~ m/emusic (\D{3}) \d{4}/i)))
    #{
    #my $currencyCode = $1;
    #if ($currencyCode eq 'CAD')
    #{
    #  $country = 'CA';
    #}
    #elsif ($currencyCode eq 'USD')
    #{
    #  $country = 'US';
    #}
    #else
    #{
    #  return undef;
    #}
    #}
    #else
    #{
    #  return undef;
    #}

    return undef;
}

sub _isEuroFileV13 {
    my $self    = shift;
    my $lines   = shift;
    my $offsets = $field_map{'13'};

    foreach my $line (@$lines) {
        if (   $line->[ $offsets->{'artist'} ] eq 'Artist'
            && $line->[ $offsets->{'album'} ] eq 'Album Title'
            && $line->[ $offsets->{'track'} ] eq 'Track Title' ) {
            if ( $line->[ $offsets->{'units'} ] eq 'Territory' ) {
                if ( $line->[ $offsets->{'price'} ] eq 'Net Royalty Pool Per Track' ) {
                    print STDERR "version: 13pd\n";
                    return '13pd';
                }
                print STDERR "version: 13eu " . ( $line->[ $offsets->{'price'} ] ) . "\n";
                return '13eu';
            }
            if ( $line->[ $offsets->{'price'} + 1 ] =~ m/^Total Payable/ ) {
                print STDERR "version: 13tp\n";
                return '13tp';
            }
            print STDERR "version: 13\n";
            return 13;
        }
    }
}

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