package RPS::Import::Red;

use strict;


use Date::Calc qw(Days_in_Month Decode_Month);

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

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

my %fieldMap = (
    1 => {
        label       => 0,
        artist      => 1,
        album       => 2,
        sales       => 3,
        psales      => 4,
        returns     => 5,
        preturns    => 6,
        total       => 8,
    },
    2 => {
        label       => 0,
        artist      => 2,
        album       => 3,
        cpid        => 5,
        catalog     => 6,
        sales       => 7,
        psales      => 8,
        returns     => 9,
        preturns    => 10,
        total       => 12,
    },
    3 => {
        label       => 0,
        artist      => 1,
        album       => 2,
        cpid        => 4,
        catalog     => 5,
        sales       => 6,
        psales      => 7,
        returns     => 8,
        preturns    => 9,
        total       => 11,
    },    
    4 => {
        label       => 0,
        artist      => 1,
        album       => 2,
        cpid        => 4,
        catalog     => 5,
        sales       => 6,
        psales      => 7,
        returns     => 8,
        preturns    => 9,
        total       => 11,
    },    
    5 => {
        date_begin  => 0, # above header

        label       => 0, # detail
        artist      => 1,
        album       => 2,
        #cpid        => 4,
        catalog     => 3,
        sales       => 4,
        psales      => 5,
        returns     => 6,
        preturns    => 7,
        total       => 9,
    },    
    6 => {
        artist      => 2,
        album       => 3,
        cpid        => 5,
        catalog     => 6,
        upc         => 7,
        sales       => 8,
        psales      => 9,
        returns     => 10,
        preturns    => 11,
        total       => 13,
    },    
    7 => {
        artist      => 2,  # C
        album       => 3,  # D
        pfx         => 4,  # E
        catalog     => 7,  # H
        upc         => 6,  # G
        sales       => 8,  # I
        psales      => 9,  # J
        returns     => 10, # K
        preturns    => 11, # L
        total       => 13, # N
    },    
);

my %productTypeMap = (
   'lp'  => RPS::File::Sale::TYPE_LP,
   'dv'  => RPS::File::Sale::TYPE_DVD,
   'vd'  => RPS::File::Sale::TYPE_DVD,
   'cd'  => RPS::File::Sale::TYPE_CD,
   'el'  => RPS::File::Sale::TYPE_CD,
   'oth' => RPS::File::Sale::TYPE_LP5, # See Case 13287
   'mv'  => RPS::File::Sale::TYPE_LP5, # See Case 13287
   'xv'  => RPS::File::Sale::TYPE_LP, # See Case 16197
   'x5'  => RPS::File::Sale::TYPE_CD_SIN, # See Case 16197
   'tp'  => RPS::File::Sale::TYPE_CASS, # See Case 15919
   'cs'  => RPS::File::Sale::TYPE_CASS, # See Case 16029
);

#public methods

sub _isValidSaleRecord {
	my $self = shift;
	my %args = @_;
    my $version = $args{file}->VersionNum();

    if( $version == 4) {
	    return ( defined($self->units) && ($self->trackName || $self->albumName) );
    } else {
        return $self->SUPER::_isValidSaleRecord();
    }
}

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

	my $retval = undef;
    my $lines = $args{lines};
    my $fileObj = $args{file}; 
    my $version = $args{file}->VersionNum();
    my $fileName = $fileObj->OrigFileName;
    my $sheet_names = $args{sheet_names};

    my( $gDateBegin, $gDateEnd ) = $self->_getDates($fileName);
    my $offsets = $fieldMap{$version};

    my $linenum;
    my $sheet_count = 0;

    foreach my $sheet(@{ $args{sheets} })
    {
        $linenum = 1;

        my $dateBegin;
        my $dateEnd;

        # FBoD 4664 - so, if it's version 7 and there is more than a single sheet, skip ones with "report" in the name.
        # the sample had a hidden tab named "Report (14)". awesome.
        if( $version == 7 && scalar @{$args{sheets}} > 1 &&  $sheet_names->[$sheet_count] =~ /report/i )  # summary sheet - skip
        {
            $sheet_count++;
            next;
        }

        foreach my $line (@$sheet)
        {
            my $prodtype    = RPS::File::Sale::TYPE_PHYSICAL;

            my $price_level = ($version == 7 ) ? RPS::File::Sale::PLEVEL_UNKNOWN : RPS::File::Sale::PLEVEL_FULL;

            my $channel     = RPS::File::Sale::CHANNEL_RETAIL;
            my $label       = $line->[$offsets->{label}];
            my $artist      = $line->[$offsets->{artist}];
            my $album       = $line->[$offsets->{album}];
            my $cpid        = $line->[$offsets->{cpid}] if(defined $offsets->{cpid});
            my $catalog     = $line->[$offsets->{catalog}] if(defined $offsets->{catalog});
            my $pfx         = $line->[$offsets->{pfx}] if(defined $offsets->{pfx});
            my $upc;
            my $countryCode;

            if( $version == 7 )
            {
                if( $fileName =~ /CA(?:N)?/i )  # if file has CA or CAN
                {
                    $countryCode = "CA";
                }
                else
                {
                    print STDERR "Couldn't get territory from $fileName\n";
                    $self->errstr("Couldn't get territory from $fileName");
                    return undef;
                }
            }
            else
            {
                $countryCode = "US";
            }
            
            if( !$dateBegin )
            {
                if( defined $offsets->{date_begin} )
                {
                    # Grab date from first row of current sheet
                    #
                    my $_dateField  = $line->[$offsets->{date_begin}];

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

                    unless ($dateBegin && $dateEnd) {
                        $self->errstr("couldn't get dates from $_dateField");
                        print STDERR "couldn't get dates from $_dateField\n";
                        return undef;
                    }
                }
                else
                {
                    # Use the date we pulled from the filename
                    #
                    if( $gDateBegin && $gDateEnd )
                    {
                        $dateBegin = $gDateBegin;
                        $dateEnd   = $gDateEnd;
                    }
                    else
                    {
                        $self->errstr("couldn't get dates from filename $fileName");
                        print STDERR "couldn't get dates from filename $fileName\n";
                        return undef;
                    }
                }
            }


            if( defined $offsets->{upc} )
            {
                $upc = $line->[$offsets->{upc}];
            }
            elsif ($catalog =~ /^\d+$/)
            {
                $upc = $catalog;
                $catalog = '';   
            }


            # Determine the product type
            #
            if ( $version == 5 )
            {
                # The configuration may appear at the end of the catalog#
                # (if it doesn't, then assume it's a CD).
                #
                my $cfg = "cd"; # default
                if ( $catalog =~ m/(\D+)$/ )
                {
                    $cfg = $1;
                    $prodtype = $productTypeMap{ lc $cfg };
                }

                # The country code comes from the sheet name
                #
                if( $sheet_names->[$sheet_count] =~ /ca/i )
                {
                    $countryCode = 'CA';
                }
                elsif( $sheet_names->[$sheet_count] !~ /us/i )
                {
                    print STDERR "Unrecognized sheet name: ". $sheet_names->[$sheet_count] . "\n";
                    $self->errstr("Can't determine country from ". $sheet_names->[$sheet_count] );
                    return undef;
                }
            }
            else
            {
                if ( $cpid && 'SEL-CFG' ne $cpid )
                {
                    my($code, $cfg) = split("-",$cpid);
                    $prodtype = $productTypeMap{ lc $cfg };
                    if ( !$prodtype )
                    {
                        print STDERR "Can't determine product type from '$cpid' in line $linenum";
                        $self->errstr("Can't determine product type from '$cpid' in line $linenum");
                        return undef;
                    }
                }
                elsif( $pfx &&  '' ne $pfx  && 'Pfx' ne $pfx )
                {
                    if( $pfx =~ /^lp$/i )
                    {
                        $prodtype = RPS::File::Sale::TYPE_LP;
                    }
                    elsif( $pfx =~ /^(cd|el)$/i )
                    {
                        $prodtype = RPS::File::Sale::TYPE_CD;
                    }
                    elsif( $pfx =~ /^si$/i )
                    {
                        $prodtype = RPS::File::Sale::TYPE_LP5;
                    }
                    elsif( $pfx =~ /^vd$/i )
                    {
                        $prodtype =  RPS::File::Sale::TYPE_DVD;
                    }
                    else
                    {
                        print STDERR "Can't determine product type from pfx '$pfx' in line $linenum\n";
                        $self->errstr("Can't determine product type from '$pfx' in line $linenum");
                        return undef;
                    }
                }
            }


            if ($album eq "Various") {
                $album  = $artist;
                $artist = "Various";
            }
       
            my ($sales)	   	= $line->[$offsets->{sales}] =~ m/^(-?\d+)$/;
            my ($psales)  	= $line->[$offsets->{psales}] =~ m/^(-?\d*\.?\d*)$/;
            my ($returns) 	= $line->[$offsets->{returns}] =~ m/^(-?\d+)$/;
            my ($preturns)  = $line->[$offsets->{preturns}] =~ m/^(-?\d*\.?\d*)$/;
            my ($total)    	= $line->[$offsets->{total}] =~ m/^(-?\d*\.?\d*)$/;

            if ( $sales <= 0 && $psales <= 0 )
            {
                $returns  += $sales;
                $preturns += $psales;

                $sales  = 0;
                $psales = 0;
            }

            if ( $returns > 0 && $preturns > 0 )
            {
                $sales  += $returns;
                $psales += $preturns;

                $returns  = 0;
                $preturns = 0;
            }

            if ( $sales > 0 && $psales < 0 )
            {
                $preturns += $psales;
                $psales = 0;
            }

            $returns  = $returns * -1;
            $preturns = $preturns * -1;

            if ($prodtype && ($sales || $returns) && $album)
            {
                if( !($sales || $returns) && $total )
                {
                    $self->errstr("Line $linenum: $total revenue with no units");
                }

                my $sale = RPS::Import::SaleRec->new();
     
                $sale->productType($prodtype);
                $sale->dateBegin($dateBegin);
                $sale->dateEnd($dateEnd);
                $sale->clientProductID($cpid) if(defined $offsets->{cpid});
                $sale->serviceProductID($catalog) if(defined $offsets->{catalog});
                $sale->upc($upc);
                $sale->labelName($label);
                $sale->artistName($artist);
                $sale->albumName($album);
                $sale->sales($sales);
                $sale->returns($returns);
                $sale->salesRevenue($psales);
                $sale->returnsRevenue($preturns);
                $sale->totalRevenue($total);
                $sale->priceLevel($price_level);
                $sale->channel($channel);
                $sale->countryCode($countryCode);
                $sale->currencyCode('USD');
                $sale->lineNum($linenum);
        
                ##$args{dumper}($sale);  ## for cmd-line testing
                $self->_insertSale(sale => $sale);
            }
            $linenum++;
        }
        $sheet_count++;
    }
	return $linenum;
}

#
# Private methods
#


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

	my ($dateBegin, $dateEnd,$month,$year);
    if ($date =~ m/(september|october|november|december|january|february|march|april|may|june|july|august)[\s_]*(\d{4})/i) {
        $month = Decode_Month($1);
        $year  = $2;
        $dateBegin = sprintf("%04d-%02d-%02d", $year, $month, 1);
        $dateEnd   = sprintf("%04d-%02d-%02d", $year, $month, Days_in_Month($year, $month));
    }
    elsif ($date =~ m/[\s_](\w{3,4}[\s_]\d{4})/i) {
        my $d = new Common::Date( $1 );
        $dateBegin = $d->monthBegin;
        $dateEnd   = $d->monthEnd;
    }
    elsif ($date =~ m/[\s_](\w{3,4})(\d{4})/i) {
        my $d = new Common::Date( $1 . " " . $2 );
        $dateBegin = $d->monthBegin;
        $dateEnd   = $d->monthEnd;
    }    
    elsif ($date =~ m/^([a-z]+)(\d{4})/) {

        $month = Decode_Month($1);
        $year  = $2;
        $dateBegin = sprintf("%04d-%02d-%02d", $year, $month, 1);
        $dateEnd   = sprintf("%04d-%02d-%02d", $year, $month, Days_in_Month($year, $month));

    } else {
        return undef;
    }

	return ($dateBegin, $dateEnd);
}

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