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

use strict;
use Date::Calc qw( Add_Delta_YM );

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

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

sub _fieldMap {
    my $self = shift;

    my %fieldMap = (
        32 => {
            serviceProductID       => 'B',
            currencyCode           => 'U',
            countryCode            => 'V',
            dateBegin              => 'A',
            rFormat                => 'I',
            rIsbn13                => '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',
            rChannel               => 'W',
        },
    );

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

sub _useIsSaleRec              { 1 }
sub _autoParseTitleAndSubtitle { 1 }
sub _advancedUnitProcessing    { 0 }
sub _dateNormalization         { 'month' }
sub rServiceName               { 'Amazon' }
sub purchaseType               { BookPub::DB::Item::Sale::kPurchaseTypeDownload }
sub productType                { BookPub::DB::Item::Sale::kProductTypeEBook }
sub rProductType               { BookPub::DB::Item::Sale::kProductTypeEBook }

sub rListPrice {
    my $self          = shift;
    my $listPrice     = $self->_getByFieldName('rListPrice');
    my $priceCurrency = $self->_getByFieldName('rListPriceCurrency');
    my $currencyCode  = $self->_getByFieldName('currencyCode');
    my $baseCurrency  = Common::Client::Current()->Locale()->currencyFormat()->currencyCode();

    # check if units and listPrice are not equal to zero to avoid dividing by zero
    if (   $self->listPriceRequired
        && $priceCurrency ne $currencyCode
        && $priceCurrency ne $baseCurrency
        && $self->units()
        && $self->units() != 0
        && $listPrice != 0 ) {

        # We're going to calculate the conversion rate.
        my $discount       = $self->_getByFieldName('rDiscount');
        my $linenumber     = $self->linenum;
        my $conversionRate = $self->revenue() / ( $listPrice * $self->units() * ( ( 100 - $discount ) / 100 ) );
        $listPrice *= $conversionRate;
    }

    return $listPrice;
}

sub rListPriceCurrency {
    my $self          = shift;
    my $priceCurrency = $self->_getByFieldName('rListPriceCurrency');
    my $currencyCode  = $self->_getByFieldName('currencyCode');
    my $baseCurrency  = Common::Client::Current()->Locale()->currencyFormat()->currencyCode();

    # For the clients that require list price currency to match the revenue currency or base currency.
    # We'll do the actual conversion in rListPrice.
    if ( $self->listPriceRequired && ( $priceCurrency ne $currencyCode ) && ( $priceCurrency ne $baseCurrency ) ) {
        $priceCurrency = $currencyCode;
    }

    return $priceCurrency;
}

sub priceType {
    my $self    = shift;
    my $country = $self->countryCode();

    if ( Common::RSApp::GetClientID == 318 ) {    # Macmillan US
        if ( $country eq 'US' || $country eq 'CA' ) {    # agency for US and CA
            return 'agency';
        } else {                                         # rrp for ROW
            return 'rrp';
        }
    } else {
        return 'rrp';
    }
}

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

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

        # Amazon always set the day to 1, so we can use that as a clue
        # for determining the date format.
        if ( $month == 1 ) {
            $month = $day;
            $day   = 1;
        }

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

        # Amazon always set the day to 1, so we can use that as a clue
        # for determining the date format.
        if ( $month == 1 ) {
            $month = $day;
            $day   = 1;
        }

        ( $year, $month, $day ) = Add_Delta_YM( $year, $month, $day, 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{2})_|_(\w{2})\.)/ );
        my $cc = $1 || $2;

        return $cc;
    }
}

sub rRevenue {
    my $self    = shift;
    my $revenue = $self->_getByFieldName('rRevenue');

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

    # If there are adjustments and units, we need to calculate what the revenue would be without the
    # adjustments because we're going to log those in a separate sale record.
    my $adjustments = $self->_getByFieldName('rAdjustments');
    if ( $adjustments && $self->units ) {

        my $discount = $self->rDiscount;
        if ( $discount > 1 ) {
            $discount /= 100;
        }

        $revenue = Common::RSMath::round( $self->rPurchasePrice * ( 1 - $discount ), 2 ) * $self->units;
    }

    return $revenue;
}

# We're going to zero these out if there are units
# so that they don't get added to the sale records and the adjustment records.
sub rAdjustments {
    my $self        = shift;
    my $adjustments = $self->_getByFieldName('rAdjustments');
    my $units       = $self->_getByFieldName('rUnits');
    if ( $adjustments && $units ) {
        return 0;
    } else {
        return $adjustments;
    }
}

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

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

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

sub preProcessLine {
    my $self = shift;

    my $adjustments = $self->_getByFieldName('rAdjustments');

    # create an adjusted revenue record if necessary
    if ( $adjustments && $self->units ) {

        my $revenue = $self->_getByFieldName('rRevenue');
        if ( $revenue =~ s/[\(\)]//g ) {
            $revenue *= -1;
        }

        $revenue = Common::RSMath::round( $revenue, 2 );

        my $rRevenue = $self->rRevenue;

        $rRevenue = Common::RSMath::round( $rRevenue, 2 );

        $revenue -= $rRevenue;

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

        # These are the fields we need to change for this record.
        $sale->rUnits(0);
        $sale->units(0);
        $sale->rAdjustments($adjustments);
        $sale->rRevenue($revenue);
        $sale->revenue($revenue);

        # And these fields can just use the regular values.
        $sale->dateBegin( $self->dateBegin() );
        $sale->dateEnd( $self->dateEnd() );
        $sale->serviceID( $self->serviceID );
        $sale->importStatus( $self->importStatus );
        $sale->productType( $self->productType );
        $sale->formatType( $self->formatType );
        $sale->priceTypeID( $self->priceTypeID );
        $sale->purchaseType( $self->purchaseType );
        $sale->serviceProductID( $self->serviceProductID );
        $sale->isAgency( $self->isAgency );
        $sale->listPrice( $self->listPrice );
        $sale->discount( $self->discount );
        $sale->currencyCode( $self->currencyCode );
        $sale->countryCode( $self->countryCode );
        $sale->rFormat( $self->rFormat );
        $sale->rPriceType( $self->rPriceType );
        $sale->rPurchaseType( $self->rPurchaseType );
        $sale->rProductType( $self->rProductType );
        $sale->rClientProductID( $self->rClientProductID );
        $sale->rIsbn10( $self->rIsbn10 );
        $sale->rIsbn13( $self->rIsbn13 );
        $sale->rServiceName( $self->rServiceName );
        $sale->rDistributor( $self->rDistributor );
        $sale->rTitle( $self->rTitle );
        $sale->rSubtitle( $self->rSubtitle );
        $sale->rAuthor( $self->rAuthor );
        $sale->rImprint( $self->rImprint );
        $sale->rPurchasePrice( $self->rPurchasePrice );
        $sale->rPurchasePriceCurrency( $self->rPurchasePriceCurrency );
        $sale->rListPrice( $self->rListPrice );
        $sale->rListPriceCurrency( $self->rListPriceCurrency );
        $sale->rDiscount( $self->rDiscount );
        $sale->rCOGS( $self->rCOGS );
        $sale->rUnitPrice( $self->rUnitPrice );

        $sale->lineNum( $self->linenum );

        $self->SUPER::_insertSale( sale => $sale );
    }
}

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();
}

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