package RPS::Import::Echospin;

use strict;


use Date::Calc qw(Days_in_Month Add_Delta_Days Decode_Month);

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

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

# map version num to the field order
my %fieldMap =
(
	1 =>
	{
		'upc'       => 0,
		'artist'    => 1,
		'album'     => 2,
		'label'     => 3,
		'units'     => 7,
		'price'     => 10,
		'type'      => 11,
		'format'    => 12,
		'country'  	=> 14,
		'period'    => 15,
	},
    2 =>
    {
        'media'     => 0,
        'isrc'      => 1,
        'upc'       => 1,
        'artist'    => 3,
        'album'     => 5,
        'label'     => 4,
        'retail'    => 8,
        'units'     => 9,
        'price'     => 13,
        'type'      => 2,
        'format'    => 14,
        'country'   => 15,
    },
);

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

#public methods

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

	my $lines = $args{lines};
	my $fileObj = $args{file};
    my $fileName = $fileObj->OrigFileName;
	my $version = $fileObj->VersionNum;
    #my $fileName = $args{OrigFileName}; # for cmd-line testing
    #my $version = $args{version}; # for cmd-line testing

    return undef unless (defined $lines && defined $version);

	my $offsets = $fieldMap{$version};

    my $prev_format;

    shift @$lines; ## skip header
    my $linenum = 2;
    my ($upc,$dateBegin,$dateEnd);
    ($dateBegin, $dateEnd) = $self->_getDates($fileName) if ($version==2);
    foreach my $line (@$lines) {

        my ($upc,$isrc);
        my $artist  = $line->[$offsets->{artist}];
        $upc     = Common::Util::normalize_upc($line->[$offsets->{upc}]);
        $isrc   = $line->[$offsets->{isrc}] if exists $offsets->{isrc};
        my $label   = $line->[$offsets->{label}];
        my $country = $line->[$offsets->{country}];

        next if ($country =~ m/^$/);

        if ($country !~ m/^[A-Z][A-Z]$/) {
            $self->errstr("invalid country code: $country");
            return undef;
        }


        ($dateBegin, $dateEnd) = $self->_getDates($line->[$offsets->{period}]) if ($version==1);
        unless (defined $dateBegin && defined $dateEnd) {
            $self->errstr("couldn't get dates from ".$line->[$offsets->{period}]);
            return undef;
        }

        my $price_level = RPS::File::Sale::PLEVEL_FULL;
        my $channel     = RPS::File::Sale::CHANNEL_RETAIL;
        my ($format, $prodtype, $album, $track);

        if ($line->[$offsets->{format}] eq "Physical") {
            $prodtype = RPS::File::Sale::TYPE_CD;
            $album = $line->[$offsets->{album}];
            if (defined $prev_format && $prev_format ne "physical") {
                $self->errstr("mixed physical/digital file");
                return undef;
            }
            $prev_format = "physical";
        } elsif ($line->[$offsets->{format}] eq "Digital") {
            $format   = RPS::File::Sale::FORMAT_DOWNLOAD;
            if (defined $prev_format && $prev_format ne "digital") {
                $self->errstr("mixed physical/digital file");
                return undef;
            }
            if(($line->[$offsets->{media}] =~ /album/i && $version==2)||($version==1)) {
                $prodtype = RPS::File::Sale::TYPE_ALBUM;
                $album = $line->[$offsets->{album}];
            }
            else {
                $prodtype = RPS::File::Sale::TYPE_TRACK;
                $track = $line->[$offsets->{album}];
            }
            $prev_format = "digital";
        } else {
            $self->errstr("unknown format: ".$line->[$offsets->{format}]);
            return undef;
        }

        my ($units) = $line->[$offsets->{units}];
        my ($price) = $line->[$offsets->{price}];
        my ($retail_price) = $line->[$offsets->{retail}];
        if ($prev_format eq "digital" && $price<0) {
            $price *= -1;
            $price = ($units != 0)?($price / $units):0;
            $price *= -1 if($price>0);
            #$units *= -1 if($units>0);
        }
         elsif($prev_format eq "digital") {
            $price = ($units != 0)?($price / $units):0;
        }


        if (($line->[$offsets->{type}] ne "Sale")&&($line->[$offsets->{type}] ne "Return")) {
            $self->errstr("unknown transaction type: ".$line->[$offsets->{type}]);
            return undef;
        }

        if ($prodtype && $units && $price && ($album||$track) && $country)
        {
            my $sale = RPS::Import::SaleRec->new();

            $sale->productType($prodtype);
            $sale->dateBegin($dateBegin);
            $sale->dateEnd($dateEnd);
            $sale->upc($upc) if ($album ne "");
            $sale->isrc($isrc) if ($track ne "");
            $sale->artistName($artist);
            $sale->albumName($album) if ($album ne "");
            $sale->trackName($track) if ($track ne "");
            $sale->labelName($label);
            if ($prev_format eq 'digital') {
                $sale->formatType($format);
                $sale->units($units);
                $sale->price($price);
            } else {
                $sale->sales($units);
                $sale->salesRevenue($price);
                $sale->totalRevenue($price);
                $sale->priceLevel($price_level);
                $sale->channel($channel);
            }
			$sale->retailPrice($retail_price);
            $sale->countryCode($country);
            $sale->lineNum($linenum);

            #$args{dumper}($sale); ## for cmd-line testing
            $self->_insertSale(sale => $sale);
        }
        #else { print STDERR "skip l:".$linenum." p:".$prodtype." u:".$units." pr:".$price." a:".$album." t:".$track." c:".$country."\n"; }
        $linenum++;
    }

    if ($prev_format eq "physical") {
        $fileObj->Physical(1);
        $fileObj->Save();
    }
	return $linenum;
}

#
# Private methods
#


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

	my $beginDate;
	my $endDate;

    if ($date =~ m/^(\d+)\/(\d+)\/(\d{4}) *- *(\d+)\/(\d+)\/(\d{4})$/) {
        my $dateBegin = sprintf("%04d-%02d-%02d", $3, $1, $2);
        my $dateEnd   = sprintf("%04d-%02d-%02d", $6, $4, $5);
	    return ($dateBegin, $dateEnd);
    }
    elsif ($date =~ /Sales Report - Digital/) {
       $date =~ s/^.* - //g;
       $date =~ s/_.*$//;
       my ($month,$year,$monthName,$dateBegin,$dateEnd);
       if($date =~ /(\d+)-(\d{4})/) {
            ($month,$year) = split("-",$date);
            $dateBegin = sprintf("%04d-%02d-%02d", $year,$month,1);
            $dateEnd = sprintf("%04d-%02d-%02d", $year,$month,Days_in_Month($year, $month));
       }
       else {
            ($monthName,$year) = split(" ",$date);
            $dateBegin = sprintf("%04d-%02d-%02d", $year,Decode_Month($monthName),1);
            $dateEnd = sprintf("%04d-%02d-%02d", $year,Decode_Month($monthName),Days_in_Month($year, Decode_Month($monthName)));
       }
       return ($dateBegin, $dateEnd);
    }
    elsif ($date =~ /Sales Report - Physical/) {
        $date =~ s/^.* - //g;
        $date =~ s/\s.*$//;
        my ($month,$year) = split("-",$date);
        my $dateBegin = sprintf("%04d-%02d-%02d", $year,$month,1);
        my $dateEnd = sprintf("%04d-%02d-%02d", $year,$month,Days_in_Month($year, $month));
        return ($dateBegin, $dateEnd);
    }
    return undef;
}

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