package RPS::Import::ECast;

use strict;

use Date::Calc qw(Add_Delta_Days Decode_Month);

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

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';

#private constants
use constant FIELD_PRODUCTID   => 0;
use constant FIELD_TRACK       => 1;
use constant FIELD_SELECTIONID => 2;
use constant FIELD_ALBUM       => 3;
use constant FIELD_ARTIST      => 4;
use constant FIELD_UPC         => 5;
use constant FIELD_ISRC        => 6;
use constant FIELD_PRICE       => 7;
use constant FIELD_UNITS       => 8;
use constant FIELD_PAYMENT     => 9;
use constant FIELD_INCOMETYPE  => 10;
use constant FIELD_LABEL       => 11;
use constant FIELD_MINUTES     => 12;
use constant FIELD_SECONDS     => 13;
use constant FIELD_INCOMESRC   => 14;

#public methods

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

    my $sheets  = $args{sheets};
    my $fileObj = $args{file};

    my $paid_lines = $sheets->[0];
    my $free_lines = $sheets->[1];

    unless ($paid_lines) {
        $self->errstr("missing paid lines");
        print STDERR "missing sheet 0\n";
        return undef;
    }

    my ( $dateBegin, $dateEnd );
    if ( $self->{fileServiceID} == Client::Service::DSP_AOL and $fileObj->VersionNum() == 4 ) {

        # version 4 from AOL is in ECast format but missing the first 4 lines where
        # the date was specified so gotta get it from the filename
        ( $dateBegin, $dateEnd ) = $self->_getDatesFromFile( $fileObj->OrigFileName );
    } else {
        ( $dateBegin, $dateEnd ) = $self->_getDates($paid_lines);
    }

    unless ( $dateBegin && $dateEnd ) {
        $self->errstr("couldn't get dates");
        return undef;
    }

    my $linenum = $self->_processLines( $paid_lines, 0, $dateBegin, $dateEnd );
    ##my $linenum = $self->_processLines($paid_lines, 0, $dateBegin, $dateEnd, \%args);

    return $linenum unless ($free_lines);

    $linenum += $self->_processLines( $free_lines, 1, $dateBegin, $dateEnd );
    ##$linenum = $self->_processLines($free_lines, 1, $dateBegin, $dateEnd, \%args);

    return $linenum;
}

#
# Private methods
#

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

    ## Excel date is (supposedly) days since 01 Jan 1900, but have to subtract 2
    ## from that number because (1) 0/1 index issue, and (2) MS wants to pretend
    ## that 1900 was a leap year.

    my ( $dateBegin, $dateEnd );
    if ( $lines->[1]->[1] =~ m/^\d{4}\-\d{2}-\d{2}$/ ) {
        $dateBegin = $lines->[1]->[1];
    } elsif ( $lines->[1]->[1] =~ m/^(\d+)\D(\d+)\D(\d{4})$/ ) {
        $dateBegin = sprintf( "%d-%02d-%02d", $3, $1, $2 );
    } else {
        my ( $year, $month, $day ) = Add_Delta_Days( 1900, 1, 1, $lines->[1]->[1] - 2 );
        return undef unless ( $year > 1995 );
        $dateBegin = sprintf( "%d-%02d-%02d", $year, $month, $day );
    }

    my ( $year, $month, $day );

    if ( $lines->[2]->[1] =~ m/^(\d{4})\-(\d{2})-(\d{2})$/ ) {
        ( $year, $month, $day ) = ( $1, $2, $3 );
    } elsif ( $lines->[2]->[1] =~ m/^(\d+)\D(\d+)\D(\d{4})$/ ) {
        ( $year, $month, $day ) = ( $3, $1, $2 );
    } else {
        ( $year, $month, $day ) = Add_Delta_Days( 1900, 1, 1, $lines->[2]->[1] - 2 );
    }

    # We want to allow a 1 day padding into the next period.  See case #11912
    ( $year, $month, $day ) = Add_Delta_Days( $year, $month, $day, -1 )
      if ( $day == 1 );

    $dateEnd = sprintf( "%d-%02d-%02d", $year, $month, $day );

    return ( $dateBegin, $dateEnd );
}

sub _getDatesFromFile {
    my $self  = shift;
    my $fName = lc $_[0];

    my ( $month, $year );
    if ( $fName =~ m/\D(\d{4})[\s\d]*([a-z]{3})/ ) {
        ( $year, $month ) = ( $1, Date::Calc::Decode_Month($2) );
    } elsif ( $fName =~ m/_(\d\d)\d\d(\d{4})_\d{8}/ ) {
        ( $month, $year ) = ( $1, $2 );
    }

    return unless ( $year && $month );
    return (
        Common::Util::normalize_date( join( '-', $year, $month, 1 ) ),
        Common::Util::normalize_date( join( '-', $year, $month, Date::Calc::Days_in_Month( $year, $month ) ) ),
    );
}

sub _processLines {
    my $self      = shift;
    my $lines     = shift;
    my $free      = shift;
    my $dateBegin = shift;
    my $dateEnd   = shift;
    ##my $args        = shift;  ## for cmd line testing

    my $prodtype = RPS::File::Sale::TYPE_TRACK;

    my $format;
    my $mediaType;

    if ( $self->is_wmg ) {
        $format    = RPS::File::Sale::FORMAT_STREAM;              # was FORMAT_VIDEOSTREAM (FB1324)
        $mediaType = RPS::DB::Item::MediaType::kMediaTypeVideo;
    } else {
        $format    = RPS::File::Sale::FORMAT_STREAM;
        $mediaType = RPS::DB::Item::MediaType::kMediaTypeAudio;
    }

    my $linenum = 1;                                              ## starting off after header

    foreach my $line (@$lines) {
        my $prodID  = $line->[FIELD_PRODUCTID];
        my $upc     = Common::Util::normalize_upc( $line->[FIELD_UPC] );
        my $isrc    = Common::Util::normalize_isrc( $line->[FIELD_ISRC] );
        my $artist  = $line->[FIELD_ARTIST];
        my $album   = $line->[FIELD_ALBUM];
        my $track   = $line->[FIELD_TRACK];
        my $label   = $line->[FIELD_LABEL];
        my ($units) = $line->[FIELD_UNITS] =~ m/^(\d+)$/;
        my $price   = $line->[FIELD_PRICE];

        unless ( $units && defined $price && $artist && $track ) {

            #print STDERR "skip $linenum\n";
            $linenum++;
            next;
        }

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

        $sale->productType($prodtype);
        $sale->formatType($format);
        $sale->mediaType($mediaType);
        $sale->dateBegin($dateBegin);
        $sale->dateEnd($dateEnd);
        $sale->serviceProductID($prodID);
        $sale->upc($upc);
        $sale->isrc($isrc);
        $sale->artistName($artist);
        $sale->albumName($album);
        $sale->trackName($track);
        $sale->labelName($label);
        $sale->units($units);
        $sale->price($price);
        $sale->free($free);
        $sale->lineNum($linenum);
        $sale->countryCode('US');

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

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