package BookPub::Import::Importer::Amazon::Version17;

use strict;

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

use lib '/app/tools/bookpub/lib';
use base 'BookPub::Import::Importer';

use Date::Calc qw( Add_Delta_YM );

sub _headerIdentifier { ( serviceProductID => 'ASIN' ) }

sub _fieldMap {
    {
        serviceProductID       => 'B',
        currencyCode           => 'U',
        dateBegin              => 'A',
        rFormat                => 'I',
        isbn                   => 'E',
        rTitle                 => 'F',
        rAuthor                => 'G',
        rImprint               => 'H',
        rUnits                 => 'L',
        rSales                 => 'J',
        rReturns               => 'K',
        rAdjustments           => 'N',
        rPurchasePrice         => 'O',
        rPurchasePriceCurrency => 'P',
        rListPrice             => 'Q',
        rListPriceCurrency     => 'R',
        rDiscount              => 'S',
        rRevenue               => 'T',
        rChannel               => 'V',
    };
}

sub _useIsSaleRec              { 1 }
sub _autoParseTitleAndSubtitle { 1 }
sub priceType                  { 'rrp' }
sub purchaseType               { BookPub::DB::Item::Sale::kPurchaseTypeDownload }
sub productType                { BookPub::DB::Item::Sale::kProductTypeEBook }

sub _processLine {
    my $self = shift;
    my $id   = $self->serviceProductID();

    if ( $id && ( lc($id) =~ /invoice number/ || lc($id) eq 'cogs' || lc($id) =~ /factuurnummer/ ) ) {
        $self->{_endOfData} = 1;
    }

    return $self->SUPER::_processLine(@_);
}

sub countryCode {
    my $self = shift;

    my $filename = $self->filename();

    $self->fail("Country code missing from filename")
      unless ( $filename =~ /(?:_(\w{2})_|_(\w{2})\.)/ );

    my $cc = $1 || $2;
    my $obj = Common::Country->Get($cc);

    if ($obj) {
        return $obj->alpha2;
    } else {
        $self->fail("Invalid country code: $cc");
    }
}

sub _getDateBegin {
    my $self = shift;
    my $date = $self->_getByFieldName('dateBegin') || return;

    # The day in the date is usually (but not always) the first.
    # So let's try to use that as a clue for the formatting.
    if ( $date && $date =~ /(\d{1,2})[\/-]01[\/-](\d{4})/ ) {

        # US date...
        my ( $year, $month, $day ) = Add_Delta_YM( $2, $1, 1, 0, -1 );
        return sprintf( "%04d-%02d-%02d", $year, $month, $day );
    } elsif ( $date && $date =~ /(\d{1,2})\/(\d{1,2})\/(\d{4})/ ) {

        # Euro date...
        my ( $year, $month, $day ) = Add_Delta_YM( $3, $2, $1, 0, -1 );
        return sprintf( "%04d-%02d-%02d", $year, $month, $day );
    } elsif ( $date =~ /^\d{5}$/ and $date > 38716 ) {

        # Excel date...
        $date = Spreadsheet::ParseExcel::Utility::ExcelFmt( "yyyy-mm-dd", $date );
        if ( $date =~ /(\d{4})-(\d{2})-(\d{2})/ ) {
            my ( $year, $month, $day ) = Add_Delta_YM( $1, $3, $2, 0, -1 );
            return sprintf( "%04d-%02d-%02d", $year, $month, $day );
        }
    }

    return $date;

}

sub _dateNormalization { 'month' }

sub _isSaleRec {
    my $self = shift;

    # If we've set the end of data flag in processLine, we are done.
    return if ( $self->{_endOfData} );

    return $self->SUPER::_isSaleRec();
}

sub units {

    # We need to make sure that the sign of the units matches the sign of the revenue
    my $self    = shift;
    my $units   = $self->_getByFieldName('rUnits');
    my $revenue = $self->rRevenue;

    if ( ( $revenue < 0 && $units > 0 ) || ( $revenue > 0 && $units < 0 ) ) {
        $units *= -1;
    }

    return $units;
}

sub rRevenue {
    my $self    = shift;
    my $revenue = $self->SUPER::rRevenue();

    if ( $revenue =~ s/[\(\)]//g ) {
        $revenue *= -1;
    }

    return $revenue;
}

sub rListPriceCurrency {
    my $self              = shift;
    my $listPriceCurrency = $self->_getByFieldName('rListPriceCurrency');
    my $revenueCurrency   = $self->_getByFieldName('currencyCode');

    # For Macmillan and RLPG, we're going to set the list price currency to the revenue currency.
    # We'll also be converting the list price with the conversion rate.
    # If it's already in USD, we can just leave it alone.
    if (   ( Common::RSApp::GetClientID == 318 || Common::RSApp::GetClientID == 346 )
        && $listPriceCurrency ne 'USD'
        && $listPriceCurrency ne $revenueCurrency ) {
        $listPriceCurrency = $revenueCurrency;
    }

    return $listPriceCurrency;
}

sub rListPrice {
    my $self              = shift;
    my $listPrice         = $self->_getByFieldName('rListPrice');
    my $listPriceCurrency = $self->_getByFieldName('rListPriceCurrency');
    my $revenueCurrency   = $self->_getByFieldName('currencyCode');

    # If list price = 0, just return that.
    # No need to worry about converting it (and that blows up anyway).
    if ( $listPrice == 0 ) {
        return $listPrice;
    }

    # For Macmillan and RLPG, we're going to convert the list price if it's not in USD
    # AND it's in a different currency than the revenue is.
    #
    if (   ( Common::RSApp::GetClientID == 318 || Common::RSApp::GetClientID == 346 )
        && $listPriceCurrency ne 'USD'
        && $listPriceCurrency ne $revenueCurrency ) {
        $listPrice =~ s/,//g;
        my $revenue  = $self->rRevenue;
        my $units    = $self->units();
        my $discount = $self->rDiscount;
        if ( $discount > 1 ) {
            $discount /= 100;
        }
        if ($units) {
            my $conversionRate = $revenue / ( $listPrice * $units * ( ( 1 - $discount ) / 1 ) );
            $listPrice *= $conversionRate;
        }
    }

    return abs($listPrice);
}

1;
