package RPS::Import::RSOutFmt;

use strict;
use Date::Calc qw(Days_in_Month  Add_Delta_Days);

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::Import::Importer;
use base 'RPS::Import::Importer';

# map version num to the field order
my %fieldMap =
(
	1 =>
	{
		'label'	    	=> 0,
		'service_id'	=> 1,
    'service_name'  => 2,
		'country'		=> 3,
		'start_date'	=> 4,
		'end_date'		=> 5,
		'ptype'			=> 6,
		'format'   		=> 7,
		'catno'   		=> 8,
		'upc'   		=> 9,
		'album'	    	=> 11,
		'artist'		=> 12,
		'isrc'			=> 18,
		'tracknum'	   	=> 21,
		'track'	    	=> 22,
		'units'	    	=> 27,
		#'price'	    	=> 28,
		'ext_price'	    	=> 29,
		'currency'	   	=> 30,
		'convrate'	   	=> 31,
		'free'  	   	=> 34,
		'price'         => 36,
	},
    2 =>
    {
        'label'             => 0,
        'service_id'        => 1,
        'service_name'      => 2,
        'outlet'            => 2,
        'country'           => 4,
        'start_date'        => 5,
        'end_date'          => 6,
        'ptype'             => 7,
        'format'            => 8,
        'catno'             => 9,
        'upc'               => 10,
        'album'             => 12,
        'album_artist'      => 13,
        'isrc'              => 19,
        'tracknum'          => 22,
        'track'             => 23,
        'artist'            => 24,
        'units'             => 28,
        'price'             => 29,
        'ext_price'         => 30,
        'currency'          => 31,
        'convrate'          => 32,
        'unit_price'        => 33,
        'free'              => 35,
        'dist_fee'          => 36,
        'net_price'         => 37,
    },
);

#public methods

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

	my $lines = $args{lines};
	my $fileObj = $args{file};
	my $version = $self->_version;
	
	my $currency_code;

    return undef unless (defined $lines && defined $version);

	my $offsets = $fieldMap{$version};

    my $linenum = 1;
    foreach my $line (@$lines)
    {
        if ($line->[$offsets->{label}] eq 'label-name') {
        
            if($version == 2){
                   my $currency_code_str = $line->[$offsets->{unit_price}];
                   
                   $currency_code_str =~ /([^-]+)-unit-price/;
                   
                   $currency_code = uc $1;                   
            }
            $linenum++;
            next;
        }
        
        # There may be sales with revenue but no units.
        my $counterFee = 0;
        
        my $service     = $line->[$offsets->{service_id}];
        my $serviceName = $line->[$offsets->{service_name}] if(defined $offsets->{service_name});
        my $prodtype    = $line->[$offsets->{ptype}];
        my $format      = $line->[$offsets->{format}];
        my $catno   	= $line->[$offsets->{catno}];
        my $upc			= $line->[$offsets->{upc}];
        my $isrc		= $line->[$offsets->{isrc}];
        my $label		= $line->[$offsets->{label}];
        my $artist		= $line->[$offsets->{artist}];
        $artist = $line->[$offsets->{album_artist}] if($artist eq "" && $version == 6);
        my $album		= $line->[$offsets->{album}];
        my $track		= $line->[$offsets->{track}];
        my $tracknum	= $line->[$offsets->{tracknum}];
        my $country 	= $line->[$offsets->{country}];
        my $currency	= $line->[$offsets->{currency}];
        my $convrate	= $line->[$offsets->{convrate}];
        my $free        = $line->[$offsets->{free}] =~ /^(1|Y)$/ ? 1 : 0;
        my $units	    = $line->[$offsets->{units}];
        my $price       = $line->[$offsets->{price}];
        my $ext_price       = $line->[$offsets->{ext_price}];
        
        if(($version == 1) && ($units == 0)){
            $linenum++;
            next;
        }
        
        if (!$price && $version == 1 && $units != 0) 
        {
          $price = $ext_price / $units;
        }
        elsif (!$price && $version == 1 && $units == 0)
        {
          $price = $ext_price;
        }
        elsif($version == 1){
            $price  /= $units;
        }
        else
        {
            # For a while the royalty report generator was reporting the dist-fee percentage
            # as a number between 0 and 100.  Two percent was written out as 2, although it
            # was stored correctly in the database as 0.02.
            #
            # Since we've been inconsistent with it, but the math always seems to have been correct
            # in the data, we'll just back into what the effective unit price. This only comes into
            # play as of version 2

            if ($units)
            {
                $price = $line->[$offsets->{net_price}] / $units;

				$price =~ s/^-0$/0/;

				$free = 1 if ( !$price );
            }
            else
            {
                # because we do some special handling for zero units later
                $price = $line->[$offsets->{net_price}];
            }
        }

        $country        =  $Common::Consts::COUNTRY_CODE{lc($line->[$offsets->{country}])} || $Common::Consts::COUNTRY_TO_CODE{lc($line->[$offsets->{country}])} if(length($line->[$offsets->{country}]) > 2);

        # We'll apply the conversion rate to the price, effectively converting
        # to USD.
        #
        if ($convrate && $version == 1)
        {
            $price *= $convrate;                      
        }
        
        if ($currency_code)
        {
          $currency = $currency_code;
        }

        my ($media_type,$fee);
        $media_type = $line->[$offsets->{'media-type'}] if($offsets->{'media-type'});
        
        
        
        $counterFee = 1 if($units == 0 && $price != 0);
        $units = 1 if($counterFee == 1);
        $price *= -1 if($counterFee == 1 && $price < 0);        

        if ($prodtype && ($units != 0 || $price != 0) && $service ne "service-id")
        {
            my ($dateBegin, $dateEnd) = $self->_getDates($line->[$offsets->{start_date}], $line->[$offsets->{end_date}]);

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

            if($service eq "" && defined $offsets->{service_name} && $serviceName ne "") {
                $service = $self->getServiceID($serviceName);
            }

            unless($service ne "") {
                $self->errstr("Service ID not provided line:".$linenum);
                print STDERR "No serviceID provided line:".$linenum . "\n";
                return undef;
            }
            
            unless($country ne "") {
                $self->errstr("Unknown country:" . $line->[$offsets->{country}]);
                print STDERR "Unknown country:".$line->[$offsets->{country}]."\n";
                return undef;
            }

            unless($format ne "") {
                $self->errstr("No format provided: " .$line->[$offsets->{format}]." line: ". $linenum);
                print STDERR "No format provided: " .$line->[$offsets->{format}]." line: ". $linenum . "\n";
                return undef;
            }

            my $sale = RPS::Import::SaleRec->new();

            $sale->serviceID($service) if($service ne "");
            $sale->productType($prodtype);
            $sale->formatType($format);
            $sale->dateBegin($dateBegin);
            $sale->dateEnd($dateEnd);
            $sale->clientProductID($catno);
            $sale->upc($upc);
            $sale->artistName($artist);
            $sale->albumName($album);
            $sale->labelName($label);
            if ($prodtype eq RPS::File::Sale::TYPE_TRACK) {
                $sale->trackName($track);
                $sale->trackNum($tracknum);
                $sale->isrc($isrc);
            }
            if($media_type) {
                $sale->mediaType($media_type);
            }
            $sale->units($units);
            $sale->price($price);
            $sale->countryCode($country);
            $sale->currencyCode($currency);
            $sale->lineNum($linenum);
            $sale->free($free);

            #$args{dumper}($sale); #cmd line debug 
            $self->_insertSale(sale => $sale);
            
            if ($counterFee == 1) 
            {
              $price  = 0;
              $units  = -1;              
              my $sale = RPS::Import::SaleRec->new();
  
              $sale->serviceID($service) if($service ne "");
              $sale->productType($prodtype);
              $sale->formatType($format);
              $sale->dateBegin($dateBegin);
              $sale->dateEnd($dateEnd);
              $sale->clientProductID($catno);
              $sale->upc($upc);
              $sale->artistName($artist);
              $sale->albumName($album);
              $sale->labelName($label);
              if ($prodtype eq RPS::File::Sale::TYPE_TRACK) {
                  $sale->trackName($track);
                  $sale->trackNum($tracknum);
                  $sale->isrc($isrc);
              }
              if($media_type) {
                  $sale->mediaType($media_type);
              }
              $sale->units($units);
              $sale->price($price);
              $sale->countryCode($country);
              $sale->currencyCode($currency);
              $sale->lineNum($linenum);
              $sale->free($free);
  
              #$args{dumper}($sale); #cmd line debug 
              $self->_insertSale(sale => $sale);            
            }                       
        }
        
        
        
        
        #else { print STDERR "Skip-> l:".$linenum ." pt: " .$prodtype." s: ".$service." u: ".$units." p: ".$price." ar: ".$artist." al: ".$album."<-Skip\n";}
        $linenum++;
    }
	return $linenum;
}

sub _getDates
{
    my $self = shift;
    my $start_date = shift;
    my $end_date = shift;
    my ($month_start,$month_end,$year_start,$year_end,$day_start,$day_end,$dateBegin,$dateEnd);

    # dates of the form yyyy-mm are allowed
    # in that case, set to first day of month for begin date
    # and last day of month for end date
    if($start_date =~ m/(\d{5})/) {
       ($year_start, $month_start, $day_start) = Add_Delta_Days(1900,1,1, $1-2);
    }
    elsif ($start_date =~ m/(\d{4})\D(\d+)\D(\d+)/) {
        $month_start = $2;
        $year_start = $1;
    }
    elsif($start_date =~ m/(\d+)\D(\d+)\D(\d{4})/) {
        $month_start = $1;
        $year_start = $3;
    }
    elsif($start_date =~ m/(\d{4})\D(\d+)/) {
        $month_start = $2;
        $year_start = $1;
    }
    if($end_date =~ m/(\d{5})/) {
        ($year_end, $month_end, $day_end) = Add_Delta_Days(1900,1,1, $1-2);
    }
    elsif($end_date =~ m/(\d{4})\D(\d+)\D(\d+)/) {
        $month_end = $2;
        $year_end = $1;
    }
    elsif($end_date =~ m/(\d+)\D(\d+)\D(\d{4})/) {
        $month_end = $1;
        $year_end = $3;
    }
    elsif($end_date =~ m/(\d{4})\D(\d+)/) {
        $month_end = $2;
        $year_end = $1;
    }
    if($month_end && $year_end && $day_end && $month_start && $year_start && $day_start) {
        $dateBegin = $year_start."-".$month_start."-".$day_start;
        $dateEnd    = $year_end."-".$month_end."-".$day_end;
        return ($dateBegin,$dateEnd);
    }
    elsif($month_end && $year_end && $month_start && $year_start) {
        $dateBegin = $year_start."-".$month_start."-01";
        $dateEnd    = $year_end."-".$month_end."-".Days_in_Month($year_end,$month_end);
        return ($dateBegin,$dateEnd);
    }
    else {
        print STDERR "Improper date format from: ". $dateBegin."\n";
        $self->errstr("Improper date format from: ". $dateBegin);
        print STDERR "Improper date end format from: ". $dateEnd."\n";
        $self->errstr("Improper date end format from: ". $dateEnd);
    }
    return undef;
}

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