package RPS::Import::ADAPhys;

use strict;

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

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

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

# header record
use constant ROW_DATES => 2;
use constant COL_DATES => 0;

# detail records
my %field_map = (
    1 => {
        SFIELD_LABEL     => 0,
        SFIELD_CONFIG    => 2,
        SFIELD_UPC       => 5,
        SFIELD_ARTIST    => 7,
        SFIELD_TITLE     => 8,
        SFIELD_UNITS     => 10,
        SFIELD_PRICE     => 12,
        RFIELD_LABEL     => 0,
        RFIELD_CONFIG    => 2,
        RFIELD_UPC       => 3,
        RFIELD_ARTIST    => 5,
        RFIELD_TITLE     => 6,
        RFIELD_UNITS     => 8,
        RFIELD_PRICE     => 10,
        RFIELD_RETAIL    => 15,
        RFIELD_WHOLESALE => 16,
    },
    2 => {
        SFIELD_LABEL  => 0,
        SFIELD_CONFIG => 2,
        SFIELD_UPC    => 5,
        SFIELD_ARTIST => 7,
        SFIELD_TITLE  => 8,
        SFIELD_UNITS  => 10,
        SFIELD_PRICE  => 12,
        RFIELD_LABEL  => 0,
        RFIELD_CONFIG => 2,
        RFIELD_UPC    => 5,
        RFIELD_ARTIST => 7,
        RFIELD_TITLE  => 8,
        RFIELD_UNITS  => 10,
        RFIELD_PRICE  => 12,
    },
);

#
# Private methods
#

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

    return undef unless ($sheets);

    my $sales_sheet   = $$sheets[0];
    my $returns_sheet = $$sheets[1];

    my $lineNum = 0;

    ### process sales ###
    my ( $dateBegin, $dateEnd ) = $self->_getDates( $sales_sheet->[ROW_DATES][COL_DATES] );
    unless ( $dateBegin && $dateEnd ) {
        $self->errstr("couldn't get dates from sales tab");
        return undef;
    }

    $lineNum = 1;
    foreach my $line (@$sales_sheet) {
        my $artist      = $line->[ $field_map{$version}{SFIELD_ARTIST} ];
        my $album       = $line->[ $field_map{$version}{SFIELD_TITLE} ];
        my $upc         = Common::Util::normalize_upc( $line->[ $field_map{$version}{SFIELD_UPC} ] );
        my $label       = $line->[ $field_map{$version}{SFIELD_LABEL} ];
        my $config      = $line->[ $field_map{$version}{SFIELD_CONFIG} ];
        my $retailPrice = $line->[ $field_map{$version}{RFIELD_RETAIL} ];
        my $wholesale   = $line->[ $field_map{$version}{RFIELD_WHOLESALE} ];
        my $prodType;

        if ( $config eq "CD" ) {
            $prodType = RPS::File::Sale::TYPE_CD;
        } elsif ( $config eq "A" ) {
            $prodType = RPS::File::Sale::TYPE_LP;
        } elsif ( $config eq "DV" ) {
            $prodType = RPS::File::Sale::TYPE_DVD;
        } elsif ( $config eq "MS" ) {
            $prodType = RPS::File::Sale::TYPE_CAS_SIN;
        } elsif ( $config eq "TC" ) {
            $prodType = RPS::File::Sale::TYPE_CASS;
        } elsif ( $config eq "CM" ) {
            $prodType = RPS::File::Sale::TYPE_CD_SIN;
        } elsif ( $config eq "" || $config =~ m/^cfg$/i ) {
            $lineNum++;
            next;
        } else {
            $self->errstr("unknown format $config line: $lineNum");

            #return undef;
        }

        my ($units) = $line->[ $field_map{$version}{SFIELD_UNITS} ] =~ m/^(-?\d+)$/;
        my ($price) = $line->[ $field_map{$version}{SFIELD_PRICE} ] =~ m/^(-?\d*\.?\d*)$/;

        if ( $prodType && $price && $artist && $album ) {
            my $sale = RPS::Import::SaleRec->new();

            $sale->productType($prodType);
            $sale->dateBegin($dateBegin);
            $sale->dateEnd($dateEnd);
            $sale->upc($upc);
            $sale->artistName($artist);
            $sale->albumName($album);
            $sale->labelName($album);

            $sale->retailPrice($retailPrice);
            $sale->wholesalePrice($wholesale);

            if ( $units < 0 || $price < 0 ) {

                # returns on the sales tab
                $units *= -1 if ( $units < 0 );
                $price *= -1 if ( $price < 0 );

                $sale->returns($units);
                $sale->returnsRevenue($price);
                $sale->totalRevenue( $price * -1 );

            } else {

                # normal sale
                $sale->sales($units);
                $sale->salesRevenue($price);
                $sale->totalRevenue($price);
            }

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

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

    ### process returns ###
    ( $dateBegin, $dateEnd ) = $self->_getDates( $returns_sheet->[ROW_DATES][COL_DATES] );
    unless ( $dateBegin && $dateEnd ) {
        $self->errstr("couldn't get dates from returns tab");
        return undef;
    }

    $lineNum = 1;
    foreach my $line (@$returns_sheet) {
        my $artist      = $line->[ $field_map{$version}{RFIELD_ARTIST} ];
        my $album       = $line->[ $field_map{$version}{RFIELD_TITLE} ];
        my $upc         = Common::Util::normalize_upc( $line->[ $field_map{$version}{RFIELD_UPC} ] );
        my $label       = $line->[ $field_map{$version}{RFIELD_LABEL} ];
        my $config      = $line->[ $field_map{$version}{RFIELD_CONFIG} ];
        my $retailPrice = $line->[ $field_map{$version}{RFIELD_RETAIL} - 2 ];
        my $wholesale   = $line->[ $field_map{$version}{RFIELD_WHOLESALE} - 2 ];
        my $prodType;

        if ( $config eq "CD" ) {
            $prodType = RPS::File::Sale::TYPE_CD;
        } elsif ( $config eq "A" ) {
            $prodType = RPS::File::Sale::TYPE_LP;
        } elsif ( $config eq "DV" ) {
            $prodType = RPS::File::Sale::TYPE_DVD;
        } elsif ( $config eq "MS" ) {
            $prodType = RPS::File::Sale::TYPE_CAS_SIN;
        } elsif ( $config eq "TC" ) {
            $prodType = RPS::File::Sale::TYPE_CASS;
        } elsif ( $config eq "CM" ) {
            $prodType = RPS::File::Sale::TYPE_CD_SIN;
        } elsif ( $config eq "" || $config =~ m/^cfg$/i ) {
            $lineNum++;
            next;
        } else {
            $self->errstr("unknown format $config");
            return undef;
        }

        my ($units) = $line->[ $field_map{$version}{RFIELD_UNITS} ];    # =~ m/^(-?\d+)$/;
        my ($price) = $line->[ $field_map{$version}{RFIELD_PRICE} ];    # =~ m/^(-?\d*\.?\d*)$/;

        $units *= -1 if ( $units < 0 );
        $price *= -1 if ( $price < 0 );

        if ( $prodType && $price != 0 && $artist && $album ) {
            my $sale = RPS::Import::SaleRec->new();

            $sale->productType($prodType);
            $sale->dateBegin($dateBegin);
            $sale->dateEnd($dateEnd);
            $sale->upc($upc);
            $sale->artistName($artist);
            $sale->albumName($album);
            $sale->labelName($label);
            $sale->returns($units);
            $sale->returnsRevenue($price);
            $sale->totalRevenue( $price * -1 );

            #$sale->totalRevenue($price);
            $sale->channel(RPS::File::Sale::CHANNEL_RETAIL);
            $sale->priceLevel(RPS::File::Sale::PLEVEL_FULL);
            $sale->countryCode('US');
            $sale->lineNum($lineNum);

            $sale->retailPrice($retailPrice);
            $sale->wholesalePrice($wholesale);

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

    return $lineNum;
}

sub _getDates {
    my $self      = shift;
    my $dateField = shift || return undef;
    my %dateIndex = (
        January   => 1,
        February  => 2,
        March     => 3,
        April     => 4,
        May       => 5,
        June      => 6,
        July      => 7,
        August    => 8,
        September => 9,
        October   => 10,
        November  => 11,
        December  => 12
    );

    $dateField =~ m#-([\d/]+)\)#;
    my $dateEnd = normalize_date($1);
    my $dateStart;

    # If the dateField is Month Year ( date range )
    if ($dateEnd) {
        return undef unless $dateEnd;

        substr( $dateEnd, -2 ) = Days_in_Month( substr( $dateEnd, 0, 4 ), substr( $dateEnd, 5, 2 ) );
        $dateStart = normalize_date( sprintf( "%d%02d01", substr( $dateEnd, 0, 4 ), substr( $dateEnd, 5, 2 ) ) );
    }

    # Does not have a date range
    else {
        $dateField =~ /(\w+) (\d+)/;
        my $month = $dateIndex{$1} if ($1);
        my $year = $2;

        return unless ( $month && $year );

        my $daysInMonth = Days_in_Month( $year, $month );

        $dateStart = sprintf( "%04d-%02d-%02d", $year, $month, 1 );
        $dateEnd   = sprintf( "%04d-%02d-%02d", $year, $month, $daysInMonth );
    }

    return ( $dateStart, $dateEnd );
}

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