package RPS::Import::DRASubset;

use strict;

use Date::Calc qw(Days_in_Month);

use lib '/app/tools/common/lib';
use Common::Util;
use Common::Consts qw(%COUNTRY_CODE);

use Common::RSMath qw(round);

use lib '/app/tools/data_classes/lib';
use Client::Service;

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

my %service_map = (
    'apple computer, inc.'     => Client::Service::DSP_ITUNES,
    'virginmega sas'           => Client::Service::DSP_VIRGINMEGA,
    'touch tunes, inc.'        => Client::Service::DSP_TOUCHTUNES,
    'hudson entertainment'     => Client::Service::DSP_HUDSON,
    'buongiorno vitaminic spa' => Client::Service::DSP_VITAMINIC,
    'mobilestreams'            => Client::Service::DSP_MOBILESTREAMS,
    'orange'                   => Client::Service::DSP_ORANGENEDERLAND,
    'fnac direct'              => Client::Service::DSP_FNAC,
);

my %format_map = (
    'permanent download'    => RPS::File::Sale::FORMAT_DOWNLOAD,
    'subscription play'     => RPS::File::Sale::FORMAT_STREAM,
    'ota'                   => RPS::File::Sale::FORMAT_DOWNLOAD,
    'subscription download' => RPS::File::Sale::FORMAT_DOWNLOAD,
    'master ringtone'       => RPS::File::Sale::FORMAT_RINGTONE,
    'polyphonic ringtone'   => RPS::File::Sale::FORMAT_RINGTONE,
);

my %field_map = (
    2 => {
        vendor_id   => 0,
        artist      => 1,
        track       => 2,
        album       => 3,
        isrc        => 4,
        upc         => 5,
        date_col    => 7,
        date_row    => 1,
        format_row  => 11,
        service_row => 12,
        start_col   => 37,
    },
);

#public methods

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

    my $lines   = $args{lines};
    my $fileObj = $args{file};
    my $version = $fileObj->VersionNum;

    #my $version = $args{version}; ## for cmd-line testing

    my $offsets = $field_map{$version};

    return undef unless ($lines);
    my ( $dateBegin, $dateEnd ) = $self->_getDates( $lines->[ $offsets->{'date_row'} ]->[ $offsets->{'date_col'} ] );
    unless ( $dateBegin && $dateEnd ) {
        $offsets->{'date_row'}++;
        ( $dateBegin, $dateEnd ) = $self->_getDates( $lines->[ $offsets->{'date_row'} ]->[ $offsets->{'date_col'} ] );
    }

    unless ( $dateBegin && $dateEnd ) {
        $self->errstr( "couldn't get dates from " . $lines->[ $offsets->{'date_row'} ]->[ $offsets->{'date_col'} ] );
        return undef;
    }

    my %errors;
    my @columns;

    my $start_col = 0;
  FIND_START: while ( $start_col < 300 ) {
        foreach my $format ( keys %format_map ) {
            if ( lc $lines->[ $offsets->{'format_row'} ]->[$start_col] eq $format ) {
                last FIND_START;
            }
        }
        $start_col++;
    }

    my $format;
    for ( my $i = $start_col ; $lines->[ $offsets->{'service_row'} ]->[$i] ne "" ; $i += 2 ) {
        if ( $lines->[ $offsets->{'format_row'} ]->[$i] ne "" ) {
            $format = $format_map{ lc $lines->[ $offsets->{'format_row'} ]->[$i] };
            unless ($format) {
                unless ( $errors{ $lines->[ $offsets->{'format_row'} ]->[$i] } ) {
                    print STDERR "unknown format: " . $lines->[ $offsets->{'format_row'} ]->[$i] . "\n";
                    $errors{ $lines->[ $offsets->{'format_row'} ]->[$i] } = 1;
                }
                $self->warning();
                next;
            }
        }

        $columns[$i]->{format} = $format;
        ( $columns[$i]->{service}, $columns[$i]->{country} ) = $self->_parseService( $lines->[ $offsets->{'service_row'} ]->[$i] );
        unless ( $columns[$i]->{service} ) {
            unless ( $errors{ $lines->[ $offsets->{'service_row'} ]->[$i] } ) {
                print STDERR "unknown service: " . $lines->[ $offsets->{'service_row'} ]->[$i] . "\n";
                $errors{ $lines->[ $offsets->{'service_row'} ]->[$i] } = 1;
            }
            $self->warning();
            next;
        }
    }

    my $linenum = 0;
    foreach my $line (@$lines) {
        $linenum++;
        next unless ( $linenum > $offsets->{'service_row'} + 1 );

        my $ptype     = RPS::File::Sale::TYPE_TRACK;
        my $artist    = $line->[ $offsets->{'artist'} ];
        my $album     = $line->[ $offsets->{'album'} ];
        my $track     = $line->[ $offsets->{'track'} ];
        my $vendor_id = $line->[ $offsets->{'vendor_id'} ];
        my $upc       = Common::Util::normalize_upc( $line->[ $offsets->{'upc'} ] );
        my $isrc      = Common::Util::normalize_isrc( $line->[ $offsets->{'isrc'} ] );

        #for (my $col = $offsets->{'start_col'}; $lines->[$offsets->{'service_row'}]->[$col] ne ""; $col += 2) {
        for ( my $col = $start_col ; $lines->[ $offsets->{'service_row'} ]->[$col] ne "" ; $col += 2 ) {

            my $format  = $columns[$col]->{format};
            my $service = $columns[$col]->{service};
            my $country = $columns[$col]->{country};

            my $units = $line->[$col];
            my $price = $line->[ $col + 1 ];

            $price =~ s/^\$//g;

            $price = ( $units != 0 ) ? round( $price / $units, 8 ) : 0;

            if ( $units && $track && $artist && $album && $service && $country && $format ) {
                my $sale = RPS::Import::SaleRec->new();

                $sale->serviceID($service);
                $sale->productType($ptype);
                $sale->formatType($format);
                $sale->dateBegin($dateBegin);
                $sale->dateEnd($dateEnd);
                $sale->serviceProductID($vendor_id);
                $sale->upc($upc);
                $sale->isrc($isrc);
                $sale->artistName($artist);
                $sale->albumName($album);
                $sale->trackName($track);
                $sale->units($units);
                $sale->price($price);
                $sale->lineNum($linenum);
                $sale->countryCode($country);

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

#
# Private methods
#

sub _getDates {
    my $self = shift;
    my $date = shift;

    my ( $dateBegin, $dateEnd );

    if ( $date =~ m/^(\d{4})-(\d?\d)-(\d?\d) to (\d{4})-(\d?\d)-(\d?\d)$/ ) {
        my ( $dateBegin, $dateEnd ) = $self->SUPER::_getDates(
            date_begin => sprintf( "%04d-%02d-%02d", $1, $2, $3 ),
            date_end   => sprintf( "%04d-%02d-%02d", $4, $5, $6 ),
            type       => "iso"
        );

        return ( $dateBegin, $dateEnd );
    }

    return undef;
}

sub _parseService {
    my $self        = shift;
    my $serviceCell = lc shift;

    my $country;
    foreach my $cc ( keys %COUNTRY_CODE ) {
        if ( $serviceCell =~ s/\s+\(?$cc\)?$// ) {
            $country = $COUNTRY_CODE{$cc};
            last;
        }
    }

    if ( $serviceCell =~ s/\s+s\.a\.r\.l\.$// ) {
        $country = 'EU';
    } else {
        $country ||= 'US';
    }

    # if country _is_ present and doesn't match anything in %COUNTRY_CODE then it'll remain part of the
    # service name and won't be identified in the following statement - so it will still get caught
    return ( $self->getServiceID($serviceCell) || $service_map{$serviceCell}, $country, );
}

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