package BookPub::Import::Importer::Audible::Version13;

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';

use Date::Calc qw(Days_in_Month);


my %sheetsWithData = (
    sales_details             => undef,
    on_demand_royalty_bearing => undef,
);

my @saleTypes = qw/alc al alop/;

sub _fieldMap {
    my $self = shift;

    my %map = (
        sales_details => {
            alc => {
                dateBegin            => 'B3',
                dateEnd              => 'B3',
                rPurchaseType        => 'J',
                rAuthor              => 'D',
                rTitle               => 'C',
                rIsbn13              => 'E',
                countryCode          => 'H',
                serviceProductID     => 'B',
                rUnits               => 'J',
                rRevenue             => 'L',
                isFree               => 'L',
                rTransactionCategory => 'I',
            },
            al => {
                dateBegin            => 'B3',
                dateEnd              => 'B3',
                rPurchaseType        => 'M',
                rAuthor              => 'D',
                rTitle               => 'C',
                rIsbn13              => 'E',
                countryCode          => 'H',
                serviceProductID     => 'B',
                rUnits               => 'M',
                rRevenue             => 'O',
                isFree               => 'O',
                rTransactionCategory => 'I',
            },
            alop => {
                dateBegin            => 'B3',
                dateEnd              => 'B3',
                rPurchaseType        => 'P',
                rAuthor              => 'D',
                rTitle               => 'C',
                rIsbn13              => 'E',
                countryCode          => 'H',
                serviceProductID     => 'B',
                rUnits               => 'P',
                rRevenue             => 'R',
                isFree               => 'R',
                rTransactionCategory => 'I',
            },

        },
    );

    if ( exists $map{$self->_sheetName} && exists $map{$self->_sheetName}{$self->_saleType} ) {
        return $map{$self->_sheetName}{$self->_saleType}
    }

    return {};
}

sub _unverifiedFieldMap {
    {
        _royalty_earner  => 'A',
        _unit_sales      => 'S',
        _net_earnings    => 'U',
    }
}

sub _headerIdentifier { rTitle => 'Title' }


sub _useIsSaleRec      { 1 }
sub priceType          { 'rrp' }
sub dateBegin          { shift->{_dateBegin} }
sub dateEnd            { shift->{_dateEnd} }
sub rPurchaseType      { uc shift->_saleType }
sub purchaseType       { BookPub::DB::Item::Sale::kPurchaseTypeSubscriptionDL }
sub productType        { BookPub::DB::Item::Sale::kProductTypeAudioBook }
sub currencyCode       { 'GBP' }
sub rListPriceCurrency { 'GBP' }


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

sub rUnits {
    my $self = shift;

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

    return $rUnits;
}

sub rRevenue {
    my $self = shift;

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

    return $rRevenue;
}

sub isFree {
    my $self = shift;

    return !$self->rRevenue && $self->rUnits ? 'Y' : 'N';
}

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

    if ( $self->sheetname =~ /^Summary$/i ) {
        my $limit = 50;
        foreach my $aRow ( @$sheet ) {
            # searching for the date value in column B (actually B3)
            my $salePeriod = $$aRow[1] || '';
            if ( my ($y, $q) = $salePeriod =~ /^(\d{4}).Q(\d)$/i ) {
                my $mBegin = $q * 3 - 2;
                my $mEnd = $q * 3;
                $self->{_dateBegin} = sprintf("%04d-%02d-%02d", $y, $mBegin, 1);
                $self->{_dateEnd}   = sprintf("%04d-%02d-%02d", $y, $mEnd, Days_in_Month($y, $mEnd));
                last;
            }
            unless (--$limit) {
                $self->fail("Unable to determine dateBegin and dateEnd.");
                last;
            }
        }
    }

    if ( $self->sheetname =~ /^On-Demand Royalty Bearing$/i ) {
        my $limit = 10;
        my $cellHasValue = 0;
        my $noDataFlag = 0;
        foreach my $aRow ( @$sheet ) {
            # check the value in cell A1
            my $cellValue = $$aRow[0] || next;

            if ( $cellValue =~ /^No data available for this period$/i ) {
                $noDataFlag++;
                last;
            }

            $cellHasValue++;
            last unless --$limit;
        }

        if ( !$noDataFlag && $cellHasValue ) {
            $self->fail("The sheet '" . $self->sheetname . "' contains data for verification.");
        }
    }

    if ( Common::RSApp::GetClientID() !~ /^(?:355)$/) {    # HUK
        $self->fail("The currency for this client must be confirmed.");
    }

    if ( exists $sheetsWithData{ $self->_sheetName } ) {
        # initial position with sales type 'alc'
        $self->{_sale_type} = $saleTypes[0];
        $self->SUPER::_processSheet($sheet, $sheetnum);
    }

    return;
}

sub _processLine {
    my $self = shift;

    unless ( $self->_isSaleRec ) {
        Common::Log::Print( " -- Ignore line sheet: " . $self->sheetname . " line: " . $self->linenum );
        $self->{_linesIgnored}++;
        return;
    }

    $self->{sumUnits}   = 0;
    $self->{sumRevenue} = 0;

    foreach my $saleType ( @saleTypes ) {
        $self->_saleType($saleType);

        $self->{sumUnits} += $self->rUnits;
        $self->{sumRevenue} += $self->rRevenue;

        if ( $self->rRevenue || $self->rUnits ) {
            $self->_saveLine();
        }
    }

    my $unitSales = $self->_getByFieldName('_unit_sales') || 0;
    if ( sprintf('%.d', $unitSales) != sprintf('%.d', $self->{sumUnits}) ) {
        $self->fail("The total number of units for sales types does not equal the 'Unit Sales' value.");
    }

    my $netEarnings = $self->_getByFieldName('_net_earnings') || 0;
    if ( sprintf('%.8f', $netEarnings) != sprintf('%.8f', $self->{sumRevenue}) ) {
        $self->fail("The total revenue for sales types does not equal the 'Net Earnings' value.");
    }

    $self->{_linesImported}++;
}

sub _isSaleRec {
    my $self = shift;

    my $royaltyEarner = $self->_getByFieldName('_royalty_earner') || '';
    return if $royaltyEarner =~ /Grand Total/i;

    return 1;
}


# local functions
sub _sheetName {
    my $self = shift;

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

    return $sheetName || '';
}

sub _saleType {
    my ($self, $val) = @_;

    if ( defined $val ) {
        $self->{_sale_type} = $val;
    }

    return $self->{_sale_type} || '';
}


1;