package BookPub::Import::Importer::Audible::Version14;

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_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',
        },
        on_demand_detail => {
            dateBegin            => 'G4',
            rPurchaseType        => 'I',
            purchaseType         => 'I',
            rAuthor              => 'C',
            rTitle               => 'D',
            rIsbn13              => 'E',
            countryCode          => 'H',
            rClientProductID     => 'F',
            serviceProductID     => 'B',
            rUnits               => 'Q',
            rListPriceCurrency   => 'M',
            rCOGS                => 'N',
            rRevenue             => 'Q',
            currencyCode         => 'M',
            isFree               => 'Q',
            rDuration            => 'P',
            rTransactionCategory => 'I',
            rComments            => 'J',
        },
    );

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

sub _unverifiedFieldMap {
    my $self = shift;

    my %map = (
        sales_detail_net_sales => {
            fxRate => 'P',
        },
        on_demand_detail => {
            fxRate => 'P',
        }
    );

    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 {
    my $self = shift;

    if ( $self->filename =~ /[ _.][^ACX][ _.]/i) {
        return 'Audible';
    }

    $self->fail("Unable to determine rServirceName.")
}

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;

    if ( $self->_sheetName eq 'on_demand_detail' ) {
        return;
    }

    my $type = $self->_getByFieldName('rPurchaseType') || '';
    return 'ALOP' if $type =~ /^Member Cash Sales \(ALOP\)$/i;
    return 'AL'   if $type =~ /^Member Credit Sales \(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;

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

    if ( $self->_sheetName eq 'on_demand_detail' ) {
        if ( $type =~ /^Audible - Catalog Subscription$/i ) {
            return BookPub::DB::Item::Sale::kPurchaseTypeSubscriptionDL;
        }
    }

    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 if $self->_sheetName eq 'on_demand_detail';

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

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

    return $rListPrice;
}

sub rUnitPrice {
    my $self = shift;

    return if $self->_sheetName eq 'on_demand_detail';

    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;

    if ( $self->_sheetName eq 'on_demand_detail' ) {
        return 'Y' unless $revenue;
    }

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

}

sub rComments {
    my $self = shift;

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


    if ( $self->_sheetName eq 'on_demand_detail' ) {
        return $rComments;
    }

    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 rUnits {
    my $self = shift;

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

    if ( $self->_sheetName eq 'on_demand_detail' ) {
        my $rRevenue = $self->_getByFieldName('rRevenue') || 0;
        $rUnits = $rRevenue >= 0 ? 1 : -1;
    }

    return $rUnits;
}


# 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)$/i ) {
        my $limit = 1;
        my $clientID = Common::RSApp::GetClientID;
        foreach my $aRow ( @$sheet ) {
            # check the value in cell A1
            my $cellValue = $$aRow[0] || '';
            if ( $cellValue !~ /^No data available for this period$/i && $clientID =~ /^346|324|318$/ ) {  # RLPG, Wiley, MMUS
                $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;
