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

use strict;
use warnings;

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

my %statesUSA = (
    al => [ 'alabama',            'ala',   'ala.'   ],
    ak => [ 'alaska'                                ],
    az => [ 'arizona',            'ariz',  'ariz.'  ],
    ar => [ 'arkansas',           'ark',   'ark.'   ],
    ca => [ 'california',         'calif', 'calif.' ],
    co => [ 'colorado',           'colo',  'colo.'  ],
    ct => [ 'connecticut',        'conn',  'conn.'  ],
    de => [ 'delaware',           'del',   'del.'   ],
    dc => [ 'districtofcolumbia', 'dc',    'd.c.'   ],
    fl => [ 'florida',            'fla',   'fla.'   ],
    ga => [ 'georgia',            'ga',    'ga.'    ],
    hi => [ 'hawaii'                                ],
    id => [ 'idaho'                                 ],
    il => [ 'illinois',           'ill',   'ill.'   ],
    in => [ 'indiana',            'ind',   'ind.'   ],
    ia => [ 'iowa'                                  ],
    ks => [ 'kansas',             'kans',  'kans.'  ],
    ky => [ 'kentucky',           'ky',    'ky.'    ],
    la => [ 'louisiana',          'la',    'la.'    ],
    me => [ 'maine'                                 ],
    md => [ 'maryland',           'md',    'md.'    ],
    ma => [ 'massachusetts',      'mass',  'mass.'  ],
    mi => [ 'michigan',           'mich',  'mich.'  ],
    mn => [ 'minnesota',          'minn',  'minn.'  ],
    ms => [ 'mississippi',        'miss',  'miss.'  ],
    mo => [ 'missouri',           'mo',    'mo.'    ],
    mt => [ 'montana',            'mont',  'mont.'  ],
    ne => [ 'nebraska',           'nebr',  'nebr.'  ],
    nv => [ 'nevada',             'nev',   'nev.'   ],
    nh => [ 'newhampshire',       'nh',    'n.h.'   ],
    nj => [ 'newjersey',          'nj',    'n.j.'   ],
    nm => [ 'newmexico',          'nm',    'n.m.'   ],
    ny => [ 'newyork',            'ny',    'n.y.'   ],
    nc => [ 'northcarolina',      'nc',    'n.c.'   ],
    nd => [ 'northdakota',        'nd',    'n.d.'   ],
    oh => [ 'ohio'                                  ],
    ok => [ 'oklahoma',           'okla',  'okla.'  ],
    or => [ 'oregon',             'ore',   'ore.'   ],
    pa => [ 'pennsylvania',       'pa',    'pa.'    ],
    ri => [ 'rhodeisland',        'ri',    'r.i.'   ],
    sc => [ 'southcarolina',      'sc',    's.c.'   ],
    sd => [ 'southdakota',        'sd',    's.d.'   ],
    tn => [ 'tennessee',          'tenn',  'tenn.'  ],
    tx => [ 'texas',              'tex',   'tex.'   ],
    ut => [ 'utah'                                  ],
    vt => [ 'vermont',            'vt',    'vt.'    ],
    va => [ 'virginia',           'va',    'va.'    ],
    wa => [ 'washington',         'wash',  'wash.'  ],
    wv => [ 'westvirginia',       'wva',   'w.va.'  ],
    wi => [ 'wisconsin',          'wis',   'wis.'   ],
    wy => [ 'wyoming',            'wyo',   'wyo.'   ],
);

sub _fieldMap {
    {
        dateBegin              => 'D',
        rAuthor                => 'I',
        rTitle                 => 'H',
        rIsbn13                => 'F',
        rState                 => 'AD',
        rPostalCode            => 'X',
        countryCode            => 'Y',
        serviceProductID       => 'G',
        rUnits                 => 'K',
        rListPrice             => 'M',
        rListPriceCurrency     => 'N',
        rPurchasePrice         => 'O',
        rPurchasePriceCurrency => 'P',
        rRevenue               => 'BE',
        currencyCode           => 'BF',
        rTaxAmount             => 'BG',
        rIncentiveAmount       => 'BK',
        rModel                 => 'BI',
        rTransactionCategory   => 'L',
    };
}

sub _unverifiedFieldMap {
    {
        transactionStatus            => 'L',
        transactionType              => 'R',
        incentiveCurrency            => 'BL',
        billToState                  => 'W',
        pub_rewards_credits          => 'BO',
        pub_rewards_credits_currency => 'BP',
        net_cogs                     => 'BQ'
    };
}

sub rProductType { BookPub::DB::Item::Sale::kProductTypeEBook }

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

sub rState {
    my $self = shift;

    my $rState      = $self->_getByFieldName('rState');
    my $billToState = $self->_getByFieldName('billToState');

    my $state = lc( $rState || $billToState || '' );
    $state =~ s/[^a-z]//g;
    return uc($state) if exists $statesUSA{$state};

    while ( my ($code, $aAbbr) = each %statesUSA ) {
        return uc($code) if grep { $state eq $_ } @$aAbbr;
    }

    return $state;
}

sub state {
    my $self = shift;

    my $state;

    if ( my $rState = $self->rState() ) {
        my $countryCode = $self->countryCode();

        if ( $countryCode && length($countryCode) != 2 ) {
            my $countryObj = Common::Country->Get($countryCode);
            if ($countryObj) {
                $countryCode = $countryObj->alpha2();
            }
        }

        if ( my $postal = Common::Postal->new($countryCode) ) {
            if ( $postal->getName($rState) ) {

                # acceptable state abbreviation
                $state = $rState;
            } else {

                # look up by the full state name
                $state = $postal->getAbbr($rState);
            }

            if ( !$state ) {

                # Apple seems to run with PI right now, an
                # obsolete code for Philippine Islands.
                # We'll let that slide (but we won't normalize
                # with it either).

                if ( uc($rState) ne 'PI' ) {
                    #$self->fail( "Invalid state '$rState' (country: " . $self->countryCode . ")" );
                }
            }
        }
    }

    return $state;
}

sub currencyCode { shift->_getByFieldName('currencyCode') || 'USD' }

sub countryCode {
    my $self = shift;

    my $countryCode = $self->_getByFieldName('countryCode') || 'US';
    my $rListPrice  = $self->_getByFieldName('rListPrice')  || 0;
    # to be sure it's a digit
    $rListPrice += 0;

    return 'US' if !$countryCode && !$rListPrice;

    return $countryCode;
}


sub rIncentiveAmount {
    my $self = shift;

    my $currencyCode      = $self->currencyCode;
    my $incentiveCurrency = $self->_getByFieldName('incentiveCurrency') || '';
    my $rIncentiveAmount  = $self->_getByFieldName('rIncentiveAmount')  || 0;
    # to be sure it's a digit
    $rIncentiveAmount += 0;

    # don't check if no amount
    return $rIncentiveAmount unless $rIncentiveAmount;

    # currencies must match
    return $rIncentiveAmount if $currencyCode eq $incentiveCurrency;

    $self->fail("currencyCode '$currencyCode' doesn't match incentiveCurrency '$incentiveCurrency'")
}

sub rUnits {
    my $self            = shift;
    my $revenue         = $self->_getByFieldName('rRevenue') || 0;
    my $units           = $self->_getByFieldName('rUnits')   || 0;
    my $transactionType = $self->_getByFieldName('transactionType');

    if ( ( $transactionType =~ /REFUND/i && $units > 0 ) || ( $transactionType !~ /REFUND/i && $revenue < 0 ) ) {
        $units = abs($units) * -1;
    }

    return $units;
}

sub rTaxAmount {
    my $self            = shift;
    my $revenue         = $self->_getByFieldName('rRevenue') || 0;
    my $tax             = $self->_getByFieldName('rTaxAmount') || 0;
    my $transactionType = $self->_getByFieldName('transactionType');

    if ( ( $transactionType =~ /REFUND/i && $tax > 0 ) || ( $transactionType !~ /REFUND/i && $revenue < 0 ) ) {
        $tax = abs($tax) * -1;
    }

    return $tax;
}

sub _isSaleRec {
    my $self = shift;

    my $transactionStatus = uc( $self->_getByFieldName('transactionStatus') || '' );
    my $revenue           = $self->SUPER::revenue();

    $self->fail("ERROR: Values should not be set in 'pub_rewards_credits, pub_rewards_credits_currency or net_cogs'") if (
        $self->_getByFieldName("pub_rewards_credits") ||
        $self->_getByFieldName("pub_rewards_credits_currency") ||
        $self->_getByFieldName("net_cogs"));

    # We're going to skip some of the lines if they have a certain status AND no revenue.
    if ( ( $transactionStatus eq "REFUNDED_NOT_RECEIVED" || $transactionStatus eq "FULFILLED_NOT_PAID" ) && $revenue == 0 ) {
        return 0;
    } else {
        return $self->SUPER::_isSaleRec();
    }
}

1;
