package BookPub::Import::Importer::EBSCO::Version1;

use strict;

use Data::Dumper;

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

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

sub _headerIdentifier { ( rTitle => 'TITLE' ) }

sub priceType { 'rrp' }

sub _fieldMap {
    {
        rPurchaseType        => 'I',
        purchaseType         => 'I',
        rProductType         => 'J7',
        rFormat              => 'J7',
        countryCode          => 'G',
        isbn                 => 'C',
        rTitle               => 'D',
        rAuthor              => 'E',
        rImprint             => 'A',
        rUnits               => 'L',
        rListPrice           => 'K',
        rDiscount            => 'Q',
        rRevenue             => 'R',
        rInstitution         => 'F',
        rDuration            => 'J',
        rModel               => 'J',
        rTransactionCategory => 'J',
    };
}

sub _unverifiedFieldMap {
    {
        secondProductType => 'I7',
        secondFormat      => 'I7',
    };
}

sub _useIsSaleRec              { 1 }
sub _autoParseTitleAndSubtitle { 1 }
sub currencyCode               { shift->{_currencyCode} }
sub dateBegin                  { shift->{_dateBegin} }
sub _dateNormalization         { shift->{_dateNormalization} }
sub _dateFormat                { ['iso'] }

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();
}

sub _processLine {
    my $self     = shift;
    my $discount = $self->_getByFieldName('rDiscount');

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

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

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

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

    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,
    );

    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 $mysteryCell    = $line->[9];
            my $altMysteryCell = $line->[8];

            if ( $mysteryCell =~ m/^(\w{3}) (\d{4})$/ || $altMysteryCell =~ m/^(\w{3}) (\d{4})$/ ) {
                my $monthName = $1;
                my $day       = 1;
                my $year      = $2;
                my $month     = $months{ lc($monthName) };
                my $date      = sprintf( "%04d-%02d-%02d", $year, $month, $day );

                $self->{_dateBegin}         = $date;
                $self->{_dateNormalization} = 'month';
            } elsif ( $mysteryCell =~ m/^(\w{3})-\w{3} (\d{4})$/ || $altMysteryCell =~ m/^(\w{3})-\w{3} (\d{4})$/ ) {
                my $monthName = $1;
                my $day       = 1;
                my $year      = $2;
                my $month     = $months{ lc($monthName) };
                my $date      = sprintf( "%04d-%02d-%02d", $year, $month, $day );

                $self->{_dateBegin}         = $date;
                $self->{_dateNormalization} = 'quarter';
            } elsif ( $mysteryCell =~ m/^(\w{3})$/ || $altMysteryCell =~ m/^(\w{3})$/ ) {
                $self->{_currencyCode} = $1;

                # We should have found the date in the row above the currency code,
                # so let's check for it now.
                if ( !$self->{_dateBegin} ) {
                    die "Unable to find date";
                }

                last;
            }
        }
    }

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

}

sub rDuration {
    my $self     = shift;
    my $duration = $self->_getByFieldName('rDuration');

    if ( $duration =~ /^PDL(.*)$/ ) {
        $duration = $1;
    }

    return $duration;
}

sub productType {
    my $self              = shift;
    my $productType       = $self->_getByFieldName('rProductType');
    my $secondProductType = $self->_getByFieldName('secondProductType');

    if ( $productType =~ /\w+/i ) {
        if ( $productType =~ /audio/i ) {
            return BookPub::DB::Item::Sale::kProductTypeAudioBook;
        } else {
            return BookPub::DB::Item::Sale::kProductTypeEBook;
        }
    } elsif ( $secondProductType =~ /\w+/i ) {
        if ( $secondProductType =~ /audio/i ) {
            return BookPub::DB::Item::Sale::kProductTypeAudioBook;
        } else {
            return BookPub::DB::Item::Sale::kProductTypeEBook;
        }
    } else {
        $self->fail("Cannot find product type");
    }
}

sub formatType {
    my $self         = shift;
    my $format       = $self->_getByFieldName('rFormat');
    my $secondFormat = $self->_getByFieldName('secondFormat');

    if ( $format =~ /\w+/i ) {
        if ( $format =~ /audio/i ) {
            return undef;
        } else {
            return BookPub::DB::Item::Sale::kFormatTypeEBL;
        }
    } elsif ( $secondFormat =~ /\w+/i ) {
        if ( $secondFormat =~ /audio/i ) {
            return undef;
        } else {
            return BookPub::DB::Item::Sale::kFormatTypeEBL;
        }
    } else {
        $self->fail("Cannot find format type");
    }
}

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

    my $countryObj = Common::Country->Get($code) || $self->fail("Unknown country code '$code'");

    return $countryObj->alpha2();
}

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

    $units = sprintf( "%d", $units );

    return $units;
}

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

    if ( lc($purchaseType) eq 'pdl' ) {
        return BookPub::DB::Item::Sale::kPurchaseTypeLoan;
    } elsif ( lc($purchaseType) eq 'purchase' ) {
        return BookPub::DB::Item::Sale::kPurchaseTypeDownload;
    } elsif ( lc($purchaseType) eq 'pdo' ) {
        return BookPub::DB::Item::Sale::kPurchaseTypeDownload;
    } elsif ( lc($purchaseType) eq 'upgrade' ) {
        return BookPub::DB::Item::Sale::kPurchaseTypeDownload;
    } elsif ( lc($purchaseType) eq 'adj' ) {
        return BookPub::DB::Item::Sale::kPurchaseTypeDownload;
    } elsif ( lc($purchaseType) eq 'cancellation' ) {
        my $model = $self->_getByFieldName('rModel');
        if ( $model =~ /Day/ ) {
            return BookPub::DB::Item::Sale::kPurchaseTypeLoan;
        } elsif ( $model =~ /1B\wU/ ) {
            return BookPub::DB::Item::Sale::kPurchaseTypeDownload;
        } elsif ( $model =~ /PDL\d+/ ) {
            return BookPub::DB::Item::Sale::kPurchaseTypeLoan;
        } else {
            $self->fail("Unknown model '$model'");
        }
    } elsif ($purchaseType) {
        $self->fail("Unknown purchase type '$purchaseType'");
    }
}

1;
