package BookPub::Import::Importer::RoyaltyShare;

use strict;
use Data::Dumper;

use lib '/app/tools/common/lib';
use Common::Util qw(formatFixedPoint);

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

# map version num to the field order
sub _fieldMap {
    my $self = shift;

    my %fieldMap = (
        3 => {

            # Header
            currencyCode => 'H1',

            # Body
            rPurchaseType => 'M',
            priceType     => 'S',
            rDistributor  => 'C',
            rServiceName  => 'D',

            conversionRate => 'AB',

            countryCode => 'P',
            rState      => 'N',
            rPostalCode => 'O',

            dateBegin => 'A',
            dateEnd   => 'B',

            rProductType => 'K',
            rFormat      => 'L',
            isbn         => 'E',
            rTitle       => 'F',
            rSubtitle    => 'G',
            rAuthor      => 'H',
            rImprint     => 'J',

            rUnits                 => 'T',
            rListPrice             => 'W',
            rListPriceCurrency     => 'X',
            rPurchasePrice         => 'U',
            rPurchasePriceCurrency => 'V',
            rTaxAmount             => 'Z',
            rDiscount              => 'Y',
            rUnitPrice             => 'AC',
            rRevenue               => 'AD',

            rDuration    => 'R',
            rInstitution => 'Q',

            rNativeListPrice         => 'W',
            rNativeListPriceCurrency => 'X',
        },
    );

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

sub _unverifiedFieldMap {
    my $self = shift;

    my %fieldMap = (
        3 => {
            headerUnits   => 'D1',
            headerRevenue => 'F1',
        },
    );

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

sub _useIsSaleRec     { 1 }
sub _headerIdentifier { ( dateBegin => 'Sale Start Date' ) }
sub _dateFormat       { [ 'numerical_year_first', 'iso' ] }
sub _validTabNames    { ['RS Digital Sales Template'] }

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

    if ( $purchaseType =~ /^Physical Retail$/i ) {
        return BookPub::DB::Item::Sale::kPurchaseTypePhysicalRetail;
    } elsif ( $purchaseType =~ /^Download$/i ) {
        return BookPub::DB::Item::Sale::kPurchaseTypeDownload;
    } elsif ( $purchaseType =~ /^Subscription Download$/i ) {
        return BookPub::DB::Item::Sale::kPurchaseTypeSubscriptionDL;
    } elsif ( $purchaseType =~ /^Stream$/i ) {
        return BookPub::DB::Item::Sale::kPurchaseTypeStream;
    } elsif ( $purchaseType =~ /^Print On Demand$/i ) {
        return BookPub::DB::Item::Sale::kPurchaseTypePrintOnDemand;
    } elsif ( $purchaseType =~ /^InAppPurchase$/i ) {
        return BookPub::DB::Item::Sale::kPurchaseTypeInAppPurchase;
    } elsif ( $purchaseType =~ /^Loan$/i ) {
        return BookPub::DB::Item::Sale::kPurchaseTypeLoan;
    } elsif ( $purchaseType =~ /^Promotional$/i ) {
        return BookPub::DB::Item::Sale::kPurchaseTypePromotional;
    } elsif ( $purchaseType =~ /^Library Sale$/i ) {

        #return BookPub::DB::Item::Sale::kPurchaseTypeLibrarySale;
        # Setting this to download since library is no longer a valid purchase type.
        return BookPub::DB::Item::Sale::kPurchaseTypeDownload;
    } elsif ($purchaseType) {
        $self->fail("Unknown purchase type '$purchaseType'");
    }
}

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

    if ( $purchaseType =~ /^Library Sale$/i ) {
        return BookPub::DB::Item::PriceTypeQualifier::kCorporate;
    }

    return undef;
}

sub _preProcess {
    my $self        = shift;
    my %args        = @_;
    my $sheet_names = $args{sheet_names};
    my $sheet_count = 0;

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

    my $units;
    my $revenue;

    # get unit and revenue totals and put them in the self object for use
    # in postProcess
    foreach my $sheet ( @{ $args{sheets} } ) {
        my $validTab;
        my $validTabNames = _validTabNames();
        foreach my $validTabName (@$validTabNames) {
            if ( $sheet_names->[$sheet_count] eq $validTabName ) {
                foreach my $line (@$sheet) {
                    $self->{line} = $line;

                    my $units = $self->_getByFieldName('rUnits');
                    if ( $units =~ /^-?\d+$/ ) {
                        $self->{_totalUnits} += $units;
                    }
                    my $revenue = $self->_getByFieldName('rRevenue');
                    if ( $revenue =~ /^-?\d*\.?\d*$/ ) {
                        $self->{_totalRevenue} += $revenue if defined $units && $units ne '';
                    }
                }
            }
            $sheet_count++;
        }
    }
}

sub _processHeader {
    my $self = shift;

    if ( $self->linenum() == 1 ) {
        my $line = $self->line;

        #grab units and revenue from the header to check against the calculated
        #units and revenue in _postProcess()
        my $headerUnits   = $self->_getByFieldName('headerUnits');
        my $headerRevenue = $self->_getByFieldName('headerRevenue');

        # save units and revenue from header to check in postProcess
        my $validTab;
        my $validTabNames = _validTabNames();
        foreach my $validTabName (@$validTabNames) {
            if ( $self->sheetname() =~ /$validTabName/i ) {
                $self->{_headerUnits}   = $headerUnits;
                $self->{_headerRevenue} = $headerRevenue;
            }
        }
    }
}

sub _postProcess {
    my $self = shift;
    $self->SUPER::_postProcess();

    my $headerUnits   = $self->{_headerUnits};
    my $headerRevenue = $self->{_headerRevenue};
    $headerRevenue = formatFixedPoint( $headerRevenue, 2 );

    my $units   = $self->{_totalUnits};
    my $revenue = $self->{_totalRevenue};
    $revenue = formatFixedPoint( $revenue, 2 );

    if ( $headerUnits != $units ) {
        $self->errstr("Header units ($headerUnits) does not match units total ($units) from the file");
        return undef;
    }

    if ( $headerRevenue != $revenue ) {
        $self->errstr("Header revenue ($headerRevenue) does not match revenue total ($revenue) from the file");
        return undef;
    }

}

sub _parseFormat {
    my $self   = shift;
    my $format = shift;

    return unless ( defined($format) );

    $format =~ s/^epub(\d+)$/\1/i;
    $format = sprintf( "%03d", $format ) if ( $format =~ /^\d+$/ );

    return
        $format =~ /^000$/ ? BookPub::DB::Item::Sale::kFormatTypeContentPackage
      : $format =~ /^001$/ ? BookPub::DB::Item::Sale::kFormatTypeHTML
      : $format =~ /^002$/ ? BookPub::DB::Item::Sale::kFormatTypePDF
      : $format =~ /^003$/ ? BookPub::DB::Item::Sale::kFormatTypePDFMerchant
      : $format =~ /^004$/ ? BookPub::DB::Item::Sale::kFormatTypeAdobeEBook
      : $format =~ /^005$/ ? BookPub::DB::Item::Sale::kFormatTypeMSLITLvl1_3
      : $format =~ /^006$/ ? BookPub::DB::Item::Sale::kFormatTypeMSLITLvl5
      : $format =~ /^007$/ ? BookPub::DB::Item::Sale::kFormatTypeNetLibrary
      : $format =~ /^008$/ ? BookPub::DB::Item::Sale::kFormatTypeMetaText
      : $format =~ /^009$/ ? BookPub::DB::Item::Sale::kFormatTypeMightyWords
      : $format =~ /^010$/ ? BookPub::DB::Item::Sale::kFormatTypeEReader
      : $format =~ /^011$/ ? BookPub::DB::Item::Sale::kFormatTypeSoftbook
      : $format =~ /^012$/ ? BookPub::DB::Item::Sale::kFormatTypeRocketBook
      : $format =~ /^013$/ ? BookPub::DB::Item::Sale::kFormatTypeGemStar1100
      : $format =~ /^014$/ ? BookPub::DB::Item::Sale::kFormatTypeGemStar1200
      : $format =~ /^015$/ ? BookPub::DB::Item::Sale::kFormatTypeFranklinEBookman
      : $format =~ /^016$/ ? BookPub::DB::Item::Sale::kFormatTypeBooks24x7
      : $format =~ /^017$/ ? BookPub::DB::Item::Sale::kFormatTypeDigitalOwl
      : $format =~ /^018$/ ? BookPub::DB::Item::Sale::kFormatTypeHandheldmed
      : $format =~ /^019$/ ? BookPub::DB::Item::Sale::kFormatTypeWizeUp
      : $format =~ /^020$/ ? BookPub::DB::Item::Sale::kFormatTypeTK3
      : $format =~ /^021$/ ? BookPub::DB::Item::Sale::kFormatTypeLitraweb
      : $format =~ /^022$/ ? BookPub::DB::Item::Sale::kFormatTypeMOBI
      : $format =~ /^023$/ ? BookPub::DB::Item::Sale::kFormatTypeOPF
      : $format =~ /^024$/ ? BookPub::DB::Item::Sale::kFormatTypeTownCompasData
      : $format =~ /^025$/ ? BookPub::DB::Item::Sale::kFormatTypePlainText
      : $format =~ /^026$/ ? BookPub::DB::Item::Sale::kFormatTypeExeBook
      : $format =~ /^027$/ ? BookPub::DB::Item::Sale::kFormatTypeSonyBBeB
      : $format =~ /^028$/ ? BookPub::DB::Item::Sale::kFormatTypeVitalSource
      : $format =~ /^029$/ ? BookPub::DB::Item::Sale::kFormatTypeEPub
      : $format =~ /^030$/ ? BookPub::DB::Item::Sale::kFormatTypeMyiLibrary
      : $format =~ /^031$/ ? BookPub::DB::Item::Sale::kFormatTypeKindle
      : $format =~ /^032$/ ? BookPub::DB::Item::Sale::kFormatTypeGoogle
      : $format =~ /^033$/ ? BookPub::DB::Item::Sale::kFormatTypeVook
      : $format =~ /^034$/ ? BookPub::DB::Item::Sale::kFormatTypeDXReader
      : $format =~ /^035$/ ? BookPub::DB::Item::Sale::kFormatTypeEBL
      : $format =~ /^036$/ ? BookPub::DB::Item::Sale::kFormatTypeEbrary
      : $format =~ /^037$/ ? BookPub::DB::Item::Sale::kFormatTypeISilo
      : $format =~ /^038$/ ? BookPub::DB::Item::Sale::kFormatTypePlucker
      : $format =~ /^039$/ ? BookPub::DB::Item::Sale::kFormatTypeVitalBook
      : $format =~ /^098$/ ? BookPub::DB::Item::Sale::kFormatTypeMultipleFormats
      : $format =~ /^099$/ ? BookPub::DB::Item::Sale::kFormatTypeUnknownEBook
      :                      undef;
}

sub _parseProductType {
    my ( $self, $format ) = @_;

    return
        $format =~ /eBook/i ? BookPub::DB::Item::Sale::kProductTypeEBook
      : $format =~ /audio/i ? BookPub::DB::Item::Sale::kProductTypeAudioBook
      :                       undef;
}

sub _isSaleRec {
    my $self = shift;
    my $validTab;
    my $validTabNames = _validTabNames();
    foreach my $validTabName (@$validTabNames) {
        if ( $self->sheetname() =~ /^$validTabName$/i ) {
            $validTab = 1;
        }
    }
    return unless $validTab;
    return unless $self->rRevenue;

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

1;
