package BookPub::Import::Importer::DeVry;

use strict;

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

use lib '/app/tools/bookpub/lib';
use BookPub::DB::Item::Sale;
use BookPub::Import::SaleRec;
use Date::Calc qw(Days_in_Month);
use base 'BookPub::Import::Importer';

sub _fieldMap {
    my $self = shift;

    my %fieldMap = (
        1 => {
            podIsbn          => 3,
            isbn             => 4,
            rInstitution     => 0,
            serviceProductID => 4,
            bookRevenue      => 10,
            podRevenue       => 12,
            unitPrice        => 5,
            podUnitPrice     => 8,
            listPrice        => 5,
            podListPrice     => 8,
            revenue          => 13,
            deliveryMethod   => 1,
        },
        2 => {
            podIsbn          => 3,  # D
            isbn             => 4,  # E
            rInstitution     => 0,  # A
            serviceProductID => 4,  # E
            bookRevenue      => 10, # K
            podRevenue       => 11, # L
            unitPrice        => 5,  # F
            podUnitPrice     => 8,  # I
            listPrice        => 5,  # F
            podListPrice     => 8,  # I
            revenue          => 12, # M
            deliveryMethod   => 1,  # B
        },
        3 => {
            podIsbn          => 3,  # D
            isbn             => 4,  # E
            rInstitution     => 0,  # A
            serviceProductID => 4,  # E
            bookRevenue      => 9,  # J
            podRevenue       => 10, # K
            unitPrice        => 5,  # F
            podUnitPrice     => 7,  # H
            listPrice        => 5,  # F
            podListPrice     => 7,  # H
            revenue          => 11, # L
            deliveryMethod   => 1,  # B
        },
        4 => {
            podIsbn          => 3,  # D
            isbn             => 4,  # E
            rInstitution     => 0,  # A
            serviceProductID => 4,  # E
            bookRevenue      => 10, # K
            podRevenue       => 11, # L
            unitPrice        => 5,  # F
            podUnitPrice     => 7,  # H
            listPrice        => 5,  # F
            podListPrice     => 7,  # H
            revenue          => 12, # M
            deliveryMethod   => 1,  # B
            bookUnits        => 9,  # J
            podUnits         => 8,  # I
        },
    );

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

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 _preProcess {
    my ($self, %args) = @_;

    my $date = $args{sheets}->[0][7][5]; # F8
    my $filename;

    if ( $date =~ /Date: (\d+)\/(\d+)\/(\d{4})/i ) {
        $self->{_dateBegin} = sprintf("%04d-%02d-%02d", $3, $1, $2 );
        $self->{_dateEnd}   = $self->{_dateBegin};
    }

    if ( !$self->{_dateBegin} ) {
        $filename = $args{file}->{OrigFileName};
        if ( $filename =~ /(\w{3,9})(\d{2})/ ) {
            my $month = $months{ lc(substr($1, 0,3)) };
            my $year  = "20" . $2;
            $self->{_dateBegin} = sprintf("%04d-%02d-%02d", $year, $month, 1 );
            $self->{_dateEnd}   = sprintf("%04d-%02d-%02d", $year, $month, Days_in_Month( $year, $month ));
        }
    }
    if ( !$self->{_dateBegin} ) {
        $self->fail("Unable to find date in the document ('$date') or filename ('$filename').");
    }

    $self->SUPER::_preProcess(%args);
}

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

    my $lines = $args{lines};
    my $saleCount;

    my %fieldMap = %{$self->_fieldMap()};

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

        my $revenue      = $line->[ $fieldMap{revenue} ] || 0;
        my $podIsbn13    = $line->[ $fieldMap{podIsbn} ];
        my $isbn13       = $line->[ $fieldMap{isbn} ];
        my $institution  = $line->[ $fieldMap{rInstitution} ];
        my $svcProdID    = $line->[ $fieldMap{serviceProductID} ];
        my $bookRevenue  = $line->[ $fieldMap{bookRevenue} ] || 0;
        my $podRevenue   = $line->[ $fieldMap{podRevenue} ] || 0;
        my $unitPrice    = $line->[ $fieldMap{unitPrice} ];
        my $podUnitPrice = $line->[ $fieldMap{podUnitPrice} ];
        my $listPrice    = $line->[ $fieldMap{listPrice} ];
        my $podListPrice = $line->[ $fieldMap{podListPrice} ];
        my $dMethod      = $line->[ $fieldMap{deliveryMethod} ];
        my $discount     = 0;

        # skip the Totals: lines
        next if ( $podRevenue =~ m/total/i );

        # skip the blank lines
        next unless ($isbn13 && ($revenue || $unitPrice));

        my $lineCounter = $i + 1;

        # since we're figuring units as revenue / unitPrice, checking if unitPrice
        # is 0
        if ( $unitPrice == 0 || !defined $unitPrice ) {
            $self->fail( "Unit price not specified on line " . $lineCounter );
        }

        if ( ( $podUnitPrice == 0 || !defined $podUnitPrice ) && $podRevenue ) {
            $self->fail( "POD unit price not specified on line " . $lineCounter );
        }

        my ( $bookUnits, $podUnits );

        if ($self->_version() == 4) {
            $bookUnits = $lines->[$i][ $fieldMap{bookUnits} ];
            $podUnits  = $lines->[$i][ $fieldMap{podUnits} ];
        }
        else {
            $bookRevenue == 0 ? $bookUnits = 0 : $bookUnits = $bookRevenue / $unitPrice;

            if ($podUnitPrice) {
                $podRevenue == 0 ? $podUnits = 0 : $podUnits = $podRevenue / $podUnitPrice;
            }
        }

        $self->fail("Found zero units with positive revenue in line $i") if ( (!$bookUnits && $bookRevenue) || (!$podUnits && $podRevenue) );

        my $isFree = (!$bookRevenue && $bookUnits) ? 'Y' : 'N';

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

        $saleRec->rServiceName('DeVry');
        $saleRec->productType(BookPub::DB::Item::Sale::kProductTypeEBook);
        $saleRec->purchaseType(BookPub::DB::Item::Sale::kPurchaseTypeSubscriptionDL);
        $saleRec->rPurchaseType(BookPub::DB::Item::Sale::kPurchaseTypeSubscriptionDL);
        $saleRec->dateBegin($self->{_dateBegin});
        $saleRec->dateEnd($self->{_dateEnd});
        $saleRec->lineNum($lineCounter);
        $saleRec->rPriceType('rrp');
        $saleRec->rIsbn13($isbn13);
        $saleRec->serviceProductID($svcProdID);
        $saleRec->rInstitution($institution);
        $saleRec->countryCode('US');
        $saleRec->units($bookUnits);
        $saleRec->rUnits($bookUnits);
        $saleRec->unitPrice( abs($unitPrice) );
        $saleRec->listPrice($listPrice);
        $saleRec->discount($discount);
        $saleRec->revenue($bookRevenue);
        $saleRec->currencyCode('USD');
        $saleRec->rDiscount($discount);
        $saleRec->rListPrice($listPrice);
        $saleRec->rListPriceCurrency('USD');
        $saleRec->rUnitPrice($unitPrice);
        $saleRec->rRevenue($revenue);
        $saleRec->rDeliveryMethod($dMethod);
        $saleRec->isFree($isFree);

        if ($bookUnits || $bookRevenue) {
            $self->_insertSale( sale => $saleRec );
            $saleCount++;
        }

        if ($podUnits) {
            my $podSaleRec = BookPub::Import::SaleRec->new();

            $isFree = (!$podRevenue && $podUnits) ? 'Y' : 'N';

            $podSaleRec->rServiceName('DeVry');
            $podSaleRec->productType(BookPub::DB::Item::Sale::kProductTypePhysicalBook);
            $podSaleRec->purchaseType(BookPub::DB::Item::Sale::kPurchaseTypePrintOnDemand);
            $podSaleRec->rPurchaseType(BookPub::DB::Item::Sale::kPurchaseTypePrintOnDemand);
            $podSaleRec->dateBegin($self->{_dateBegin});
            $podSaleRec->dateEnd($self->{_dateEnd});
            $podSaleRec->lineNum($lineCounter);
            $podSaleRec->rPriceType('rrp');
            $podSaleRec->rIsbn13($podIsbn13);
            $podSaleRec->serviceProductID($svcProdID);
            $podSaleRec->rInstitution($institution);
            $podSaleRec->countryCode('US');
            $podSaleRec->rUnits($podUnits);
            $podSaleRec->units($podUnits);
            $podSaleRec->unitPrice( abs($podUnitPrice) );
            $podSaleRec->listPrice($podListPrice);
            $podSaleRec->discount($discount);
            $podSaleRec->revenue($podRevenue);
            $podSaleRec->currencyCode('USD');
            $podSaleRec->rDiscount($discount);
            $podSaleRec->rListPrice($podListPrice);
            $podSaleRec->rListPriceCurrency('USD');
            $podSaleRec->rUnitPrice($podUnitPrice);
            $podSaleRec->rRevenue($revenue);
            $podSaleRec->rDeliveryMethod($dMethod);
            $podSaleRec->isFree($isFree);

            if ($podUnits || $podRevenue) {
                $self->_insertSale( sale => $podSaleRec );
                $saleCount++;
            }
        }
    }

    return $saleCount;
}

1;
