package BookPub::Import::Importer::Audible::Version12;

use strict;
use warnings;

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

use lib '/app/tools/sale_import/lib/';
use Import::ValidationError;

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


sub _fieldMap {
    my $self = shift;

    my %map = (
        sales_detail_per_unit => {
            dateBegin            => 'G4',
            rPurchaseType        => 'I',
            purchaseType         => 'G',
            rAuthor              => 'C',
            rTitle               => 'D',
            rIsbn13              => 'E',
            countryCode          => 'H',
            rClientProductID     => 'F',
            serviceProductID     => 'B',
            rUnits               => 'S',
            rListPrice           => 'M',
            rListPriceCurrency   => 'O',
            rRevenue             => 'T',
            currencyCode         => 'O',
            rTransactionCategory => 'I',
            rComments            => 'J',
        },
        sales_detail_net_sales => {
            dateBegin            => 'G4',
            rPurchaseType        => 'I',
            purchaseType         => 'G',
            rAuthor              => 'C',
            rTitle               => 'D',
            rIsbn13              => 'E',
            countryCode          => 'H',
            rClientProductID     => 'F',
            serviceProductID     => 'B',
            rUnits               => 'P',
            rUnitPrice           => 'Q',
            rListPrice           => 'Q',
            rListPriceCurrency   => 'M',
            rCOGS                => 'N',
            rRevenue             => 'R',
            currencyCode         => 'M',
            rTransactionCategory => 'I',
            rComments            => 'J',
        },
        adjustments => {
            dateBegin            => 'G4',
            rPurchaseType        => 'R',
            rAuthor              => 'H',
            rTitle               => 'G',
            rIsbn13              => 'I',
            countryCode          => 'M',
            serviceProductID     => 'F',
            rUnits               => 'T',
            rListPrice           => 'J',
            rListPriceCurrency   => 'K',
            rRevenue             => 'U',
            currencyCode         => 'K',
        },
    );

    return $map{$self->_sheetName};
}

sub _unverifiedFieldMap {
    my $self = shift;

    my %map = (
        sales_detail_per_unit => {
            fxRate => 'P',
        },
        sales_detail_net_sales => {
            fxRate => 'P',
        },
        adjustments => {
            royaltyEarner => 'A',
        },

    );

    return $map{$self->_sheetName};
}

sub _headerIdentifier { rTitle => 'Title' }

my %months = (
    'jan' => 1, 'feb' => 2, 'mar' => 3, 'apr' => 4, 'may' => 5, 'jun' => 6,
    'jul' => 7, 'aug' => 8, 'sep' => 9, 'oct' => 10, 'nov' => 11, 'dec' => 12,
);

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

sub _useIsSaleRec { 1 }
sub priceType     { 'rrp' }
sub dateBegin     { shift->{_dateBegin} }
sub dateEnd       { shift->{_dateEnd} }
sub productType   { BookPub::DB::Item::Sale::kProductTypeAudioBook }

sub rPurchaseType {
    my $self = shift;

    my $type = $self->_getByFieldName('rPurchaseType') || '';
    return 'ALOP' if $type =~ /^Member Cash Sales \(ALOP\)$/i;
    return 'AL'   if $type =~ /^(?:Member Credit Sales \(AL\)|al)$/i;
    return 'ALC'  if $type =~ /^Non-Member Cash Sales \(ALC\)$/i;

    $self->fail("Unable to determine rPurchaseType from: '$type'");
}

sub purchaseType {
    my $self = shift;

    return BookPub::DB::Item::Sale::kPurchaseTypeDownload if ($self->_sheetName eq 'adjustments');

    my $type = $self->_getByFieldName('purchaseType') || '';
    if ( $type =~ /^Promotional (?:Sale|Return)$/i ) {
        return BookPub::DB::Item::Sale::kPurchaseTypePromotional;
    } elsif ( $type =~ /^(?:Sale|Return)$/i ) {
        return BookPub::DB::Item::Sale::kPurchaseTypeSubscriptionDL;
    }

    $self->fail("Unable to determine purchaseType from: '$type'");
}

sub rListPrice {
    my $self = shift;

    return $self->SUPER::rListPrice(@_) if ($self->_sheetName eq 'adjustments');

    my $rListPrice  = $self->_getByFieldName('rListPrice')  || 0;
    my $fxRate  = $self->_getByFieldName('fxRate')          || 1;
    my $netUnits = $self->_getByFieldName('rUnits')         || 0;

    $rListPrice *= $fxRate if $self->_sheetName eq 'sales_detail_per_unit';
    $rListPrice /= $netUnits if $self->_sheetName eq 'sales_detail_net_sales';

    return $rListPrice;
}

sub rUnitPrice {
    my $self = shift;

    return if ($self->_sheetName eq 'adjustments');

    my $netSales = $self->_getByFieldName('rUnitPrice') || 0;
    my $netUnits = $self->_getByFieldName('rUnits') || 0;
    my $royaltyRate = $self->_getByFieldName('rCOGS') || 0;

    return $netSales / $netUnits * $royaltyRate;
}

sub isFree {
    my $self = shift;

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

    return (!$revenue && $units) ? 'Y' : 'N';

}

sub rComments {
    my $self = shift;

    return if ($self->_sheetName eq 'adjustments');

    my $rComments = $self->_getByFieldName('rComments')       || ''; # J
    my $purchaseType = $self->_getByFieldName('purchaseType') || ''; # G

    if ( $rComments =~ /^WfV$/i ) {
        return $rComments = "WS4V"      if $purchaseType !~ /^Promotional (?:Sale|Return)$/i;
        return $rComments = "WS4VPROMO" if $purchaseType =~ /^Promotional (?:Sale|Return)$/i;
    }

    if ( $rComments =~ /^Standard$/i ) {
        return $rComments = "NONWS4V"      if $purchaseType !~ /^Promotional (?:Sale|Return)$/i;
        return $rComments = "NONWS4VPROMO" if $purchaseType =~ /^Promotional (?:Sale|Return)$/i;
    }
}

sub _isSaleRec {
    my $self = shift;

    if ($self->_sheetName eq 'adjustments') {
        my $total = $self->_getByFieldName('royaltyEarner') || '';
        return 0 if $total =~ /^total$/i;
    }

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


# overridden functions
sub _processSheet {
    my ( $self, $sheet, $sheetnum ) = @_;

    if ( $self->sheetname =~ /^Cover Sheet$/i ) {
        my $limit = 50;
        foreach my $aRow ( @$sheet ) {
            # searching for the date value in column G (actually G4)
            my $salePeriod = $$aRow[6] || '';
            if ( my ($y, $m) = $salePeriod =~ /^(\d{4})_(\w{3,9}|Q\d)$/ ) {
                if ($m =~ /^[Qq]/) {
                    ($self->{_dateBegin}, $self->{_dateEnd}) = $self->_getDates( date_begin => "$y$m", type => 'quarter' );
                    last;
                }
                $m = substr($m, 0, 3);
                $m = $months{lc $m};
                $self->{_dateBegin} = sprintf("%04d-%02d-%02d", $y, $m, 1);
                $self->{_dateEnd} = sprintf("%04d-%02d-%02d", $y, $m, 1);
                last;
            }
            unless (--$limit) {
                $self->fail("Unable to determine dateBegin and dateEnd.");
                last;
            }
        }
    }

    if ( $self->sheetname =~ /^(?:On\-Demand Detail|Adjustments)$/i ) {
        my $limit = 1;
        foreach my $aRow ( @$sheet ) {
            # check the value in cell A1
            my $cellValue = $$aRow[0] || '';
            if ( $cellValue !~ /^No data available for this period$/i ) {
                next if ( Common::RSApp::GetClientID == 348 && $self->sheetname =~ /^Adjustments$/i); # Exception for MacmillanAU (RSD-11225)
                $self->fail("The sheet '" . $self->sheetname . "' contains data for verification.");
            }
            last unless --$limit;
        }
    }

    $self->SUPER::_processSheet($sheet, $sheetnum);

    return;
}

sub _sheetName {
    my $self = shift;

    my $sheetName = lc( $self->sheetname || '' );
    $sheetName =~ s/[)(]//g;
    $sheetName =~ s/[\s\-]/_/g;

    return $sheetName || '';
}

1;
