package BookPub::Import::Importer::iGroup::Version1;

use strict;
use warnings;

use Date::Calc qw(Add_Delta_Days);
use Data::Dumper;

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

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

sub _headerIdentifier { ( isbn => 'ISBN' ) }

sub _fieldMap {
    my $self = shift;

    my $map = {
        'order details' => {
            isbn       => 'B',
            rTitle     => 'C',
            rAuthor    => 'D',
            rListPrice => 'F',
        },
    };

    # ignore all sheets except 'order details'
    my $sheet = lc( $self->sheetname ) || return {};
    $sheet =~ /order details/ ? return $map->{$sheet} : return {};
}

sub _unverifiedFieldMap {
    { altListPrice => 'G', };
}

#   This field map will only be used for the summary tab
#
my %summaryFieldMap = (
    date          => 0,
    orderNumber   => 1,
    rInstitution  => 2,
    rPurchaseType => 4,
    commission    => 6,

);

#   This field map will only be used for capturing the order numbers
#
my %orderNumberFieldMap = (
    orderNumberText => 0,
    orderNumber     => 1,
);

#   This field map will only be used for capturing the discount
#
my %discountFieldMap = (
    discountText => 3,
    discount     => 4,
);

#   This field map will only be used for capturing the adjustment
#
my %adjustmentFieldMap = (
    adjustmentText => 3,
    adjustment     => 4,
);

my %summaryData;
my %orderNumbers;
my %discountLines;
my %adjustmentLines;

sub priceType                  { 'rrp' }
sub productType                { BookPub::DB::Item::Sale::kProductTypeEBook }
sub rProductType               { BookPub::DB::Item::Sale::kProductTypeEBook }
sub _autoParseTitleAndSubtitle { 1 }
sub _useIsSaleRec              { 1 }
sub rUnits                     { 1 }
sub rPurchaseType              { $_[0]->purchaseType }
sub rRevenue                   { $_[0]->revenue }

sub rServiceName {
    return BookPub::Tracker::Service::GetDefaultServiceName(
        service_id => shift->serviceID
    );
}

sub countryCode {
    my $self = shift;

    if ( Common::RSApp::GetClientID =~ /^(?:314|361|346)$/ ) {    # Bloomsbury USA, RLPG
        return 'SG';
    }
    if ( Common::RSApp::GetClientID =~ /^(?:335)$/ ) {    # Berrett-Koehler
        return 'HK';
    }

    $self->fail("Cannot determine country code for not BB or RLPG clients.");
}

sub currencyCode { 'USD' }

sub rListPriceCurrency { 'USD' }

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

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

    my $sheetnum = 0;

    foreach my $sheet ( @{ $args{sheets} } ) {
        my $sheetname = $args{sheet_names}->[$sheetnum];
        $sheetnum++;
        my $lineNum = 0;
        my $orderNumber;

        # We need to go through the summary tab and store some of that data in a hash
        # so that we can access it while processing the Details tab.
        # Edit #2, this sheetname thing is getting a little extreme, maybe on the next
        # addition to the if, we should just go with $sheetname ne 'Order Details'
        if (   $sheetname eq 'Rowman & Littlefield'
            || $sheetname eq 'Rowman &amp; Littlefield'
            || $sheetname eq 'NBN'
            || $sheetname eq 'A&C Black'
            || $sheetname eq 'Hart'
            || $sheetname eq 'RLPG'
            || $sheetname eq 'Bloomsbury'
            || $sheetname eq 'Berrett-Koehler' ) {
            my $foundHeader = 0;
            foreach my $line (@$sheet) {

                if ( $line->[0] eq 'Date' ) {
                    $foundHeader = 1;
                    next;
                } elsif ( $foundHeader == 0 ) {
                    next;
                }

                my $orderNumber = $line->[ $summaryFieldMap{orderNumber} ];

                if ( !$orderNumber && $foundHeader == 1 ) {
                    last;
                }

                # Grab the data and store it
                $summaryData{$orderNumber}{date}          = $line->[ $summaryFieldMap{date} ];
                $summaryData{$orderNumber}{commission}    = $line->[ $summaryFieldMap{commission} ];
                $summaryData{$orderNumber}{rPurchaseType} = $line->[ $summaryFieldMap{rPurchaseType} ];
                $summaryData{$orderNumber}{rInstitution}  = $line->[ $summaryFieldMap{rInstitution} ];
            }

        } elsif ( $sheetname =~ /Order Details/ ) {

            # We need to read the file and associate the discount with the lines
            # that use it.
            # 1) start at 'Order #' and store start line value.
            # 2) read until the line with the extra discount is found, store the end value
            # 3) go back and set the extra discount value for all line from the start
            #    to end
            # 4) reset vars
            $lineNum = 1;
            my ( $startNum, $endNum, $discount, $adjustment );
            foreach my $line (@$sheet) {
                my $orderNumberText = $line->[ $orderNumberFieldMap{orderNumberText} ];
                my $discountText    = $line->[ $discountFieldMap{discountText} ];
                my $adjustmentText  = $line->[ $adjustmentFieldMap{adjustmentText} ];
                if ( $orderNumberText =~ /Order \#/ ) {

                    #start group
                    $startNum = $lineNum;
                }

                if ( $adjustmentText =~ /Total Sales Amount/ ) {
                    $adjustment = $line->[ $adjustmentFieldMap{adjustment} ];

                    # loop to set all values in adjustmentLines
                    for ( my $i = $startNum ; $i <= $lineNum ; $i++ ) {
                        $adjustmentLines{$sheetnum}{$i} = $adjustment;
                    }
                }

                if ( $discountText =~ /Special price on additional \& upgraded content/ || $discountText =~ /After Discount/ ) {

                    #end group
                    $endNum   = $lineNum;
                    $discount = $line->[ $discountFieldMap{discount} ];

                    # loop to set all values in DISCOUNTLines
                    for ( my $i = $startNum ; $i <= $endNum ; $i++ ) {
                        $discountLines{$sheetnum}{$i} = $discount;
                    }

                    # They are now giving us multiple sub groups under one order number.
                    # So we'll just have to assume that the next group starts right after
                    # this one ends.
                    $startNum = $lineNum + 1;
                }

                $lineNum++;
            }
            $lineNum = 0;
            foreach my $line (@$sheet) {

                # We capture the order numbers to be used for each line here
                # since the first one comes before the headers.
                my $orderNumberText = $line->[ $orderNumberFieldMap{orderNumberText} ];
                if ( $orderNumberText =~ /Order \#/ ) {
                    $orderNumber = $line->[ $orderNumberFieldMap{orderNumber} ];
                    if ( !$orderNumber ) {
                        my $line = $lineNum + 1;
                        $self->fail( "No order number was found on line " . $line );
                    }
                }
                if ($orderNumber) {
                    $orderNumbers{$sheetnum}{$lineNum} = $orderNumber;
                }
                $lineNum++;
            }
        } else {
            $self->fail( "Unexpected tab name " . $sheetname );
        }
    }
}

sub preProcessLine {
    my $self = shift;

    my $sheetNum    = $self->sheetnum;
    my $lineNum     = $self->linenum;
    my $orderNumber = $orderNumbers{$sheetNum}{$lineNum};
    return unless $orderNumber =~ /;/;

    my @ordersGroup = split '\s*;\s*', $orderNumber;
    my $lastOrderNumber = pop @ordersGroup;

    # save/duplicate a row for each order number
    foreach (@ordersGroup) {
        $orderNumbers{$sheetNum}{$lineNum} = $_;
        $self->_processLine();
    }

    $orderNumbers{$sheetNum}{$lineNum} = $lastOrderNumber;

    return 1;
}

sub rDiscount {
    my $self        = shift;
    my $sheetnum    = $self->sheetnum;
    my $line        = $self->linenum;
    my $orderNumber = $orderNumbers{$sheetnum}{$line};
    my $commission  = $summaryData{$orderNumber}{commission};
    my $discount    = $discountLines{$sheetnum}{$line};
    my $adjustment  = $adjustmentLines{$sheetnum}{$line};
    if ( !$discount ) {
        $discount = 0;
    }
    if ( !$adjustment ) {
        $adjustment = 1;
    }

    my $ret = ( 1 - $discount ) * ( 1 - $commission ) * $adjustment;

    return $ret;
}

sub _getDateBegin {
    my $self        = shift;
    my $sheetnum    = $self->sheetnum;
    my $orderNumber = $orderNumbers{$sheetnum}{ $self->linenum };
    my $date        = $summaryData{$orderNumber}{date};

    if ( $date =~ /^\d{5}$/ and $date > 38716 ) {
        $date = Spreadsheet::ParseExcel::Utility::ExcelFmt( "yyyy-mm-dd", $date );
    }

    return $date;
}

sub rInstitution {
    my $self        = shift;
    my $sheetnum    = $self->sheetnum;
    my $orderNumber = $orderNumbers{$sheetnum}{ $self->linenum };
    my $institution = $summaryData{$orderNumber}{rInstitution};

    return $institution;

}

sub purchaseType {
    my $self        = shift;
    my $sheetnum    = $self->sheetnum;
    my $orderNumber = $orderNumbers{$sheetnum}{ $self->linenum };
    my $type        = $summaryData{$orderNumber}{rPurchaseType};

    if ( $type =~ /Perpetual/i ) {
        return BookPub::DB::Item::Sale::kPurchaseTypeLoan;
    }

    return;

}

sub units {
    my $self = shift;
    my $revenue = $self->rListPrice || return 1;
    return $revenue < 0 ? -1 : 1;
}

sub rListPrice {
    my $self = shift;

    my $listPrice = $self->_getByFieldName('altListPrice');

    if ( !$listPrice ) {
        $listPrice = $self->_getByFieldName('rListPrice');
    }

    return $listPrice;
}

sub revenue {
    my $self = shift;

    my $listPrice = $self->rListPrice;
    my $discount  = $self->rDiscount;

    my $revenue = $listPrice * $discount;
    my $line    = $self->linenum;

    return $revenue;
}

sub _isSaleRec {
    my $self   = shift;
    my $title  = $self->_getByFieldName('rTitle');
    my $author = $self->_getByFieldName('rAuthor');

    if ( $self->_getByFieldName('isbn') eq 'ISBN' ) {
        return undef;
    }

    if ( $self->_getByFieldName('isbn') =~ /^PO/ ) {
        return undef;
    }

    if (   ( $author =~ /^Total/ || $author =~ /^Special/ || $author =~ /^After/ || $author =~ /^TAEBDC/ )
        && ( $title eq '' || undef $title ) ) {
        return undef;
    }

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

sub isFree {
    my $self = shift;

    return !$self->rListPrice ? 'Y' : 'N';
}


1;
