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