package RPS::Import::BMGSonyPhys2;

use strict;

use Date::Calc qw(Days_in_Month Decode_Month);

use lib '/app/tools/common/lib';
use Common::Consts qw(%CURRENCY_TO_COUNTRY);
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      => 0,
    ARTIST_TITLE     => 1,
    PROD_TYPE        => 2,
    UNITS_SALES      => 3,
    UNITS_RETURNS    => 4,
    REVENUE_SALES    => 5,
    REVENUE_DISCOUNT => 6,
    REVENUE_RETURNS  => 7,
    REVENUE_TOTAL    => 9,    # should be sum of cols 5,7
    PPD              => 10,
};

my %PROD_TYPES = (
    IACB => RPS::File::Sale::TYPE_CD,
    IACF => RPS::File::Sale::TYPE_CD,
    IACM => RPS::File::Sale::TYPE_CD,
    IADZ => RPS::File::Sale::TYPE_DVD,
    IAEZ => RPS::File::Sale::TYPE_DVD,
    ISCZ => RPS::File::Sale::TYPE_CD,
    IVDZ => RPS::File::Sale::TYPE_DVD,
    IVEZ => RPS::File::Sale::TYPE_DVD,
    LACB => RPS::File::Sale::TYPE_CD,
    LACF => RPS::File::Sale::TYPE_CD,
    LACM => RPS::File::Sale::TYPE_CD,
    LAEZ => RPS::File::Sale::TYPE_DVD,
    LVEZ => RPS::File::Sale::TYPE_DVD,
);

sub _importLines {
    my $self         = shift;
    my %args         = @_;
    my $summarySheet = $args{sheets}->[0];    # will it always b sheet 0?
    my $dataSheet    = $args{sheets}->[2];    # will it always b sheet 2?
    my $fileObj      = $args{file};
    $fileObj->Physical(1);

    my $summary = $self->_getFileSummary($summarySheet);
    unless ( $summary->{dateBegin} && $summary->{dateEnd} ) {
        $self->errstr("couldn't get dates");
        return undef;
    }
    unless ( $summary->{rate} ) {
        $self->errstr("couldn't get rate");
        return undef;
    }
    unless ( $summary->{currency} ) {
        $self->errstr("couldn't get currency");
        return undef;
    }
    unless ( $summary->{country} = $CURRENCY_TO_COUNTRY{ $summary->{currency} } ) {
        $self->errstr("couldn't map currency to country");
        return undef;
    }

    my $sumNetSales = 0;
    my %errors      = ();
    my $lineNum     = 1;
    foreach my $line (@$dataSheet) {
        my $unitsSales   = $line->[UNITS_SALES];
        my $unitsReturns = $line->[UNITS_RETURNS];

        my $revenueSales    = $line->[REVENUE_SALES];
        my $revenueReturns  = $self->numeric( $line->[REVENUE_RETURNS] );
        my $revenueDiscount = $line->[REVENUE_DISCOUNT];
        my $revenueTotal    = $line->[REVENUE_TOTAL];
        my $ppd             = $line->[PPD];

        $revenueReturns *= -1 if ( defined $revenueReturns );

        my $catNum   = $line->[CATALOG_NUM];
        my $artTitle = $line->[ARTIST_TITLE];

        next unless ( $artTitle && defined $revenueReturns );

        my ( $artist, $title ) = $self->_parseDescription($artTitle);

        my $config = uc $line->[PROD_TYPE];
        my $prodType = $PROD_TYPES{$config} || '';

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

        $sumNetSales += $revenueTotal;

        if ( abs( $revenueTotal - ( $revenueSales - $revenueReturns ) ) > 1 && $title ne "" ) {
            print STDERR $lineNum . " " . $revenueTotal . " != " . $revenueSales . "-" . $revenueReturns . "\n";
            $self->errstr( 'mismatched total line:' . $lineNum );
            return undef;
        }

        my $sales =
          ( ( $revenueSales == 0 && $revenueDiscount == 0 ) || $revenueSales + $revenueDiscount == 0 )
          ? 0
          : int( $unitsSales * ( $revenueSales / ( $revenueSales + $revenueDiscount ) ) + 0.5 );

        #print STDERR "returns: $unitsReturns\n";
        my $returns = $unitsReturns == 0 ? $unitsReturns : int( $unitsReturns * ( $revenueReturns / ( $unitsReturns * $ppd ) ) + 0.5 );

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

        $sale->productType($prodType);
        $sale->dateBegin( $summary->{dateBegin} );
        $sale->dateEnd( $summary->{dateEnd} );
        $sale->clientProductID($catNum);
        $sale->artistName($artist);
        $sale->albumName($title);
        $sale->sales($sales);
        $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( $summary->{country} );
        $sale->currencyCode( $summary->{currency} );
        $sale->lineNum($lineNum);

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

        #$args{dumper}($sale);

    } continue {
        $lineNum++;
    }

    if ( abs( $sumNetSales - $summary->{netSales} ) > 1 ) {

        #$self->errstr('total sales mismatch');
        #return 0;
    }

    return $lineNum;
}

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

    my ( $month, $year, $netSales, $netPayable, $currency );
    foreach my $row (@$lines) {
        if ( !$month && $row->[0] =~ m/^(\w+)\s+(\d+)/ ) {
            ( $month, $year ) = ( $1, $2 );
        }

        if ( !$netSales && lc( $row->[0] ) =~ m/^net sales/ ) {
            $netSales = $self->_getFirstNumericColumn( $row, 1 );
        }

        if ( !$netPayable && lc( $row->[0] ) =~ m/^net amount payable to/ ) {
            $netPayable = $self->_getFirstNumericColumn( $row, 1 );
            next;
        }

        # the same label shows up again and has the currency code
        if ( $netPayable && lc( $row->[0] ) =~ m/^net amount payable to/ ) {
            foreach my $cell (@$row) {
                if ( $cell =~ m/^[A-Z]{3}/ ) {
                    $currency = $cell;
                    last;
                }
            }
            last;
        }
    }

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

    $month = Decode_Month($month) unless ( $month =~ m/\d+/ );
    $year += 2000 unless ( $year > 1999 );
    $netSales ||= 1;    # in case it's not set so we don't divide by 0

    return {
        dateBegin => sprintf( "%d-%02d-01", $year, $month ),
        dateEnd   => sprintf( "%d-%02d-%d", $year, $month, Days_in_Month( $year, $month ) ),
        netSales => $netSales,
        rate     => $netPayable / $netSales,
        currency => uc $currency,
    };
}

sub _getFirstNumericColumn {
    my $self  = shift;
    my $row   = shift;
    my $start = shift || 0;

    for ( my $i = $start ; $i <= scalar @$row ; $i++ ) {
        my $numeric = $self->numeric( $row->[$i] );
        return $numeric if ( defined $numeric );
    }

    return undef;
}

sub _parseDescription {
    my $self        = shift;
    my $description = shift;

    $description =~ s/\s*\b\d?dvd-?\s*//i;
    $description =~ s/\s*\dcd(-|\s+|\b)//i;

    $description =~ s/^(.+?)\///;
    my $artist = $1;
    $artist =~ s/^(.+),(.+)$/$2 $1/;
    $artist =~ s/^\s+//;
    $artist =~ s/\s+$//;

    $description =~ s/^\s+//;
    $description =~ s/\s+$//;

    return ( $artist, $description );
}

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