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.
###
