#---------------------------------------------------------------
# ____                   _ _         ____  _
#|  _ \ ___  _   _  __ _| | |_ _   _/ ___|| |__   __ _ _ __ ___
#| |_) / _ \| | | |/ _` | | __| | | \___ \| '_ \ / _` | '__/ _ \
#|  _ < (_) | |_| | (_| | | |_| |_| |___) | | | | (_| | | |  __/
#|_| \_\___/ \__, |\__,_|_|\__|\__, |____/|_| |_|\__,_|_|  \___|
#            |___/             |___/
#
# Copyright (C) 2010 RoyaltyShare, Inc.   All Rights Reserved
#---------------------------------------------------------------

package RPS::Import::EMIForeignDigital::v1;

use strict;

use lib '/app/tools/rps/lib';
use RPS::DB::Item::Client;

use lib '/app/tools/common/lib';
use Common::Country;
use Common::Consts;
use Common::Assert;
use Common::Log;

use lib '/app/tools/data_classes/lib';

use lib '/app/tools/rps/lib';
use RPS::Import::SaleRec;
use RPS::DB::Item::MediaType;
use RPS::File::Sale;

use lib '/app/tools/rps/lib';
use RPS::Import::Importer;
use base 'RPS::Import::Importer';

my %gTerritoryMap = (
    'philippines (polyeast)' => 'philippines',
    'taiwan (gold typhoon)'  => 'taiwan',
    'virgin india'           => 'india',
    'arabia'                 => 'united arab emirates',
);

sub _fieldMap {
    {
        label      => 1,
        territory  => 0,
        date       => 0,    # only on summary sheet
        type       => 7,
        format     => 7,
        service_id => 4,
        artist     => 2,
        upc        => 5,
        isrc       => 6,
        title      => 3,    # album or track name
        quantity   => 10,
        net_price  => 12,
    };
}

sub _importLines {
    my $self        = shift;
    my %args        = @_;
    my $fileObj     = $args{file};
    my $version     = $args{file}->VersionNum();
    my $fileName    = $args{file}->OrigFileName();
    my $serviceID   = $args{file}->ServiceID;
    my $sheet_count = 0;

    assert( defined $args{sheets} );
    assert( defined $version );

    my $offsets     = $self->_fieldMap;
    my $sheet_names = $args{sheet_names};
    my $sheets      = $args{sheets};
    my $linenum     = 1;

    my ( $dateBegin, $dateEnd );

    # foundDate - set once the begin/end dates have been determined.
    my $foundDate;

    for ( my $sheetIndex = 0 ; $sheetIndex < scalar @{ $args{sheets} } ; $sheetIndex++ ) {
        my $sheet = $sheets->[$sheetIndex];

        my $foundHeader = 0;
        for ( my $lineIndex = 0 ; $lineIndex < scalar @$sheet ; $lineIndex++ ) {

            $linenum = $lineIndex + 1;
            my $line = $sheet->[$lineIndex];

            if ( $sheetIndex == 0 ) {

                # Get date range

                my $_date = $line->[ $offsets->{date} ];

                if (   $_date =~ /^jan/i
                    || $_date =~ /^feb/i
                    || $_date =~ /^mar/i
                    || $_date =~ /^apr/i
                    || $_date =~ /^may/i
                    || $_date =~ /^jun/i
                    || $_date =~ /^jul/i
                    || $_date =~ /^aug/i
                    || $_date =~ /^sep/i
                    || $_date =~ /^oct/i
                    || $_date =~ /^nov/i
                    || $_date =~ /^dec/i ) {
                    if ( $_date !~ m/[a-z]{3}'\d\d/i ) {
                        print STDERR "Unrecognized date '$_date'\n";
                        $self->errstr("Unrecognized date on line $linenum: $_date");
                        return undef;
                    } else {
                        my $date = _getDate($_date);

                        $dateBegin = $date if ( !$dateBegin );
                        $dateEnd   = $date if ( !$dateEnd );

                        $dateBegin = $date if ( $dateBegin > $date );
                        $dateEnd   = $date if ( $dateEnd < $date );
                    }

                }

                next;

            } else {

                if ( !$dateBegin && !$dateEnd ) {
                    print STDERR "Unable to determine date range on sheet 1\n";
                    $self->errstr("Unable to determine date range on sheet 1");
                    return undef;
                } else {
                    if ( !$foundDate ) {

                        # If this isn't the first sheet, then determine the actual end date

                        my ( $_begin, $_end ) = $self->_getDates( date_begin => $dateEnd );

                        $dateEnd = $_end;

                        # Convert to valid date format

                        $dateBegin =
                          sprintf( "%04d-%02d-%02d", substr( $dateBegin, 0, 4 ), substr( $dateBegin, 4, 2 ), substr( $dateBegin, 6, 2 ) );

                        $foundDate = 1;
                    }
                }
            }

            if ( !$foundHeader ) {
                my $qty = $line->[ $offsets->{quantity} ];

                if ( 'Net Sales Units' eq $line->[ $offsets->{quantity} ] ) {
                    $foundHeader = 1;
                }
                next;
            }

            my $currencyCode = 'GBP';

            my $serviceProductID = $line->[ $offsets->{service_id} ];

            my $mediaType     = mediaType( $line->[ $offsets->{format} ] );
            my $productType   = productType( $line->[ $offsets->{format} ], $serviceProductID );
            my $productFormat = formatType( $line->[ $offsets->{format} ] );

            my $trackTitle;
            my $albumTitle;
            my $isrc = $line->[ $offsets->{isrc} ];
            if ( 'NA' eq $isrc ) {
                undef $isrc;
                $albumTitle = $line->[ $offsets->{title} ];
            } else {
                $trackTitle = $line->[ $offsets->{title} ];
            }

            my $artist   = $line->[ $offsets->{artist} ];
            my $label    = $line->[ $offsets->{label} ];
            my $upc      = $line->[ $offsets->{upc} ];
            my $units    = $line->[ $offsets->{quantity} ];
            my $netPrice = $line->[ $offsets->{net_price} ];

    #            print STDERR "line($linenum): units($units) netPrice($netPrice) artist($artist) aTitle($albumTitle) tTitle($trackTitle)\n";

            if ( ( $units || $artist ) && $netPrice && ( '' ne $albumTitle || '' ne $trackTitle ) ) {

                my $territory = $line->[ $offsets->{territory} ];
                $territory = _normalizeTerritory($territory);

                my $countryObj = Common::Country->Get($territory);
                my $country = $countryObj->alpha2 if ($countryObj);

                my $unitPrice = $netPrice / $units if ( $units != 0 );

                $unitPrice *= -1 if ( $unitPrice < 0 );

                my $sale = RPS::Import::SaleRec->new();

                $sale->labelName($label);
                $sale->mediaType($mediaType);
                $sale->productType($productType);
                $sale->formatType($productFormat);
                $sale->dateBegin($dateBegin);
                $sale->dateEnd($dateEnd);
                $sale->trackName($trackTitle);
                $sale->albumName($albumTitle);
                $sale->artistName($artist);
                $sale->upc($upc);
                $sale->isrc($isrc);
                $sale->serviceProductID($serviceProductID);
                $sale->units($units);
                $sale->price($unitPrice);
                $sale->countryCode($country);
                $sale->currencyCode($currencyCode);
                $sale->lineNum($linenum);

                $self->_insertSale( sale => $sale );
            }
        }
    }

    return $linenum;
}

sub _normalizeTerritory {
    my ($country) = @_;
    $country =~ s/EMI Records //;
    $country =~ s/EMI //;
    return $gTerritoryMap{ lc $country } || $country;    # normalize if necessary
}

sub _getDate {

    my $dt = shift;

    my %gMonthMap = (
        'jan' => 1,
        'feb' => 2,
        'mar' => 3,
        'apr' => 4,
        'may' => 5,
        'jun' => 6,
        'jul' => 7,
        'aug' => 8,
        'sep' => 9,
        'oct' => 10,
        'nov' => 11,
        'dec' => 12,
    );
    my $m     = substr( $dt, 0, 3 );
    my $month = $gMonthMap{ lc $m };
    my $year  = substr( $dt, -2 );

    my $date = sprintf( "20%02d%02d01", $year, $month );

    return $date;
}

sub productType {
    my $format    = shift || return;
    my $productID = shift || return;

    if ( $format =~ /album download/i ) {
        return RPS::File::Sale::TYPE_ALBUM;

    } elsif ( $format =~ /subscr download/i && $productID =~ /^0.{11}$/ ) {
        return RPS::File::Sale::TYPE_ALBUM;

    } elsif ( $format =~ /subscr download/i ) {
        return RPS::File::Sale::TYPE_TRACK;

    } elsif ( $format =~ /track download/i ) {
        return RPS::File::Sale::TYPE_TRACK;

    } elsif ( $format =~ /track ringtune/i ) {
        return RPS::File::Sale::TYPE_TRACK;

    } elsif ( $format =~ /track ringback/i ) {
        return RPS::File::Sale::TYPE_TRACK;

    } elsif ( $format =~ /video download/i && $productID =~ /^0.{11}$/ ) {
        return RPS::File::Sale::TYPE_ALBUM;

    } elsif ( $format =~ /video download/i ) {
        return RPS::File::Sale::TYPE_TRACK;

    } else {
        die "Unable to determine product type: Format: $format ID: $productID";
    }
}

sub formatType {
    my $format = shift || return;

    if ( $format =~ /album download/i ) {
        return RPS::File::Sale::FORMAT_DOWNLOAD;

    } elsif ( $format =~ /subscr download/i ) {
        return RPS::File::Sale::FORMAT_TETHERED;

    } elsif ( $format =~ /track download/i ) {
        return RPS::File::Sale::FORMAT_DOWNLOAD;

    } elsif ( $format =~ /track ringtune/i ) {
        return RPS::File::Sale::FORMAT_RINGTONE;

    } elsif ( $format =~ /track ringback/i ) {
        return RPS::File::Sale::FORMAT_RINGTONE;

    } elsif ( $format =~ /video download/i ) {
        return RPS::File::Sale::FORMAT_DOWNLOAD;

    } else {
        die "Unable to determine format type. Format: $format";
    }
}

sub mediaType {
    my $format = shift || return;

    if (   $format =~ /(album|track) download/i
        || $format =~ /subscr download/i
        || $format =~ /track (ringback|ringtone)/i ) {
        return RPS::DB::Item::MediaType::kMediaTypeAudio;
    } elsif ( $format =~ /video download/i ) {
        return RPS::DB::Item::MediaType::kMediaTypeVideo;
    } else {
        return undef;
    }

}

###
1;    # Play nicely.
###
