package RPS::Import::BMGSonyPhys;

use strict;

use Date::Calc qw(Days_in_Month Decode_Month);

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

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

use constant {
    CATALOG_NUM            => 1,
    PROD_TYPE              => 2,
    LABEL                  => 5,
    TITLE                  => 7,
    ARTIST                 => 8,
    WHOLESALE              => 11,
    UNITS_SALES            => 12,
    UNITS_RETURNS          => 13,
    UNITS_SALES_NET        => 14,
    UNITS_DISCOUNTED       => 15,
    UNITS_RETURNS_DISCOUNT => 16,
    UNITS_ROYALTY          => 17,
    REVENUE_GROSS          => 18,
    REVENUE_DISCOUNT       => 19,
    REVENUE_SALES          => 20,
    REVENUE_RETURNS        => 21,
    REVENUE_TOTAL          => 22,
};

sub _importLines {
    my $self    = shift;
    my %args    = @_;
    my $version = $self->_version();
    my $sheet   = $args{sheets}->[0];
    my $fileObj = $args{file};
    $fileObj->Physical(1);

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

    my %totals = (
        unitsSales     => 0,
        unitsDiscount  => 0,
        unitsReturns   => 0,
        revenueSales   => 0,
        revenueReturns => 0,
    );
    my %errors  = ();
    my $lineNum = 1;
    foreach my $line (@$sheet) {
        my $unitsReturnsDiscount = $self->numeric( $line->[UNITS_RETURNS_DISCOUNT] );
        next unless ( defined $unitsReturnsDiscount );    # skip non-data rows

        my $unitsReturns   = $line->[UNITS_RETURNS];
        my $unitsSales     = $line->[UNITS_SALES];
        my $unitsSalesNet  = $line->[UNITS_SALES_NET];
        my $unitsDiscount  = $line->[UNITS_DISCOUNTED];
        my $revenueSales   = $line->[REVENUE_SALES];
        my $revenueGross   = $line->[REVENUE_GROSS];
        my $revenueReturns = $line->[REVENUE_RETURNS];
        my $revenueTotal   = $line->[REVENUE_TOTAL];

        my $catNum         = $line->[CATALOG_NUM];
        my $label          = $line->[LABEL];
        my $album          = $line->[TITLE];
        my $artist         = $line->[ARTIST];
        my $wholesalePrice = $line->[WHOLESALE];

        if ( lc $catNum eq 'total' ) {
            if (   $totals{unitsSales} != $unitsSales
                || $totals{unitsDiscount} != $unitsDiscount
                || $totals{unitsReturns} != $unitsReturns
                || abs( $totals{revenueSales} - $revenueSales ) > 1
                || abs( $totals{revenueReturns} - $revenueReturns ) > 1 ) {
                $self->errstr('invalid totals');
                print STDERR "
$totals{unitsSales}     != $unitsSales
$totals{unitsDiscount}  != $unitsDiscount
$totals{unitsReturns}   != $unitsReturns
$totals{revenueSales}   != $revenueSales
$totals{revenueReturns} != $revenueReturns\n";
                return undef;
            }
            last;
        }

        my $config = lc $line->[PROD_TYPE];
        my $prodType =
            $config =~ m/^cd.+(album|ep|single)/ ? RPS::File::Sale::TYPE_CD
          : $config eq 'cd extra album'          ? RPS::File::Sale::TYPE_DBL_CD
          : $config =~ /^cdg\s/                  ? RPS::File::Sale::TYPE_CD
          :    # should this b vcd?
          $config =~ m/cd.+combo/             ? RPS::File::Sale::TYPE_DVD_CD_SET :    # covers cd/dvd combo and dvd/cd combo
            $config =~ m/(dvd|blu\W?ray|umd)/ ? RPS::File::Sale::TYPE_DVD
          : $config eq 'cassette album'       ? RPS::File::Sale::TYPE_CASS
          :                                     '';

        unless ( $prodType || $errors{$config} ) {
            $self->errstr('unknown format');
            print STDERR "config: $config line: $lineNum\n";
            $errors{$config} = 1;
        }

        # verify some of the numbers
        my $OK = 1;
        if ( $unitsSalesNet != $unitsSales - $unitsReturns ) {
            $OK = 0;
            print STDERR "$lineNum net sales units $unitsSalesNet != $unitsSales - $unitsReturns\n";
        }
        if ( $line->[UNITS_ROYALTY] != $unitsSalesNet - $unitsDiscount + $unitsReturnsDiscount ) {
            $OK = 0;
            print STDERR "$lineNum royalty units $line->[UNITS_ROYALTY] != $unitsSalesNet - $unitsDiscount + $unitsReturnsDiscount\n";
        }
        if ( abs( $revenueSales - ( $revenueGross - $line->[REVENUE_DISCOUNT] ) ) > 1 ) {
            $OK = 0;
            print STDERR "$lineNum rev sales $revenueSales != $revenueGross - $line->[REVENUE_DISCOUNT]\n";
        }
        if ( abs( $revenueTotal - ( $revenueSales - $revenueReturns ) ) > 1 ) {
            $OK = 0;
            print STDERR "$lineNum rev total $revenueTotal != $revenueSales - $revenueReturns\n";
        }

        $self->errstr('inconsistent values') unless $OK;

        $totals{unitsSales}     += $unitsSales;
        $totals{unitsDiscount}  += $unitsDiscount;
        $totals{unitsReturns}   += $unitsReturns;
        $totals{revenueSales}   += $revenueSales;
        $totals{revenueReturns} += $revenueReturns;

        my $sales   = $unitsSales - $unitsDiscount;
        my $returns = $unitsReturns - $unitsReturnsDiscount;

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

        $sale->productType($prodType);
        $sale->dateBegin($dateBegin);
        $sale->dateEnd($dateEnd);
        $sale->clientProductID($catNum);
        $sale->artistName($artist);
        $sale->albumName($album);
        $sale->labelName($label);
        $sale->sales($sales);
        $sale->wholesalePrice($wholesalePrice);
        $sale->salesRevenue($revenueSales);
        $sale->returns($returns);
        $sale->returnsRevenue($revenueReturns);
        $sale->totalRevenue($revenueTotal);
        $sale->channel(RPS::File::Sale::CHANNEL_RETAIL);
        $sale->priceLevel(RPS::File::Sale::PLEVEL_FULL);
        $sale->countryCode('AU');
        $sale->currencyCode('AUD');
        $sale->lineNum($lineNum);

        $self->_insertSale( sale => $sale );

        #$args{dumper}($sale);

    } continue {
        $lineNum++;
    }

    return $lineNum;
}

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

    my ( $month, $year );
    foreach my $row (@$lines) {
        if ( $row->[1] =~ m/^period:\s*(\w*)\s+(\d+)/i ) {
            ( $month, $year ) = ( $1, $2 );
            last;
        }
    }

    return undef unless ( $year && $month );

    $month = Decode_Month($month) unless ( $month =~ m/\d+/ );
    $year += 2000 unless ( $year > 1999 );

    return ( sprintf( "%d-%02d-01", $year, $month ), sprintf( "%d-%02d-%d", $year, $month, Days_in_Month( $year, $month ) ) );
}

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