package BookPub::Import::Importer::Apple::Version2;

use strict;

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

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

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

sub _fieldMap {
    {
        serviceProductID       => 'K',
        currencyCode           => 'I',
        countryCode            => 'R',
        dateBegin              => 'A',
        dateEnd                => 'B',
        isPreOrder             => 'S',
        rProductType           => 'P',
        rClientProductID       => 'E',
        isbn                   => 'D',
        rTitle                 => 'M',
        rAuthor                => 'L',
        rImprint               => 'N',
        rUnits                 => 'F',
        rListPrice             => 'G',
        rListPriceCurrency     => 'I',
        rPurchasePrice         => 'U',
        rPurchasePriceCurrency => 'V',
        rUnitPrice             => 'G',
        rRevenue               => 'H',
        rFormat                => 'P',
        rPromoCode             => 'T',
    };
}

sub _useIsSaleRec              { 1 }
sub _autoParseTitleAndSubtitle { 1 }

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

sub rIsbn13 {
    my $self = shift;

    my $isbn = $self->_getByFieldName("isbn") || $self->_getByFieldName("rClientProductID");

    return $isbn;
}

sub priceType {
    my $self = shift;

    my $clientID = Common::RSApp::GetClientID();
    if ( $self->productType eq BookPub::DB::Item::Sale::kProductTypeEBook ) {
        if ( $clientID =~ /^335$/ ) {         # BKP
            return $self->countryCode =~ /^(?:US|CA)$/ ? 'agency' : 'agencyplustax';
        } elsif ( $clientID =~ /^359$/ && $self->filename =~ /^85116969/ ) {    # MMUK
            return 'agencyplustax';
        } elsif ( $clientID =~ /^348$/ ) {    # MMAU
            return 'agencyplustax';
        } elsif ( $clientID =~ /^346$/ ) {    # RLPG
            return 'rrp';
        } elsif ( $clientID =~ /^324$/ && $self->filename =~ /^80127007/ ) {    # Wiley
            return 'rrp';
        } else {
            return 'agency';
        }
    } elsif ( $self->productType eq BookPub::DB::Item::Sale::kProductTypeAudioBook ) {
        if ( $clientID =~ /^318$/ ) {         # MMUS
            return 'suppliersnet';
        }
        return 'rrp';
    } elsif( $self->productType eq BookPub::DB::Item::Sale::kProductTypeEJournal ) {
        return 'rrp';
    }

}

sub dateBegin {
    my $self = shift;

    my $dateBegin;
    my $dateEnd;

    my $startDate = $self->_getDateBegin();
    my $endDate   = $self->_getDateEnd();

    if ( $startDate && $endDate ) {
        ( $dateBegin, $dateEnd ) = Common::Util::normalize_sales_month_dates( $startDate, $endDate );
    }

    return $dateBegin;
}

sub dateEnd {
    my $self = shift;

    my $dateBegin;
    my $dateEnd;

    my $startDate = $self->_getDateBegin();
    my $endDate   = $self->_getDateEnd();

    if ( $startDate && $endDate ) {
        ( $dateBegin, $dateEnd ) = Common::Util::normalize_sales_month_dates( $startDate, $endDate );
    }

    return $dateEnd;
}

sub _getDateBegin {
    my $self = shift;

    my $date = $self->_getByFieldName('dateBegin') || '';
    if ( $date =~ /^(\d{1,2})\/(\d{1,2})\/(\d{2,4})$/ ) {
        return sprintf "20%02d-%02d-%02d", substr($3, -2), $1, $2;
    }

    $self->fail("Unable to determine dateBegin from: '$date'.");
}

sub _getDateEnd {
    my $self = shift;

    my $date = $self->_getByFieldName('dateEnd') || '';
    if ( $date =~ /^(\d{1,2})\/(\d{1,2})\/(\d{2,4})$/ ) {
        return sprintf "20%02d-%02d-%02d", substr($3, -2), $1, $2;
    }

    $self->fail("Unable to determine dateEnd from: '$date'.");
}

sub purchaseType {
    my $format = shift->rFormat();
    if ( $format && ( $format =~ /^IA[9CY]$/i || $format =~ /^IA[9CY]-M$/i ) ) {
        return BookPub::DB::Item::Sale::kPurchaseTypeSubscriptionDL;
    } elsif ( $format && ( $format =~ /^IA1$/i || $format =~ /^IA1-M$/i || $format =~ /^FI1$/i ) ) {
        return BookPub::DB::Item::Sale::kPurchaseTypeInAppPurchase;
    } else {
        return BookPub::DB::Item::Sale::kPurchaseTypeDownload;
    }
}

sub _isSaleRec {
    my $self = shift;

    my $format = $self->SUPER::rFormat() || return;
    my $revenue = $self->revenue();

    if ( $format && $format =~ /^7[TF]?$/i && !$revenue ) {
        Log->warn("Ignoring sale with 'Update' format type");
        return;
    }

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

sub rProductType { shift->productType }

sub productType {
    my $self = shift;

    my $type = $self->_getByFieldName('rProductType') || '';
    my $vendor = $self->_getByFieldName('rClientProductID') || '';

    my $typeCode = $self->_parseProductType($type, $vendor);
    return $typeCode;
}

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

    if ( $type && ( $type =~ /^eb1$/i || $type =~ /^b1$/i || $type =~ /^f1$/ ) ) {
        return BookPub::DB::Item::Sale::kProductTypeEBook;
    } elsif ( $type =~ /^b$/i ) {
        return BookPub::DB::Item::Sale::kProductTypeAudioBook;
    } elsif ( $type =~ /^IAY$/i && $vendor && $vendor =~ /^0JRNL/i) {
        return BookPub::DB::Item::Sale::kProductTypeEJournal;
    } elsif ( $self->rFormat ) {
        # the product type field is reporting a format type, not a product type
        return BookPub::DB::Item::Sale::kProductTypeEBook;
    } else {
        return $self->SUPER::_parseProductType($type);
    }

    return;
}

sub rFormat {
    my $self    = shift;
    my $format  = $self->SUPER::rFormat() || return;
    my $revenue = $self->revenue();

    # One apple format actually reports this information in the product type field.
    # See case #13326

    # Known format types:
    #   1 - Free or Paid Apps (iPhone/iPod)
    #   7 - Updates (iPhone/iPod)
    #   IA1 - In-App Purchase
    #   IA9 - In-App Subscription
    #   IAY  In-App Purchase Auto-renewable subscription (iOS)
    #   IAC  In-App Purchase Free subscription (iOS)
    #   1F - Free or Paid Apps (All)
    #   7F - Updates (All)
    #   1T - Free or Paid Apps (iPad)
    #   7T - Updates (iPad)
    #   F1  Free or paid app Mac app
    #   F7  Update Mac app
    #   FI1  In-App Purchase Mac app
    #   1E  Paid app Custom iPhone and iPod touch (iOS)
    #   1EP  Paid app Custom iPad (iOS)
    #   1EU  Paid app Custom universal (iOS)

    if ( $format =~ / ^ ( 1[TF]? | F1 | IA[19Y] | FI1 ) $ /ix ) {
        return $format;
    } elsif ( $format =~ /^7[TF]?$/i ) {
        $self->fail("application upgrade sales item containing unexpected revenue")
          if ($revenue);
    } else {

        # This isn't a format type we recognize.  Let product type actually handle any error cases
        return;
    }

}

sub formatType {
    my $self = shift;
    my $type = $self->SUPER::rFormat || return;

    if ( $type =~ / ^ ( 1[TF]? | F1 | IA[19Y] | FI1 ) $ /ix ) {
        return BookPub::DB::Item::Sale::kFormatTypeAppleMultimedia;
    } else {
        return;
    }
}

sub rListPrice {
    my $self = shift;

    my $clientID   = Common::RSApp::GetClientID();
    my $rListPrice = abs( $self->_getByFieldName("rListPrice") || 0 );

    if ( $self->rProductType eq BookPub::DB::Item::Sale::kProductTypeEBook ) {
        $rListPrice = abs($self->_getByFieldName("rPurchasePrice") || 0) if ($clientID != 355); # NOT HUK
        $rListPrice *= 1.42747252747253 if $clientID == 355; # HUK
    }

    return $rListPrice;
}

sub rListPriceCurrency {
    my $self = shift;

    my $clientID   = Common::RSApp::GetClientID();
    my $rListPriceCurrency = $self->_getByFieldName("rListPriceCurrency") || '';

    if ( $self->rProductType eq BookPub::DB::Item::Sale::kProductTypeEBook ) {
        $rListPriceCurrency = $self->_getByFieldName("rPurchasePriceCurrency") if ($clientID != 355); # NOT HUK
    }

    return $rListPriceCurrency;
}

sub isPreOrder {
    my $preorder = shift->SUPER::isPreOrder() || return;

    return lc($preorder) eq 'p' ? 'Y' : undef;
}

sub rState {
    my $self = shift;

    my $state = $self->SUPER::rState() || return;
    my $country = $self->countryCode();

    if ( uc($country) eq 'US' && uc($state) eq 'US' ) {
        return undef;
    } else {
        return $state;
    }
}

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

    return abs($purchasePrice);
}

1;
