package BookPub::Import::Importer::Gardners::Version12;

use strict;

use Date::Calc qw( Add_Delta_YM );

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

sub _fieldMap {
    {
        dateBegin            => 'V',
        rPurchaseType        => 'G',
        rFormat              => 'B',
        rPriceType           => 'I1',    #Header
        rAuthor              => 'D',
        rTitle               => 'C',
        rIsbn13              => 'A',
        rInstitution         => 'W',
        rPostalCode          => 'Y',
        countryCode          => 'P',
        rUnits               => 'O',
        rUnitPrice           => 'K',
        rListPrice           => 'J',
        rListPriceCurrency   => 'N',
        rDiscount            => 'L',
        rRevenue             => 'K',
        currencyCode         => 'N',
        rDuration            => 'H',
        rChannel             => 'U',
        rModel               => 'F',
        rTransactionCategory => 'E',
    };
}

sub _unverifiedFieldMap {
    {
        invOrCn         => 'E',
        commercialModel => 'F',
        retailPrice     => 'I',
    };
}

sub _headerIdentifier { ( rTitle => 'TITLE' ) }
sub _useIsSaleRec     { 1 }
sub _dateFormat       { ['iso'] }
sub productType       { BookPub::DB::Item::Sale::kProductTypeEBook }

sub dateBegin {
    my $self = shift;
    my $date = $self->_getByFieldName('dateBegin');
    my $year;
    my $month;
    my $day;

    # if date is missing, use the date from the filename
    if ( !$date || $date eq '' ) {
        if ( $self->filename =~ /_(\d{4})_(\d{2})/ ) {
            $year  = $1;
            $month = $2;
            $day   = 1;
        }
    }

    # date might be either MM-DD-YYYY or DD-MM-YYYY
    elsif ( $date && $date =~ /(\d{1,2})[\-\/](\d{1,2})[\-\/](\d{4})/ ) {
        $year  = $3;
        $month = $2;
        $day   = $1;
    } else {
        $self->fail("Unexpected date format, $date");
    }
    $date = sprintf( "%04d-%02d-%02d", $year, $month, $day );
    return $date;
}

sub purchaseType {
    my $self = shift;
    my $type = $self->_getByFieldName('rPurchaseType');

    if ( !$type ) {
        return BookPub::DB::Item::Sale::kPurchaseTypeDownload;
    } elsif ( $type =~ /ANNUAL CONCURRENT ACCESS/i
        || $type =~ /LIMITED CONCURRENT USER/i
        || $type =~ /RENTAL/i ) {
        return BookPub::DB::Item::Sale::kPurchaseTypeLoan;
    } elsif ( $type =~ /^SUBSCRIPTION$/i ) {
        return BookPub::DB::Item::Sale::kPurchaseTypeSubscriptionDL;
    } else {
        $self->fail("Unexpected purchaseType: $type");
    }
}

sub priceType {
    my $self  = shift;
    my $type  = $self->_getByFieldName('rPriceType');
    my $model = $self->_getByFieldName('commercialModel');

    if ( $model =~ /agency/i ) {
        return 'agency';
    } elsif ( $model =~ /academic|retail|library/i ) {
        return 'rrp';
    } elsif ( !$model && $type =~ /rrp/i ) {
        return 'rrp';
    } else {
        $self->fail("Unexpected priceType: $type($model)");
    }
}

sub priceTypeQualifierID {
    my $self  = shift;
    my $model = $self->_getByFieldName('commercialModel');

    if ( $model =~ /academic|library/i ) {
        return BookPub::DB::Item::PriceTypeQualifier::kCorporate;    # Library
    }

    return undef;
}

sub countryCode {
    my $self = shift;
    my $code = $self->_getByFieldName('countryCode');

    if ( !$code ) {
        return 'GB';
    } else {
        return $code;
    }
}

sub rListPrice { abs( shift->_getByFieldName('rListPrice') ) }

sub rUnits {
    my $self         = shift;
    my $units        = $self->_getByFieldName('rUnits');
    my $saleOrReturn = $self->_getByFieldName('invOrCn');

    if ( $saleOrReturn =~ /CN/i ) {
        $units *= -1;
    } elsif ( $saleOrReturn !~ /INVOICE|CREDIT/i ) {    # note that sign is already correct for CREDITs
        $self->fail("Can't determine sale or return: $saleOrReturn");
    }

    return sprintf "%.0f", $units;
}

sub rSales {
    return (shift->rUnits < 0) ? undef : 1;
}

sub rReturns {
    return (shift->rUnits > 0) ? undef : 1;
}

sub rTaxUnitPrice {
    my $self                     = shift;
    my $recommendedPurchasePrice = $self->_getByFieldName('retailPrice');
    my $rListPrice               = $self->_getByFieldName('rListPrice');

    my $taxUnitPrice = abs( $recommendedPurchasePrice - $rListPrice );
    return $taxUnitPrice;
}

sub rTaxAmount {
    my $self = shift;

    return $self->rTaxUnitPrice * $self->units;
}

sub _processLine {
    my $self = shift;
    my $isbn = $self->_getByFieldName('rIsbn13');

    if ( $isbn && $isbn =~ /TOTAL/i ) {
        $self->{_endOfData} = 1;
    }

    return $self->SUPER::_processLine(@_);
}

sub _isSaleRec {
    my $self = shift;

    # If we've set the end of data flag in processLine, we are done.
    return if ( $self->{_endOfData} );

    return $self->SUPER::_isSaleRec();
}

1;
