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.
###
