package RPS::Import::Nokia2;

use strict;

use Date::Calc qw(Days_in_Month Decode_Month);

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

use lib '/app/tools/common/lib';
use Common::Consts qw(%COUNTRY_TO_CODE %COUNTRY_CODE);
use Common::Util qw(trimspaces);
use Common::RSDB;
use Common::RSApp;
use Common::Assert;
use Common::Consts;
use Common::Country;

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

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

use DBI;
use Data::Dumper;

#use constant FIELD_TITLE            => 5;
#use constant FIELD_ARTIST           => 4;
#use constant FIELD_ISRC             => 6;
#use constant FIELD_UPC              => 7;
#use constant FIELD_CURRENCY_CODE    => 15;
#use constant FIELD_TOTAL            => 14;
#use constant FIELD_DELIVERY         => 2;
#use constant FIELD_PRICE            => 6;
#use constant FIELD_SALE_DATE        => 3;
#use constant FIELD_COUNTRY          => 13;
#use constant FIELD_LABEL            => 8;
#use constant FIELD_CATALOG_NUMBER   => 9;
#use constant FIELD_EXCHANGE         => 13;
#use constant FIELD_RATE             => 14;

my %field_map = (
    2 => {
        delivery  => 2,
        sale_date => 3,
        artist    => 4,
        title     => 5,
        isrc      => 6,
        upc       => 7,
        label     => 8,
        catalog   => 9,
        country   => 11,
        exchange  => 11,
        total     => 12,
        rate      => 12,
        currency  => 13,
    },
    3 => {
        delivery => 2,
        artist   => 3,
        title    => 4,
        isrc     => 8,
        upc      => 9,
        label    => 10,
        catalog  => 11,
        country  => 12,
        exchange => 12,
        units    => 14,
        total    => 16,
        rate     => 16,
    },
    4 => {
        revenue_row => 0,
        revenue_col => 4,
        delivery    => 2,
        artist      => 3,
        title       => 4,
        isrc        => 8,
        upc         => 9,
        label       => 10,
        catalog     => 11,
        country     => 12,
        exchange    => 12,
        units       => 14,
    },
);

my %delivery_formats = (
    'DOWNLOAD'              => RPS::File::Sale::FORMAT_DOWNLOAD,
    'Stream'                => RPS::File::Sale::FORMAT_STREAM,
    'Limited Download'      => RPS::File::Sale::FORMAT_DOWNLOAD,
    'Over the Air Download' => RPS::File::Sale::FORMAT_DOWNLOAD,
    'Ringtone'              => RPS::File::Sale::FORMAT_RINGTONE,
    'Ringback'              => RPS::File::Sale::FORMAT_RINGBACK,
    'Over the Air Download' => RPS::File::Sale::FORMAT_DOWNLOAD,
    'Burn'                  => RPS::File::Sale::FORMAT_DOWNLOAD,
    'Other'                 => RPS::File::Sale::FORMAT_STREAM,
    'Play'                  => RPS::File::Sale::FORMAT_STREAM,
    'Realtone'              => RPS::File::Sale::FORMAT_RINGTONE,
    'D'                     => RPS::File::Sale::FORMAT_DOWNLOAD,
    'S'                     => RPS::File::Sale::FORMAT_STREAM,
    'C'                     => RPS::File::Sale::FORMAT_DOWNLOAD,
);

my %gCountryCodeToCurrencyMap = (
    'US' => 'USD',
    'JP' => 'JPY',
    'NZ' => 'NZD',
    'IS' => 'ISD',
    'JM' => 'JMD',
    'EU' => 'EUR',
    'GB' => 'GBP',
    'CA' => 'CAD',
    'AU' => 'AUD',
    'DE' => 'EUR',
    'FR' => 'EUR',
    'BE' => 'EUR',
    'IT' => 'EUR',
    'CH' => 'CHF',
    'PL' => 'PLN',
    'LV' => 'LVL',
    'LT' => 'LTL',
    'KR' => 'KRW',
    'ZA' => 'ZAR',
    'GR' => 'EUR',
    'NL' => 'EUR',
);

my $currencyCode;

my %service_map = (
    "ovi music brazil"         => Client::Service::DSP_OVI_MUSIC,
    "ovi music finland"        => Client::Service::DSP_OVI_MUSIC,
    "ovi music germany"        => Client::Service::DSP_OVI_MUSIC,
    "ovi music italy"          => Client::Service::DSP_OVI_MUSIC,
    "ovi music singapore"      => Client::Service::DSP_OVI_MUSIC,
    "ovi music south africa"   => Client::Service::DSP_OVI_MUSIC,
    "ovi music spain"          => Client::Service::DSP_OVI_MUSIC,
    "ovi music sweden"         => Client::Service::DSP_OVI_MUSIC,
    "ovi music united kingdom" => Client::Service::DSP_OVI_MUSIC,
    "ovi music france"         => Client::Service::DSP_OVI_MUSIC,
    "ovi music norway"         => Client::Service::DSP_OVI_MUSIC,
);

#
# public methods
#

sub _importLines {
    my $self  = shift;
    my %args  = @_;
    my $lines = $args{lines};
    return undef unless ($lines);

    #my $version = $args{version}; # cmd-line testing
    #my $fileName = $args{OrigFileName}; # cmd-line testing
    my $version  = $args{file}->VersionNum();
    my $fileName = $args{file}->OrigFileName();
    my $offsets  = $field_map{$version};
    my $clientID = $args{client_id};

    if ( !$clientID ) {
        $clientID = $args{clientID};
    }

    if ( !$clientID ) {
        $self->errstr("couldn't get client ID");
        print STDERR "couldn't get client ID\n";
        return undef;
    }

    #print STDERR "Args: ".Dumper(\%args);

    print STDERR "client ID: $clientID\n";

    my $linenum         = 1;
    my $was_album_title = 0;
    my (
        %errors,        $passed_format,  $album,         $dateBegin,  $dateEnd,
        $total_columns, $fee_percentage, $exchange_rate, $commission, $commisable_units
    );

    if ( !defined $offsets->{currency} ) {
        my $client = RPS::DB::Item::Client->Lookup( client_id => $clientID );
        my $country_code = $client->country_code;
        $currencyCode = $gCountryCodeToCurrencyMap{$country_code};

        if ( !$currencyCode ) {
            $self->errstr("couldn't get base currency from country of origin");
            print STDERR "couldn't get base currency from country of origin\n";
            return undef;
        }
    }

    my ( $dateBegin, $dateEnd );

    ( $dateBegin, $dateEnd ) = $self->_getDates( date_begin => $fileName, type => 'text' );

    unless ( $dateBegin && $dateEnd ) {
        ( $dateBegin, $dateEnd ) = $self->_getDates( date_begin => $fileName, type => 'iso' );
    }

    unless ( $dateBegin && $dateEnd ) {
        ( $dateBegin, $dateEnd ) = $self->_getDates( date_begin => $fileName, type => 'us' );
    }

    unless ( $dateBegin && $dateEnd ) {
        ( $dateBegin, $dateEnd ) = $self->_getDates( date_begin => $fileName, type => 'numerical' );
    }

    unless ( $dateBegin && $dateEnd ) {
        $self->errstr("couldn't get dates from file name: $fileName");
        print STDERR "$fileName\n";
        return undef;
    }

    foreach my $line (@$lines) {
        $exchange_rate = $line->[ $offsets->{rate} ] if ( $line->[ $offsets->{exchange} ] eq "XR" );
        $commission    = $line->[ $offsets->{rate} ] if ( $line->[ $offsets->{exchange} ] eq "Net Revenue Commission" );
        $commisable_units++
          if ( $line->[ $offsets->{artist} ] ne ""
            && $line->[ $offsets->{artist} ] !~ /artist/i
            && $line->[ $offsets->{title} ] ne "" );
        $linenum++;
    }

    my $avg_price;
    my $total_units;
    my $total_revenue;

    $commission /= $commisable_units if ( $commission ne "" && $commisable_units > 0 );
    $linenum = 1;
    foreach my $line (@$lines) {
        my $artist = $line->[ $offsets->{artist} ];
        my $isrc   = $line->[ $offsets->{isrc} ];
        my $title  = $line->[ $offsets->{title} ];
        my $upc    = $line->[ $offsets->{upc} ];

        #my $price           = .01;
        my $price = ( defined $offsets->{total} ) ? $line->[ $offsets->{total} ] : 0;

        $currencyCode = $line->[ $offsets->{currency} ] if ( defined $offsets->{currency} );
        my $format = $delivery_formats{ $line->[ $offsets->{delivery} ] };

        my $product_type;

        if ( !$isrc ) {
            $product_type = RPS::File::Sale::TYPE_ALBUM;
        } else {
            $product_type = RPS::File::Sale::TYPE_TRACK;
        }

        my $units = 1;

        if ( ( $version == 3 ) || ( $version == 4 ) ) {
            $units = $line->[ $offsets->{units} ];
        }

        my $label           = $line->[ $offsets->{label} ];
        my $service_product = $line->[ $offsets->{catalog} ];

        $price /= $exchange_rate if ( $exchange_rate ne "" && $currencyCode ne "GBP" );
        $price += $commission if ( $commission != 0 );
        $currencyCode = "GBP" if ( $exchange_rate ne "" && $currencyCode ne "GBP" );

        if (   ( $artist ne "" )
            && ( $artist !~ /^artist$/i )
            && ( $units > 0 )
            && ( $title ne "" )
            && ( ( $price =~ /\d+/ ) || ( ( $version == 4 ) && ( $units =~ /\d+/ ) ) ) ) {
            my $sale = RPS::Import::SaleRec->new();

            my $countryName = $line->[ $offsets->{country} ];

            #            print STDERR "DEBUG: line $linenum: looking for country '$countryName'\n";

            my $country;
            if ( $countryName && '' ne $countryName ) {
                my $obj = Common::Country->Get($countryName);
                $country = $obj->alpha2();
            }

            unless ( $dateBegin && $dateEnd ) {
                $self->errstr( "couldn't get dates from " . $line->[ $offsets->{sale_date} ] . " at row $linenum " );
                print STDERR "$fileName\n";
                return undef;
            }

            unless ($country) {
                $self->errstr( "unknown country " . $line->[ $offsets->{country} ] . " at row $linenum " );
                print STDERR "$fileName\n";
                return undef;
            }

            $sale->productType($product_type);
            $sale->upc($upc);
            $sale->isrc($isrc)       if ( $isrc ne "" );
            $sale->trackName($title) if ( $isrc ne "" );
            $sale->albumName($title) if ( $isrc eq "" );
            $sale->formatType($format);
            $sale->serviceProductID($service_product);
            $sale->dateBegin($dateBegin);
            $sale->dateEnd($dateEnd);
            $sale->artistName($artist);
            $sale->labelName($label);
            $sale->price( sprintf( "%.8f", ( $price / $units ) ) ) if ( $version != 4 );
            $sale->units($units);
            $sale->currencyCode($currencyCode) if ($currencyCode);
            $sale->countryCode($country);
            $sale->lineNum($linenum);

            #$args{dumper}($sale); ## for cmd-line testing
            $self->_insertSale( sale => $sale );
        }

        #else { print STDERR "skip l:".$linenum." a:".$artist." t:".$title." u:".$units." p:".$price."\n"; }
        $linenum++;
    }
    return $linenum;
}

#
# Private methods
#

#sub _get_dates
#{
#    my $passed_date = shift;
#    my $version = shift;
#    my ($year,$month,$day);

#    if($version == 2){

#        if($passed_date =~ m/(\d{4})\D(\d+)\D(\d+)/){
#            ($year,$month,$day) = ($1, $2, $3);
#        }
#        elsif($passed_date =~ m/(\d+)\D(\d+)\D(\d{4})/){
#            ($day,$month,$year) = ($1, $2, $3);
#        }
#    }
#    elsif($version == 3){
#        if($passed_date =~
#        /(jan|feb|mar|apr|may|jun|jul|aug|sept|oct|nov|dec)/i){
#            $month = Decode_Month($1);
#        }

#        if($passed_date =~ /(\d{4})/){
#            $year = $1;
#        }
#        elsif($passed_date =~ /(\d{2})/){
#            $year = $1 + 2000;
#        }
#    }

#print STDERR "Returning dates: $month year: $year\n";

#    if(!($year || $month)){
#        return undef;
#    }

#    return (
#        sprintf("%04d-%02d-01", $year, $month),
#        sprintf("%04d-%02d-%02d", $year, $month, Days_in_Month($year, $month))
#    );
#}

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