package BookPub::Import::Importer::ebrary::Version8;

use strict;
use Data::Dumper;

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 _headerIdentifier { ( rTitle => 'Title' ) }

sub _fieldMap {
    my $self = shift;

    my %fieldMap = (
        8 => {
            serviceProductID => 0,
            isbn13           => 1,
            title            => 4,
            author           => 3,
            listPrice        => 5,

            unitsDirectSUPO  => 6,
            units3rdSUPO     => 9,
            unitsDirect3USER => 13,
            units3rd3USER    => 16,
            unitsDirectMUPO  => 20,
            units3rdMUPO     => 23,

            revenueDirectSUPO  => 8,
            revenue3rdSUPO     => 11,
            revenueDirect3USER => 15,
            revenue3rd3USER    => 18,
            revenueDirectMUPO  => 22,
            revenue3rdMUPO     => 25,
        },
        10 => {
            serviceProductID => 0,
            isbn13           => 1,
            title            => 5,
            author           => 3,
            listPrice        => 6,

            unitsDirectSUPO  => 7,
            units3rdSUPO     => 10,
            unitsDirect3USER => 14,
            units3rd3USER    => 17,
            unitsDirectMUPO  => 21,
            units3rdMUPO     => 24,

            revenueDirectSUPO  => 9,
            revenue3rdSUPO     => 12,
            revenueDirect3USER => 16,
            revenue3rd3USER    => 19,
            revenueDirectMUPO  => 23,
            revenue3rdMUPO     => 26,
        },
        12 => {
            serviceProductID => 0,
            isbn13           => 1,
            title            => 4,
            listPrice        => 5,

            unitsDirectSUPO  => 7,
            units3rdSUPO     => 10,
            unitsDirect3USER => 14,
            units3rd3USER    => 17,
            unitsDirectMUPO  => 21,
            units3rdMUPO     => 24,

            revenueDirectSUPO  => 9,
            revenue3rdSUPO     => 12,
            revenueDirect3USER => 16,
            revenue3rd3USER    => 19,
            revenueDirectMUPO  => 23,
            revenue3rdMUPO     => 26,
        },
        14 => {
            serviceProductID => 0,
            isbn13           => 1,
            title            => 5,
            author           => 3,
            listPrice        => 7,

            unitsDirectSUPO  => 8,
            units3rdSUPO     => 11,
            unitsDirect3USER => 15,
            units3rd3USER    => 18,
            unitsDirectMUPO  => 22,
            units3rdMUPO     => 25,

            discountDirectSUPO  => 9,
            discount3rdSUPO     => 12,
            discountDirect3USER => 16,
            discount3rd3USER    => 19,
            discountDirectMUPO  => 23,
            discount3rdMUPO     => 26,

            revenueDirectSUPO  => 10,
            revenue3rdSUPO     => 13,
            revenueDirect3USER => 17,
            revenue3rd3USER    => 20,
            revenueDirectMUPO  => 24,
            revenue3rdMUPO     => 27,
        },
    );

    return $fieldMap{ $self->_version() };
}

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

    Log->info("Starting _preProcess");
    $self->SUPER::_preProcess(%args);

    foreach my $sheet ( @{ $args{sheets} } ) {
        foreach my $line (@$sheet) {

            # Since we're at the preProcess stage, it seems we have to reference rows by number.
            my $dateCell = $line->[0];
            if ( $dateCell =~ m/ebrary Title Revenue Report \(Perpetual Access\)\s+(Q\d)\s+(\d{4}) for/i ) {
                $self->{_dateBegin} = "$1-$2";
                last;
            }
        }

        if ( !$self->{_dateBegin} ) {
            $self->fail("Unable to find date in header");
        }
    }
}

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

    my $dateStr = $self->{_dateBegin};

    my ( $dateBegin, $dateEnd ) = $self->_getDates( date_begin => $dateStr, type => 'quarter' );
    unless ( $dateBegin and $dateEnd ) {
        $self->errstr('invalid date');
        Common::Log::Print("invalid date string: '$dateStr'");
        return undef;
    }

    my $fieldMapRef = $self->_fieldMap();

    my %fieldMap = %$fieldMapRef;

    my $lines = $args{sheets}[ $fieldMap{dataSheet} ];
    for ( my $i = 1 ; $i < scalar @$lines ; $i++ ) {
        my $title  = $lines->[$i][ $fieldMap{title} ];
        my $isbn13 = $lines->[$i][ $fieldMap{isbn13} ];
        if ( ( !$title || $title eq 'Totals' || $title eq 'Title' ) && ( !$isbn13 || $isbn13 eq 'Electronic ISBN' ) ) {
            Common::Log::Print("skip line $i - title: '$title', isbn: '$isbn13'");
            next;
        }
        my $subtitle;
        ( $title, $subtitle ) = BookPub::Import::Importer::ParseTitleAndSubtitle($title);

        my $listPrice        = $lines->[$i][ $fieldMap{listPrice} ];
        my $serviceProductID = $lines->[$i][ $fieldMap{serviceProductID} ];
        my $author;
        if ( defined $fieldMap{author} ) {
            $author = $lines->[$i][ $fieldMap{author} ];
            if ( $author =~ m/^(.*)\(.+\)$/ ) {
                $author = $1;
            }
        }

        my $unitsDirectSUPO  = $lines->[$i][ $fieldMap{unitsDirectSUPO} ];
        my $units3rdSUPO     = $lines->[$i][ $fieldMap{units3rdSUPO} ];
        my $unitsDirect3USER = $lines->[$i][ $fieldMap{unitsDirect3USER} ];
        my $units3rd3USER    = $lines->[$i][ $fieldMap{units3rd3USER} ];
        my $unitsDirectMUPO  = $lines->[$i][ $fieldMap{unitsDirectMUPO} ];
        my $units3rdMUPO     = $lines->[$i][ $fieldMap{units3rdMUPO} ];

        my $discountDirectSUPO  = $lines->[$i][ $fieldMap{discountDirectSUPO} ];
        my $discount3rdSUPO     = $lines->[$i][ $fieldMap{discount3rdSUPO} ];
        my $discountDirect3USER = $lines->[$i][ $fieldMap{discountDirect3USER} ];
        my $discount3rd3USER    = $lines->[$i][ $fieldMap{discount3rd3USER} ];
        my $discountDirectMUPO  = $lines->[$i][ $fieldMap{discountDirectMUPO} ];
        my $discount3rdMUPO     = $lines->[$i][ $fieldMap{discount3rdMUPO} ];

        my $revenueDirectSUPO  = $lines->[$i][ $fieldMap{revenueDirectSUPO} ];
        my $revenue3rdSUPO     = $lines->[$i][ $fieldMap{revenue3rdSUPO} ];
        my $revenueDirect3USER = $lines->[$i][ $fieldMap{revenueDirect3USER} ];
        my $revenue3rd3USER    = $lines->[$i][ $fieldMap{revenue3rd3USER} ];
        my $revenueDirectMUPO  = $lines->[$i][ $fieldMap{revenueDirectMUPO} ];
        my $revenue3rdMUPO     = $lines->[$i][ $fieldMap{revenue3rdMUPO} ];

        my $saleRec = BookPub::Import::SaleRec->new();

        # defaults
        $saleRec->countryCode('US');
        $saleRec->currencyCode('USD');
        $saleRec->rListPriceCurrency('USD');
        $saleRec->priceTypeID(BookPub::DB::Item::PriceType::kPriceTypeRRP);
        $saleRec->productType(BookPub::DB::Item::Sale::kProductTypeEBook);
        $saleRec->purchaseType(BookPub::DB::Item::Sale::kPurchaseTypeDownload);
        $saleRec->formatType(BookPub::DB::Item::Sale::kFormatTypeEbrary);
        $saleRec->lineNum( $i + 1 );

        $saleRec->dateBegin($dateBegin);
        $saleRec->dateEnd($dateEnd);

        $saleRec->rIsbn13($isbn13);
        $saleRec->rTitle($title);
        $saleRec->rAuthor($author);
        $saleRec->serviceProductID($serviceProductID);
        $saleRec->rSubtitle($subtitle) if $subtitle;
        $saleRec->listPrice($listPrice);
        $saleRec->rListPrice($listPrice);

        if ( $unitsDirectSUPO != 0 || $revenueDirectSUPO != 0 ) {
            my $unitPrice;
            if ($unitsDirectSUPO) {
                $unitPrice = abs( $revenueDirectSUPO / $unitsDirectSUPO );
            } else {
                $unitPrice = $listPrice;
            }

            $saleRec->units($unitsDirectSUPO);
            if ($discountDirectSUPO) {
                $saleRec->rDiscount($discountDirectSUPO);
                $saleRec->discount($discountDirectSUPO);
            } else {
                $saleRec->discount( BookPub::Import::Importer::CalculateDiscount( $unitPrice, $listPrice ) );
            }
            $saleRec->unitPrice($unitPrice);
            $saleRec->revenue($revenueDirectSUPO);

            $saleRec->rUnits($unitsDirectSUPO);
            $saleRec->rRevenue($revenueDirectSUPO);

            $saleRec->rModel("SUPO");
            $saleRec->rTransactionCategory("Direct");

            $self->_insertSale( sale => $saleRec );
            $saleCount++;
        }

        if ( $units3rdSUPO != 0 || $revenue3rdSUPO != 0 ) {
            my $unitPrice;
            if ($units3rdSUPO) {
                $unitPrice = abs( $revenue3rdSUPO / $units3rdSUPO );
            } else {
                $unitPrice = $listPrice;
            }

            $saleRec->units($units3rdSUPO);
            if ($discount3rdSUPO) {
                $saleRec->rDiscount($discount3rdSUPO);
                $saleRec->discount($discount3rdSUPO);
            } else {
                $saleRec->discount( BookPub::Import::Importer::CalculateDiscount( $unitPrice, $listPrice ) );
            }
            $saleRec->unitPrice($unitPrice);
            $saleRec->revenue($revenue3rdSUPO);

            $saleRec->rUnits($units3rdSUPO);
            $saleRec->rRevenue($revenue3rdSUPO);

            $saleRec->rModel("SUPO");
            $saleRec->rTransactionCategory("3rd Party");

            $self->_insertSale( sale => $saleRec );
            $saleCount++;
        }

        if ( $unitsDirect3USER != 0 || $revenueDirect3USER != 0 ) {
            my $unitPrice;
            if ($unitsDirect3USER) {
                $unitPrice = abs( $revenueDirect3USER / $unitsDirect3USER );
            } else {
                $unitPrice = $listPrice;
            }

            $saleRec->units($unitsDirect3USER);
            if ($discountDirect3USER) {
                $saleRec->rDiscount($discountDirect3USER);
                $saleRec->discount($discountDirect3USER);
            } else {
                $saleRec->discount( BookPub::Import::Importer::CalculateDiscount( $unitPrice, $listPrice ) );
            }
            $saleRec->unitPrice($unitPrice);
            $saleRec->revenue($revenueDirect3USER);

            $saleRec->rUnits($unitsDirect3USER);
            $saleRec->rRevenue($revenueDirect3USER);

            $saleRec->rModel("3USER");
            $saleRec->rTransactionCategory("Direct");

            $self->_insertSale( sale => $saleRec );
            $saleCount++;
        }

        if ( $units3rd3USER != 0 || $revenue3rd3USER != 0 ) {
            my $unitPrice;
            if ($units3rd3USER) {
                $unitPrice = abs( $revenue3rd3USER / $units3rd3USER );
            } else {
                $unitPrice = $listPrice;
            }

            $saleRec->units($units3rd3USER);
            if ($discount3rd3USER) {
                $saleRec->rDiscount($discount3rd3USER);
                $saleRec->discount($discount3rd3USER);
            } else {
                $saleRec->discount( BookPub::Import::Importer::CalculateDiscount( $unitPrice, $listPrice ) );
            }
            $saleRec->unitPrice($unitPrice);
            $saleRec->revenue($revenue3rd3USER);

            $saleRec->rUnits($units3rd3USER);
            $saleRec->rRevenue($revenue3rd3USER);

            $saleRec->rModel("3USER");
            $saleRec->rTransactionCategory("3rd Party");

            $self->_insertSale( sale => $saleRec );
            $saleCount++;
        }

        if ( $unitsDirectMUPO != 0 || $revenueDirectMUPO != 0 ) {
            my $unitPrice;
            if ($unitsDirectMUPO) {
                $unitPrice = abs( $revenueDirectMUPO / $unitsDirectMUPO );
            } else {
                $unitPrice = $listPrice;
            }

            $saleRec->units($unitsDirectMUPO);
            if ($discountDirectMUPO) {
                $saleRec->rDiscount($discountDirectMUPO);
                $saleRec->discount($discountDirectMUPO);
            } else {
                $saleRec->discount( BookPub::Import::Importer::CalculateDiscount( $unitPrice, $listPrice ) );
            }
            $saleRec->unitPrice($unitPrice);
            $saleRec->revenue($revenueDirectMUPO);

            $saleRec->rUnits($unitsDirectMUPO);
            $saleRec->rRevenue($revenueDirectMUPO);

            $saleRec->rModel("MUPO");
            $saleRec->rTransactionCategory("Direct");

            $self->_insertSale( sale => $saleRec );
            $saleCount++;
        }

        if ( $units3rdMUPO != 0 || $revenue3rdMUPO != 0 ) {
            my $unitPrice;
            if ($units3rdMUPO) {
                $unitPrice = abs( $revenue3rdMUPO / $units3rdMUPO );
            } else {
                $unitPrice = $listPrice;
            }

            $saleRec->units($units3rdMUPO);
            if ($discount3rdMUPO) {
                $saleRec->rDiscount($discount3rdMUPO);
                $saleRec->discount($discount3rdMUPO);
            } else {
                $saleRec->discount( BookPub::Import::Importer::CalculateDiscount( $unitPrice, $listPrice ) );
            }
            $saleRec->unitPrice($unitPrice);
            $saleRec->revenue($revenue3rdMUPO);

            $saleRec->rUnits($units3rdMUPO);
            $saleRec->rRevenue($revenue3rdMUPO);

            $saleRec->rModel("MUPO");
            $saleRec->rTransactionCategory("3rd Party");

            $self->_insertSale( sale => $saleRec );
            $saleCount++;
        }

    }

    return $saleCount;
}

1;
