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.
###
