package BookPub::Import::Importer::GooglePlay::Version2;

use strict;

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

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

sub _fieldMap {
    {
        serviceProductID   => 0,
        currencyCode       => 17,
        countryCode        => 11,
        rState             => 12,
        rPostalCode        => 13,
        dateBegin          => 1,
        rTitle             => 6,
        rProductType       => 8,
        rIsbn13            => 19,
        rSales             => 4,
        rReturns           => 4,
        rListPrice         => 15,
        rListPriceCurrency => 14,
        rTaxAmount         => 18,
        rDiscount          => 18,
        rRevenue           => 18,
    };
}

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 _unverifiedFieldMap {
    { transactionType => 4, };
}

sub _headerIdentifier { ( rTitle => 'Product Title' ) }

sub _importLines {
    my $self = shift;
    my %args = @_;
    my $lines;

    # data static across sales group
    my (
        $serviceProductID,
        $currencyCode,
        $countryCode,
        $rState,
        $rPostalCode,
        $dateBegin,
        $productType,
        $rIsbn13,
        $rTitle,
        $rAuthor,
        $rListPriceCurrency,
        $purchaseType,
        $formatType
    );

    # data dynamic within sales group
    # groupType is a variable to the transaction type, either sale or return
    my (
        $rSales,     $rReturns,   $units,     $googleFee, $googleFeeRefund, $charge, $chargeRefund,
        $rListPrice, $rTaxAmount, $rDiscount, $revenue,   $transactionType, $nextTransactionType, $groupType
    );

    $self->{lines} = $args{lines};
    Log->debug("in _importLines");

    my $sheetNumber = 0;
    my $saleCount   = 0;
    $purchaseType = BookPub::DB::Item::Sale::kPurchaseTypeSubscriptionDL;

    foreach my $sheet ( @{ $args{sheets} } ) {
        $self->{sheetnum} = $sheetNumber;
        Log->debug("sheetnum = $self->{sheetnum}");

        my ( $id, $nextID ) = ( 0, 0 );

        # line 0 is the header
        $lines = $args{sheets}[$sheetNumber];
        ( $rSales, $rReturns, $units, $googleFee, $googleFeeRefund, $charge, $chargeRefund, $rTaxAmount, $rDiscount, $revenue ) =
          ( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 );

        for ( my $i = 1 ; $i < scalar @$lines ; $i++ ) {
            my $line     = $lines->[$i];
            my $nextLine = $lines->[ $i + 1 ];

            # get the service product id of this line and the next
            $id     = $line->[ $self->_fieldMap->{serviceProductID} ];
            $nextID = $nextLine->[ $self->_fieldMap->{serviceProductID} ];

            my $linenum = $i + 1;
            $transactionType     = $line->[ $self->_unverifiedFieldMap->{transactionType} ];
            $nextTransactionType = $nextLine->[ $self->_unverifiedFieldMap->{transactionType} ];

            next unless $transactionType;

            # check the transaction type and get tax, revenue and units calculated based on it
            if ( $transactionType =~ /^charge$/i ) {
                $rSales     = 1;
                $units      = 1;
                $charge     += $line->[ $self->_fieldMap->{rRevenue} ];
                $rListPrice = abs( $line->[ $self->_fieldMap->{rListPrice} ] || 0 );
                $groupType  = 'sale';

            } elsif ( $transactionType =~ /^charge refund$/i ) {
                $rReturns     = 1;
                $units        = -1;
                $chargeRefund += $line->[ $self->_fieldMap->{rRevenue} ];
                $rListPrice   = abs( $line->[ $self->_fieldMap->{rListPrice} ] || 0 );
                $groupType    = 'return';

            } elsif ( $transactionType =~ /^google fee$/i ) {
                $googleFee += $line->[ $self->_fieldMap->{rDiscount} ];

            } elsif ( $transactionType =~ /^google fee refund$/i ) {
                $googleFeeRefund += $line->[ $self->_fieldMap->{rDiscount} ];

            } elsif ( $transactionType =~ /^tax$/i || $transactionType =~ /^tax refund$/i ) {
                $rTaxAmount += $line->[ $self->_fieldMap->{rTaxAmount} ];

            } else {
                $self->fail("Unexpected transaction type: $transactionType");
            }

            # convert 'serviceProductID' to a digital representation, if possible.
            my $currID = $id;
            if ( $currID =~ /\d/ && $nextID =~ /\d/ ) {
                $currID =~ s/[^\d]//g;
                $nextID =~ s/[^\d]//g;
            }
            $currID .= '_refund' if $transactionType     && $transactionType =~ /refund/i;
            $nextID .= '_refund' if $nextTransactionType && $nextTransactionType =~ /refund/i;

            # if the next serviceProductID is new, we've hit the end of a group so we write all data to the sale table
            if ( $nextID ne $currID ) {

                if ( $groupType eq 'sale' ) {
                    $rDiscount = 1 - ( ( $charge + $googleFee ) / $charge );
                    $revenue = $charge + $googleFee;
                } elsif ( $groupType eq 'return' ) {
                    $rDiscount = 1 - ( ( $chargeRefund + $googleFeeRefund ) / $chargeRefund );
                    $revenue = $chargeRefund + $googleFeeRefund;
                } else {
                    $rDiscount = 0;
                    $revenue   = 0;
                }

                # set vars that are static for all records (title, etc)
                $serviceProductID   = $id;
                $currencyCode       = $line->[ $self->_fieldMap->{currencyCode} ];
                $countryCode        = $line->[ $self->_fieldMap->{countryCode} ];
                $rState             = $line->[ $self->_fieldMap->{rState} ];
                $rPostalCode        = $line->[ $self->_fieldMap->{rPostalCode} ];
                $dateBegin          = $line->[ $self->_fieldMap->{dateBegin} ];
                $productType        = $self->_rProductType( $line->[ $self->_fieldMap->{rProductType} ] );
                $rIsbn13            = $line->[ $self->_fieldMap->{rIsbn13} ];
                $rTitle             = $line->[ $self->_fieldMap->{rTitle} ] || '';
                $rAuthor            = '';
                $rListPriceCurrency = $line->[ $self->_fieldMap->{rListPriceCurrency} ];

                ($rTitle, $rAuthor) = split /\s?-\s?/, $rTitle, 2;

                # massage the date, Apr 1, 2014 -> 2014-04-01
                if ( $dateBegin && $dateBegin =~ /(\w{3})\s*(\d{1,2}),\s*(\d{4})/ ) {
                    $dateBegin = sprintf( "%04d-%02d-%02d", $3, $months{ lc($1) }, $2 );
                } elsif ( $dateBegin && $dateBegin =~ /(\d{1,2}).*(\w{3}).*(\d{2})/ ) {
                    $dateBegin = sprintf( "%04d-%02d-%02d", 2000 + $3, $months{ lc($2) }, $1 );
                } else {
                    $self->fail("Unexpected date format: $dateBegin");
                }

                # write the record
                Log->debug("writing record for: $id");
                my $saleRec = BookPub::Import::SaleRec->new();

                $saleRec->purchaseType($purchaseType);
                $saleRec->isAgency('Y');
                $saleRec->rComments($serviceProductID);
                $saleRec->currencyCode($currencyCode);
                $saleRec->countryCode($countryCode);
                $saleRec->rState($rState);
                $saleRec->rPostalCode($rPostalCode);
                $saleRec->dateBegin($dateBegin);
                $saleRec->dateEnd($dateBegin);
                $saleRec->productType($productType);
                $saleRec->rProductType($productType);
                $saleRec->rIsbn13($rIsbn13);
                $saleRec->rTitle($rTitle);
                $saleRec->rAuthor($rAuthor);
                $saleRec->rSales($rSales);
                $saleRec->rReturns($rReturns);
                $saleRec->units($units);
                $saleRec->listPrice($rListPrice);
                $saleRec->rListPrice($rListPrice);
                $saleRec->rListPriceCurrency($rListPriceCurrency);
                $saleRec->rTaxAmount($rTaxAmount);
                $saleRec->taxAmount($rTaxAmount);
                $saleRec->discount($rDiscount);
                $saleRec->rDiscount($rDiscount);
                $saleRec->revenue($revenue);
                $saleRec->rRevenue($revenue);
                $saleRec->rServiceName('Google Play');

                # the linenum stored is the last line of the multi-line group
                $saleRec->lineNum($linenum);

                $self->_insertSale( sale => $saleRec );

                # reset vars
                ( $rSales, $rReturns, $units, $googleFee, $googleFeeRefund, $charge, $chargeRefund, $rTaxAmount, $rDiscount, $revenue, $rListPrice ) =
                  ( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 );
                $groupType = '';

                $saleCount++;
            }
        }
        $sheetNumber++;
        return $saleCount;
    }
}

sub _rProductType {
    my $self = shift;
    my $type = shift;

    # RS Template says when productType is not provided, default to eBook.  In the two
    # sample file provided, a product of 0 and 1 is supplied.
    if ( $type == 0 || $type == 1 ) {
        return BookPub::DB::Item::Sale::kProductTypeEBook;
    } else {
        $self->fail("Unexpected product type: $type");
    }
}

# redefine Tax validation, see RSD-3019 (skip tax validation)
sub _validateTaxAmount {}

1;
