package RPS::Import::Indigo::v1;

use strict;

use lib '/app/tools/common/lib';
use Common::Assert;
use Common::Country;

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

sub _fieldMap {
    {
        dateBegin       => 'A',    # period
        labelName       => 'D',    # label
        configuration   => 'H',    # format
        artistName      => 'I',    # artist
        clientProductID => 'F',    # label-cat-no
        upc             => 'G',    # barcode
        albumName       => 'J',    # title
        countryCode     => 'P',    # country
        sales           => 'R',    # sales_gross_units
        salesRevenue    => 'S',    # sales_gross_EUR
        returns         => 'T',    # returns_units
        returnsRevenue  => 'U',    # returns_EUR
    };
}

sub _unverifiedFieldMap {
    {
        margin      => 'X',        # margin
        payable     => 'Y',        # payable
        handlingFee => 'AA',       # handling_fee_AT
    };
}

sub _headerIdentifier { ( albumName => 'title' ) }

sub physical { 1 }

sub countryCode {
    my $self        = shift;
    my $countryCode = $self->_getByFieldName('countryCode');
    return ( $countryCode =~ /^-$/ ) ? 'DE' : $countryCode;
}

sub saleDates {
    my $self      = shift;
    my $startDate = $self->_getByFieldName('dateBegin');

    if ( $startDate =~ /(\d{4})-(\d{1,2})/ )    # YYYY-MM
    {
        $startDate = sprintf( "%04d-%02d-%02d", $1, $2, 1 );
    }
    return $self->_getDates( date_begin => $startDate );
}

sub productType {
    my $self = shift;
    my $type = $self->_getByFieldName('configuration');

    if ( $type =~ /^cd$/i ) {
        return RPS::File::Sale::TYPE_CD;
    } elsif ( $type =~ /^2cd$/i ) {
        return RPS::File::Sale::TYPE_DBL_CD;
    } elsif ( $type =~ /^lp$/i || $type =~ /^2lp$/i ) {
        return RPS::File::Sale::TYPE_LP;
    } elsif ( $type =~ /^si$/i || $type =~ /^ms$/i ) {
        return RPS::File::Sale::TYPE_LP5;
    }
    $self->fail("Unable to determine product type from ($type)");
}

sub channel { RPS::File::Sale::CHANNEL_RETAIL }

sub priceLevel { RPS::File::Sale::PLEVEL_UNKNOWN }

sub currencyCode { 'EUR' }

sub returns {
    my $self    = shift;
    my $returns = $self->_getByFieldName('returns');
    return abs($returns);
}

sub returnsRevenue {
    my $self    = shift;
    my $revenue = $self->_getByFieldName('returnsRevenue');
    return abs($revenue);
}

sub totalRevenue {
    my $self        = shift;
    my $payable     = $self->_getByFieldName('payable');
    my $handlingFee = $self->_getByFieldName('handlingFee');

    # NOTE: the template says to add the payable and handlingFee to arrive at the
    # net revenue, however this doesn't equal salesRevenue - returnsRevenue, so
    # we'll need to override _validateTotalSum.
    #
    return $payable + $handlingFee;
}

sub _isValidSaleRecord {
    my $self = shift;

    # The line is valid if it has sales or returns, and has an album title
    #
    return ( ( $self->sales != 0 || $self->returns != 0 ) && $self->albumName );
}

# In RPS::Import::Importer, the following methods are normally used to validate
# the total_revenue during sale record validation:
#
#   _validateTotalSum( )
#   _validateReturnTotalSum( )
#   _validateSaleTotalSum( )
#
# Normally, we just use the salesRevenue and returnsRevenue to validate the totalRevenue.
# For Indigo, we need to take the 'margin' and 'handling_fee_AT' into account.
#
sub _validateTotalSum {
    my ( $self, $saleRec ) = @_;

    my $salesRevenue   = $saleRec->salesRevenue   ? $saleRec->salesRevenue   : 0;
    my $returnsRevenue = $saleRec->returnsRevenue ? $saleRec->returnsRevenue : 0;

    # Note: the total revenue being recorded is NOT the same as salesRevenue - returnsRevenue.
    # This is because we're calculating totalRevenue as the payable + handling_fee_AT
    #
    my $totalRevenue = $saleRec->totalRevenue;

    my $handlingFee = $self->_getByFieldName('handlingFee');
    my $margin      = $self->_getByFieldName('margin');

    my $netRevenue = $salesRevenue - $returnsRevenue;    # should be same as col W

    # We expect the following:
    #
    # sales_gross_EUR - returns_EUR  =  (payable - (payable*margin)) + handling_fee
    #
    my $expectedRevenue = $netRevenue * ( 1 - $margin );    # should equal 'payable' column
    $expectedRevenue += $handlingFee;                       # should get us to the total_revenue

    #First check to see if the total revenue is within a penny of the
    #expected revenue, then check to see if the sign of the total revenue
    #matches the sign of $salesRevenue - $returnsRevenue within a penny
    #
    #    if(((abs($totalRevenue) - abs($expectedRevenue)) > .01)||
    #        (($salesRevenue > $returnsRevenue) && (($totalRevenue + .01) < 0))||
    #        (($salesRevenue < $returnsRevenue) && (($totalRevenue - .01) > 0)))
    if (   ( ( abs($totalRevenue) - abs($expectedRevenue) ) > .01 )
        || ( ( $salesRevenue > $returnsRevenue ) && ( ( $totalRevenue - $handlingFee + .01 ) < 0 ) )
        || ( ( $salesRevenue < $returnsRevenue ) && ( ( $totalRevenue - $handlingFee - .01 ) > 0 ) ) ) {
        die Import::ValidationError->new( $saleRec,
"Total revenue $totalRevenue does not equal sales revenue $salesRevenue minus returns revenue $returnsRevenue, expected $expectedRevenue"
        );
    }
}

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

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

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