package RPS::Import::ADAPhysical::v6;

use strict;


use lib '/app/tools/common/lib';
use Common::Util qw(normalize_date normalize_upc);
use Common::Country;
use Date::Calc qw(Days_in_Month);
use Data::Dumper;

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

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

use base 'RPS::Import::Importer';

use constant kDataNotFound => -1;

sub _fieldMap {
    {
        'statement summary' => {
            date_row        => 3,
            date_col        => 1,
        },

        'physical sales' => {
            label           => 0,  # A
            configuration   => 7,  # H
            artistName      => 3,  # D
            catalogID       => 2,  # C
            upc             => 8,  # I
            albumName       => 4,  # E
            country         => 12, # M
            wholesalePrice  => 13, # N
            distFee         => 22, # W            
            returnFee       => 23, # X            

            sales           => 14, # O
            returns         => 15, # P
            netUnits        => 16, # Q
            totalRevenue    => 24, # Y            
        },            
    }
}


my %productTypeMap = (
   '1cd'              => RPS::File::Sale::TYPE_CD,
   '2cd'              => RPS::File::Sale::TYPE_CD,
   'single (10")'     => RPS::File::Sale::TYPE_LP5,
   '12" vinyl single' => RPS::File::Sale::TYPE_LP5,
   '7"'               => RPS::File::Sale::TYPE_LP5,
   '12" vinyl'        => RPS::File::Sale::TYPE_LP,
   'cd'               => RPS::File::Sale::TYPE_CD,
   '1cd + 1dvd'       => RPS::File::Sale::TYPE_DVD_CD_SET,
   '12" vinyl x 2'    => RPS::File::Sale::TYPE_LP,
   'lp'               => RPS::File::Sale::TYPE_LP, # FB 10795
   '1lp'              => RPS::File::Sale::TYPE_LP, # FB 10795
);

#
# Private methods
#

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

    my $offsets = $self->_fieldMap;

    my $sheet_count = 0;
    my ($linenum,$serviceID);

    return undef unless (defined $args{sheets} && defined $version);

    my $sheet_names = $args{sheet_names};


    my $dateBegin;
    my $dateEnd;

    my $dateField;

    #----------------------------------------------------
    # Extract the date information from the summary sheet
    #----------------------------------------------------

    # Assume that the first sheet is the summary sheet
    #
    my $sheet = @{ $args{sheets} }[0];

    if( $sheet_count == 0 )
    {
        # The row/column offsets can be skewed if there are blank columns (left)
        # and/or rows (top) in the sales file.  Scan the first 10 rows to see
        # if we can find the date information.
        #
        my $dateFound;
        my $row=0;
        while( !$dateFound && $row < 10 )
        {
            my $data = $offsets->{'statement summary'};

            # Get the date information from the top of each sheet
            #
            my $dateRow = $row;
            my $dateCol = $data->{date_col};

            $dateField = $sheet->[$dateRow][$dateCol];
            if( !$dateField )
            {
                # If sheet has a blank leftmost column, then the column offset will be off by 1
                #
                $dateField = $sheet->[$dateRow][$dateCol-1];
            }

            # Period: DD/MM/YYYY - DD/MM/YYYY
            #         $1 $2  $3    $4 $5  $6
            if ( $dateField =~ m/Period: (\d{1,2})\/(\d{1,2})\/(\d{4}) . (\d{1,2})\/(\d{1,2})\/(\d{4})/ )
            {
                # FB4918: Use the end date to determine the sales period
                #
                my($eDay, $eMonth, $eYear) = ($4, $5, $6);
                $dateBegin = join("-", $eYear, sprintf("%02d",$eMonth), "01"               );
                $dateEnd   = join("-", $eYear, sprintf("%02d",$eMonth), Days_in_Month( $eYear, $eMonth ) );

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

                $dateFound=1;
            }

            $row++;
        }
    }

    #-------------------------
    # Process the detail sheet
    #-------------------------
    $sheet_count = 0;
    foreach my $sheet(@{ $args{sheets} })
    {

        my $sheetName = $sheet_names->[$sheet_count];

        my $sheetIndex = lc $sheetName;

        if ($sheetIndex ne 'physical sales')
        {
            $sheet_count++;
            next;
        }

        my $data = $offsets->{$sheetIndex};

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

            my $sn = $sheet_count + 1;
            my $lineInfo = "Sheet $sn, line $linenum";

            my $cfg = $line->[$data->{configuration}];      
            
            # Defaulting config to CD if blank (FB8937)
            if (!$cfg) {
                $cfg = 'cd';
            }  

            my $catalogNumber = $line->[$data->{catalogID}];
            my $label         = $line->[$data->{label}];
            my $upc           = $line->[$data->{upc}];
            my $artist        = $line->[$data->{artistName}];
            my $title         = $line->[$data->{albumName}];     
            my $wholesale     = $line->[$data->{wholesalePrice}];            
            my $country       = $line->[$data->{country}];

            my $netUnits       = $line->[$data->{netUnits}];
            my $totalRevenue   = $line->[$data->{totalRevenue}];

            # Use the net units and revenue for the sales and returns data
            #
            my $sales          = $line->[$data->{sales}];
            my $salesRevenue   = ($totalRevenue > 0) ? $totalRevenue : 0;
            my $returns        = $line->[$data->{returns}];
            my $returnsRevenue = ($totalRevenue < 0) ? $totalRevenue : 0;

            if( $sales < 0 )
            {
                $returns += $sales;
                $sales = 0;
            }


            # Accept lines with sales or returns with revenue.  Also accept lines with
            # revenue but no sale or return units (these will error out, which is what we want).
            #
            if ( ($sales || $returns || $totalRevenue ) &&
                 $cfg !~ m/format\/config/i &&
                 ($artist || $title || $upc) )
            {

                my $countryCode; 
                if( my $obj = Common::Country->Get($country) )
                {
                    $countryCode = $obj->alpha2();
                }
                else
                {
                   $self->errstr("Unknown country '$country' in line $linenum");
                   return undef;
                }

                my $productType = $productTypeMap{ lc $cfg };
                if ( !$productType )
                {
                   print STDERR "Can't determine product type from '$cfg' in line $linenum";
                   $self->errstr("Can't determine product type from '$cfg' in line $linenum");
                   return undef;
                }                   

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

                if( $returns )
                {
                    $sale->returns(abs($returns));
                    $sale->returnsRevenue(abs($returnsRevenue));
                }
                if( $sales )
                {
                    $sale->sales($sales);
                    $sale->salesRevenue($salesRevenue);
                }

                $sale->totalRevenue($totalRevenue);
                
                my $free = 0;
                my $netUnits = $sales + $returns;
                
                if ($netUnits != 0 && $totalRevenue == 0) {
                    $free = 1;
                }
                
                $sale->free($free);

                $sale->wholesalePrice($wholesale);              
                $sale->productType($productType);
                $sale->dateBegin($dateBegin);
                $sale->dateEnd($dateEnd);
                $sale->labelName($label);
                $sale->albumName($title);
                $sale->serviceProductID($catalogNumber);

                $sale->upc(Common::Util::normalize_upc($upc)) if( $upc );

                $sale->artistName($artist);

                $sale->channel(RPS::File::Sale::CHANNEL_RETAIL);
                $sale->priceLevel(RPS::File::Sale::PLEVEL_FULL);
                $sale->countryCode($countryCode);                            
                $sale->currencyCode('GBP');                            
                
                $sale->lineNum($linenum);

                $self->_insertSale(sale => $sale);
            }
#            else { print STDERR "skip sheet($sheetIndex) l($linenum) ar($artist) title($title) "
#                   ." s($sales), r($returns) sR($salesRevenue) rR($returnsRevenue) tR($totalRevenue)\n"; }
            $linenum++;
        }
        $sheet_count++;
    }

    return $linenum;
}


sub _validateTotalSum {
    my ($self, $saleRec) = @_;
}

sub _validateReturnTotalSum {
    my( $self, $saleRec ) = @_;
}

sub _validateSaleTotalSum {
    my( $self, $saleRec ) = @_;
}

# _getDates: helper method to process US or UK formatted dates.
#
# The end date is checked to see if it's a US or UK-formatted date, with
# the assumption that the day will be be greater than 12 (most likely
# between 28-31). The begin date determines the reporting period, which
# will span one month regardless of the end date specified in the file.
#
sub _getDates {
    my $self  = shift;
    my %args  = @_;

    my $_dateBegin = $args{date_begin};  # YYYY-MM-DD or YYYY-DD-MM
    my $_dateEnd   = $args{date_end};    # YYYY-MM-DD or YYYY-DD-MM

    my $dateBegin = $_dateBegin;

    my( $beginYear, $beginMonth, $beginDay ) = split("-", $_dateBegin);
    my( $endYear,   $endMonth,   $endDay   ) = split("-", $_dateEnd);

    if( $endMonth > 12 )
    {
        $dateBegin = join("-", $beginYear, $beginDay, $beginMonth); # swap the month/day fields
    }

    return $self->SUPER::_getDates( date_begin => $dateBegin );
}

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