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

use strict;

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

use Date::Calc qw( Add_Delta_YM );

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

sub _fieldMap {
    my $self = shift;

    my %fieldMap = (
        31 => {
            serviceProductID   => 'B',
            currencyCode       => 'V',
            countryCode        => 'W',
            dateBegin          => 'A',
            rFormat            => 'I',
            isbn               => 'E',
            rTitle             => 'F',
            rAuthor            => 'G',
            rImprint           => 'H',
            rUnits             => 'L',
            rSales             => 'J',
            rReturns           => 'K',
            rAdjustments       => 'N',
            rListPrice         => 'Q',
            rListPriceCurrency => 'R',
            rPurchasePrice     => 'O',
            rRevenue           => 'U',
        },
        35 => {
            serviceProductID   => 'B',
            currencyCode       => 'V',
            dateBegin          => 'A',
            rFormat            => 'I',
            isbn               => 'E',
            rTitle             => 'F',
            rAuthor            => 'G',
            rImprint           => 'H',
            rUnits             => 'L',
            rSales             => 'J',
            rReturns           => 'K',
            rAdjustments       => 'N',
            rListPrice         => 'Q',
            rListPriceCurrency => 'R',
            rPurchasePrice     => 'O',
            rRevenue           => 'U',
        },
        46 => {
            serviceProductID       => 'B',
            currencyCode           => 'W',
            countryCode            => 'X',
            dateBegin              => 'A',
            rFormat                => 'I',
            isbn                   => 'E',
            rTitle                 => 'F',
            rAuthor                => 'G',
            rImprint               => 'H',
            rUnits                 => 'L',
            rSales                 => 'J',
            rReturns               => 'K',
            rAdjustments           => 'N',
            rListPrice             => 'Q',
            rListPriceCurrency     => 'R',
            rPurchasePrice         => 'O',
            rPurchasePriceCurrency => 'P',
            rDiscount              => 'S',
            rRevenue               => 'V',
        },
        47 => {
            serviceProductID       => 'B',
            currencyCode           => 'U',
            countryCode            => 'V',
            dateBegin              => 'A',
            rFormat                => 'I',
            isbn                   => 'E',
            rTitle                 => 'F',
            rAuthor                => 'G',
            rImprint               => 'H',
            rUnits                 => 'L',
            rSales                 => 'J',
            rReturns               => 'K',
            rAdjustments           => 'N',
            rListPrice             => 'Q',
            rListPriceCurrency     => 'R',
            rPurchasePrice         => 'O',
            rPurchasePriceCurrency => 'P',
            rDiscount              => 'S',
            rRevenue               => 'T',
        },
        54 => {
            serviceProductID       => 'B',
            currencyCode           => 'V',
            countryCode            => 'W',
            dateBegin              => 'A',
            rFormat                => 'I',
            isbn                   => 'E',
            rTitle                 => 'F',
            rAuthor                => 'G',
            rImprint               => 'H',
            rUnits                 => 'L',
            rSales                 => 'J',
            rReturns               => 'K',
            rAdjustments           => 'N',
            rListPrice             => 'Q',
            rListPriceCurrency     => 'R',
            rPurchasePrice         => 'O',
            rPurchasePriceCurrency => 'P',
            rDiscount              => 'S',
            rRevenue               => 'U',
            rFee                   => 'T',
        },
        59 => {
            serviceProductID       => 'B',
            currencyCode           => 'W',
            countryCode            => 'X',
            dateBegin              => 'A',
            rFormat                => 'I',
            isbn                   => 'E',
            rTitle                 => 'F',
            rAuthor                => 'G',
            rImprint               => 'H',
            rUnits                 => 'L',
            rSales                 => 'J',
            rReturns               => 'K',
            rAdjustments           => 'N',
            rListPrice             => 'Q',
            rListPriceCurrency     => 'R',
            rPurchasePrice         => 'O',
            rPurchasePriceCurrency => 'P',
            rDiscount              => 'S',
            rRevenue               => 'Y',
        },
        62 => {
            serviceProductID       => 'B',
            currencyCode           => 'V',
            countryCode            => 'W',
            dateBegin              => 'A',
            rPurchaseType          => 'X',
            rChannel               => 'X',
            rFormat                => 'I',
            isbn                   => 'E',
            rTitle                 => 'F',
            rAuthor                => 'G',
            rImprint               => 'H',
            rUnits                 => 'L',
            rSales                 => 'J',
            rReturns               => 'K',
            rAdjustments           => 'N',
            rListPrice             => 'Q',
            rListPriceCurrency     => 'R',
            rPurchasePrice         => 'O',
            rPurchasePriceCurrency => 'P',
            rDiscount              => 'S',
            rRevenue               => 'U',
            rFee                   => 'T',
            rModel                 => 'X',
        },
        80 => {
            dateBegin                => 'A',
            rFormat                  => 'I',
            rAuthor                  => 'G',
            rTitle                   => 'F',
            rIsbn13                  => 'E',
            rImprint                 => 'H',
            countryCode              => 'X',
            serviceProductID         => 'B',
            rReturns                 => 'K',
            rSales                   => 'J',
            rUnits                   => 'L',
            rAdjustments             => 'N',
            rListPrice               => 'Q',
            rListPriceCurrency       => 'R',
            rNativeListPrice         => 'O',
            rNativeListPriceCurrency => 'P',
            rDiscount                => 'S',
            rRevenue                 => 'V',
            currencyCode             => 'W',
        },
    );

    return $fieldMap{ $self->_version() };
}

sub _useIsSaleRec              { 1 }
sub _autoParseTitleAndSubtitle { 1 }
sub productType                { BookPub::DB::Item::Sale::kProductTypeEBook }
sub rProductType               { BookPub::DB::Item::Sale::kProductTypeEBook }
sub _dateNormalization         { 'month' }

sub purchaseType {
    my $self = shift;

    return BookPub::DB::Item::Sale::kPurchaseTypeDownload unless ($self->_version() == 62);

    my $type = $self->_getByFieldName( 'rPurchaseType' ) || "";

    return BookPub::DB::Item::Sale::kPurchaseTypeLoan if ($type =~ /Lending/i);
    return BookPub::DB::Item::Sale::kPurchaseTypeDownload unless $type;

    $self->fail( "Could not determine purchase type from $type" );
}

sub rServiceName {
    return BookPub::Tracker::Service::GetDefaultServiceName( service_id => shift->serviceID );
}

sub priceType {
    my $self = shift;
    my $type;

    if ( $self->_version() =~ /^(?:54|62)$/ ) {
        if ( Common::RSApp::GetClientID =~ /^(348|359|355|310)$/ ) {    # Macmillan AU/UK, Hachette UK
            $type = 'agencyplustax';
        } else {
            $type = 'agency';
        }
    } elsif ( Common::RSApp::GetClientID == 346 || $self->_version == 59 ) {    # Rowman Littlefield
        $type = 'rrp';
    } elsif ( $self->_version =~ /^(:?46|80)$/ ) {    # Amazon v46 and v80 is RRP for all clients (see RSD-4090, RSD-8480)
        $type = 'rrp';
    } else {
        $type = 'agency';
    }

    return $type;
}

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

    if ( $date && $date =~ /(\d{4})[\/-](\d{1,2})[\/-](\d{1,2})/ ) {
        my ( $year, $month, $day ) = Add_Delta_YM( $1, $2, $3, 0, -1 );

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

        return sprintf( "%04d-%02d-%02d", $year, $month, $day );
    }
}

sub countryCode {
    my $self = shift;

    if ( defined $self->_getByFieldName('countryCode') ) {
        return $self->_getByFieldName('countryCode');
    } else {
        my $filename = $self->filename();
        $self->fail("Country code missing from filename")
          unless ( $filename =~ /^\w{5}_(\w{2})_/ );

        return $1;
    }
}

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

    if ( $id && $id =~ m/Invoice[_ ]Number/i ) {
        $self->{_endOfData} = 1;
    }

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

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 rSales {
    my $self    = shift;
    my $sales   = $self->_getByFieldName('rSales');
    my $returns = $self->_getByFieldName('rReturns');
    my $units   = $sales - $returns;
    my $revenue = $self->revenue();

    # Flipping sales for version 35
    if ( $self->_version() == 35 ) {
        if ( ( $units > 0 && $revenue < 0 ) || ( $units < 0 && $revenue > 0 ) ) {
            return $returns;
        }
    }

    return $sales;
}

sub rReturns {
    my $self    = shift;
    my $sales   = $self->_getByFieldName('rSales');
    my $returns = $self->_getByFieldName('rReturns');
    my $units   = $sales - $returns;
    my $revenue = $self->revenue();

    # Flipping sales for version 35
    if ( $self->_version() == 35 ) {
        if ( ( $units > 0 && $revenue < 0 ) || ( $units < 0 && $revenue > 0 ) ) {
            return $sales;
        }
    }

    return $returns;
}

sub units {
    my $self  = shift;
    my $units = $self->_getByFieldName('rUnits');
    my $adj   = $self->_getByFieldName('rAdjustments');

    if ( $self->_version() == 35 ) {
        return $units + $adj;
    }

    return $units;
}

sub rFee {
    my $self = shift;

    return ( $self->SUPER::rFee() || 0 ) / 100;
}

sub isFree {
    my $self = shift;

    if ( $self->version == 80 ) {
        my $revenue = $self->_getByFieldName('rRevenue') || 0;
        my $units   = $self->_getByFieldName('rUnits')   || 0;
        return !$revenue && $units ? 'Y' : 'N';
    }

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


1;
