package RPS::Import::Puretracks::v1;

use strict;

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

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

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

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

my %field_map = (
    1 => {
        date_row        => 0,
        date_col        => 0,
        units           => 0,
        code            => 1,
        artist          => 2,
        title           => 3,
        price           => 2,
        deduct          => 2,
        deduct_alt      => 1,
        summary_product => 0,
    },
    2 => {
        date_row        => 0,
        date_col        => 0,
        units           => 1,
        code            => 2,
        artist          => 3,
        title           => 4,
        price           => 3,
        deduct          => 3,
        summary_product => 1,
    },
    3 => {
        date_col        => 1,
        date_start_row  => 8,
        date_end_row    => 9,
        units           => 0,
        code            => 1,
        artist          => 2,
        artist_track    => 3,
        title           => 3,
        title_track     => 4,
        price           => 2,
        deduct          => 2,
        summary_product => 0,
    },
    4 => {
        date_col        => 1,
        date_start_row  => 8,
        date_end_row    => 9,
        units           => 0,
        code            => 1,
        artist          => 2,
        artist_track    => 3,
        title           => 3,
        title_track     => 4,
        price           => 2,
        deduct          => 2,
        summary_product => 0,
    },
    5 => {
        date_col        => 0,
        units           => 1,
        code_track      => 2,
        artist          => 3,
        title           => 2,
        title_track     => 4,
        price           => 3,
        deduct          => 2,
        summary_product => 1,
    },
    6 => {
        date_col        => 0,
        units           => 1,
        code            => 2,
        code_track      => 2,
        artist          => 3,
        title           => 4,
        price           => 3,
        deduct          => 0, # no-deductions??
        summary_product => 1,
    },
    7 => {
        date_col        => 1,
        date_start_row  => 8,
        date_end_row    => 9,
        units           => 9,
        code            => 4,
        artist          => 7,
        artist_track    => 7,
        title           => 8,
        title_track     => 8,
        price           => 3,
        detail_price    => 11,
        deduct          => 5,
        upc             => 2,
        isrc            => 3,
        spid            => 4,
        label           => 5,
        summary_product => 0,
    },
    8 => {
        date_col        => 0,
        units           => 1,
        code            => 2,
        code_track      => 2,
        artist          => 3,
        title           => 4,
        price           => 2,
        deduct          => 4, # no-deductions??
        summary_product => 0,
    },
    10 => {
        date_col        => 1,
        date_start_row  => 9,
        date_end_row    => 10,
        units           => 0,
        code            => 1,
        artist          => 2,
        artist_track    => 3,
        title           => 3,
        title_track     => 4,
        price           => 2,
        deduct          => 4,
        summary_product => 0,
    },
    9 => {
        date_col        => 1,
        date_start_row  => 8,
        date_end_row    => 9,
        units           => 0,
        code            => 1,
        artist          => 2,
        artist_track    => 3,
        title           => 3,
        title_track     => 4,
        price           => 3,
        deduct          => 5,
        summary_product => 0,
        upc             => 1,
        isrc            => 1,
        #spid            => 4,
        #label           => 5,
    },
    11 => {
        date_col        => 1,
        date_start_row  => 9,
        date_end_row    => 10,
        units           => 1,
        code            => 2,
        artist          => 4,
        title           => 5,
        price           => 3,
        deduct          => 5,
        summary_product => 0,
    },
);

#public methods

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

	my $sheets = $args{sheets};
    my $version = $self->_version();
    my $fileName = $args{file}->OrigFileName;
    #my $fileName = $args{OrigFileName}; ## for cmd-line testing

    my $offsets = $field_map{$version};

	my $summary = $sheets->[0];
	my $albums  = $sheets->[1];
	my $tracks  = $sheets->[2];

    my ($country, $currency);
    if ($fileName =~ m/ US / || $fileName =~ /_US_/ || $fileName =~ /^US_/ ) {
        $country  = 'US';
        $currency = 'USD';
    } else {
        $country  = 'CA';
        $currency = 'CAD';
    }

    my ($album_price, $track_price, $month);
    my ($albumDeduct, $trackDeduct);
    my $in_pub_deduct = 0;
    my ($priceColumn,$deductionColumn);
    foreach my $line (@$summary)
    {
        if($version == 11) {
            if($line->[0] eq "Type") {
                my @columns = @$line;
                for(my $x=0;$x<@columns;$x++) {
                    $priceColumn = $x if($line->[$x] =~ /net payment/i);
                    $deductionColumn = $x if($line->[$x] =~ /deduction/i);
                }
            }
            elsif($line->[$offsets->{summary_product}] eq "Product" && $album_price eq "") {
                $album_price = $line->[$priceColumn];
                $album_price /= $line->[1] if($line->[1]!=0);
                $albumDeduct = 0;
            }
            elsif($line->[$offsets->{summary_product}] eq "Track" && $track_price eq "") {
                $track_price = $line->[$priceColumn];
                $track_price /= $line->[1] if($line->[1] != 0);
                $trackDeduct = 0;
            }
        }
        elsif(($line->[$offsets->{summary_product}] eq "Product"||$line->[$offsets->{summary_product}] eq "Albums"||$line->[$offsets->{summary_product}] eq "Album") && ($version>6)) {
            $album_price = $line->[$offsets->{price}];
            $albumDeduct = $line->[$offsets->{deduct}]/$line->[1] if($line->[1]>0);

        }
        elsif(($line->[$offsets->{summary_product}] eq "Track" && $version>6)||($line->[$offsets->{summary_product}] eq "Tracks" && $version>6)) {
            $track_price = $line->[$offsets->{price}];
            $trackDeduct = $line->[$offsets->{deduct}]/$line->[1] if($line->[1]>0);

        }
        elsif ($line->[$offsets->{summary_product}] =~ /^(Albums|Product)$/)
        {
            if ($version =~ /^(5|6)$/)
            {
                $month = Decode_Month($line->[$offsets->{month}]);
                $album_price->{$month} = $line->[$offsets->{price}];
            }
            else
            {
                $album_price = $line->[$offsets->{price}];
            }
        }
        elsif ($line->[$offsets->{summary_product}] =~ /^Track/)
        {
            if ($version =~ /^(5|6)$/)
            {
                $track_price->{$month} = $line->[$offsets->{price}];
            }
            else
            {
                $track_price = $line->[$offsets->{price}];
            }
        }
        elsif ($line->[0] =~ /Publishing Deduction?/ || $line->[1] =~ /Publishing Deduction/i || ($in_pub_deduct && $version !~ /^(3|4)$/))
        {
            $in_pub_deduct = 1;

            $albumDeduct ||=
                $line->[$offsets->{deduct}] =~ m/^\$(\d+\.\d\d)\/per Albums?$/ ? $1 :
                $line->[$offsets->{deduct_alt}] =~ m/^\$(\d+\.\d\d)\/per Albums?$/ ? $1 :
                ($line->[$offsets->{summary_product}] =~ m/album/i &&
                    $line->[$offsets->{deduct}] =~ m/^(\d+(\.\d+)?)$/) ? $1 : 0;

            $trackDeduct ||=
                $line->[$offsets->{deduct}] =~ m/^\$(\d+\.\d\d)\/per Tracks?$/ ? $1 :
                $line->[$offsets->{deduct_alt}] =~ m/^\$(\d+\.\d\d)\/per Tracks?$/ ? $1 :
                ($line->[$offsets->{summary_product}] =~ m/track/i &&
                     $line->[$offsets->{deduct}] =~ m/^(\d+(\.\d+)?)$/) ? $1 : 0;
        }
    }

    if ($album_price eq "" && $track_price eq "") {
        $self->errstr("couldn't get prices");
        return undef;
    }

    if ($version =~ /^(5|6)$/)
    {
        map { $album_price->{$_} -= $albumDeduct } keys %$album_price;
        map { $track_price->{$_} -= $trackDeduct } keys %$track_price;
    }
    else
    {
        $album_price -= $albumDeduct;

        $track_price -= $trackDeduct;

    }

	my ($dateBegin, $dateEnd);
    if ($version == 8) {
        my $adjusted_filename = $fileName;
        $adjusted_filename =~ s/^.*US /Summary / if ($fileName =~ /US/);
        $adjusted_filename =~ s/^.*CA /Summary / if ($fileName =~ /CA/);
        $adjusted_filename =~ s/\.xls//;
        ($dateBegin,$dateEnd) = $self->_getDates($adjusted_filename);
    }
    elsif ($version == 1 || $version == 2) {
	    ($dateBegin, $dateEnd) = $self->_getDates($summary->[$offsets->{date_row}]->[$offsets->{date_col}]);
	    unless ($dateBegin && $dateEnd) {
            $self->errstr("couldn't get dates");
            print STDERR 'dates: '. $summary->[$offsets->{date_row}]->[$offsets->{date_col}] ."\n";
            return undef;
        }
    }
    elsif($version>7) {
        my @name_parts;
        $fileName =~ m/(\d{8})\-(\d{8})/;
        if($fileName =~ m/(\d{8})\-(\d{8})/) {
            $name_parts[0] = $1;
            $name_parts[1] = $2;
        }
        elsif($fileName =~ m/(\d{8}) \- (\d{8})/) {
            $name_parts[0] = $1;
            $name_parts[1] = $2;
        }
        elsif($fileName =~ m/(\d{8})\_\-\_(\d{8})/) {
            $name_parts[0] = $1;
            $name_parts[1] = $2;
        }
        ($dateBegin, $dateEnd) = $self->_getDates_alt($name_parts[0], $name_parts[1]);
        unless ($dateBegin && $dateEnd) {
            $self->errstr("couldn't get dates");
            print STDERR 'dates: '. $name_parts[0] . ", " .$name_parts[1] ."\n";
            return undef;
        }
    }
    elsif ($version !~ /(5|6)/)
    {
	    ($dateBegin, $dateEnd) = $self->_getDates_alt($summary->[$offsets->{date_start_row}]->[$offsets->{date_col}], $summary->[$offsets->{date_end_row}]->[$offsets->{date_col}]);
	    unless ($dateBegin && $dateEnd) {
            $self->errstr("couldn't get dates");
            print STDERR 'dates: '. $summary->[$offsets->{date_start_row}]->[$offsets->{date_col}] ."\n";
            return undef;
        }
    }
    my $linenum = $self->_processLines($albums, RPS::File::Sale::TYPE_ALBUM, $dateBegin, $dateEnd, $album_price, $country, $currency, $offsets,$version,$fileName);

    # on the track tab some of the columns shift (for some versions)
    foreach my $k(qw(artist title code))
    {
        my $trackKey = $k . '_track';
        $offsets->{$k} = $offsets->{$trackKey} if (exists $offsets->{$trackKey});
    }

    $linenum   += $self->_processLines($tracks, RPS::File::Sale::TYPE_TRACK, $dateBegin, $dateEnd, $track_price, $country, $currency, $offsets,$version,$fileName);

	return $linenum;
}

#
# Private methods
#


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

    my ($dateBegin, $dateEnd);
    if($date =~ m/Q(\d) (\d{4})/) {
        my $year = $2;
        my $qtr = $1;
        if ($qtr == 1) {
            $dateBegin = $year."-01-01";
            $dateEnd   = $year."-03-".Days_in_Month($year, 3);
        } elsif ($qtr == 2) {
            $dateBegin = $year."-04-01";
            $dateEnd   = $year."-06-".Days_in_Month($year, 6);
        } elsif ($qtr == 3) {
            $dateBegin = $year."-07-01";
            $dateEnd   = $year."-09-".Days_in_Month($year, 9);
        } elsif ($qtr == 4) {
            $dateBegin = $year."-10-01";
            $dateEnd   = $year."-12-".Days_in_Month($year, 12);
        }
    }
    elsif($date =~ m/Summary\s*(\w+)\s+(\d{4})$/) {
        my $month = Decode_Month($1);
        my $year  = $2;
        $dateBegin = sprintf("%04d-%02d-%02d", $year, $month, 1);
        $dateEnd   = sprintf("%04d-%02d-%02d", $year, $month, Days_in_Month($year, $month));
    }

	return ($dateBegin, $dateEnd);
}

sub _getDates_alt
{
	my $self = shift;
	my $date1 = shift;
	my $date2 = shift;
    my ($dateBegin, $dateEnd);

    if($date1 =~ m/(\d{4})(\d\d)(\d\d)/) {
        $dateBegin = sprintf("%04d-%02d-%02d",$1,$2,$3);
    }
    elsif ($date1 =~ m/^(\d+)$/) {
        my ($year, $month, $day) = Add_Delta_Days(1900,1,1, $1 - 2);
        $dateBegin = sprintf("%04d-%02d-%02d", $year, $month, 1);
    }
    if($date2 =~ m/(\d{4})(\d\d)(\d\d)/) {
        $dateEnd = sprintf("%04d-%02d-%02d",$1,$2,$3);
    }
    elsif ($date2 =~ m/^(\d+)$/) {
        my ($year, $month, $day) = Add_Delta_Days(1900,1,1, $1 - 2);
        $dateEnd   = sprintf("%04d-%02d-%02d", $year, $month, Days_in_Month($year, $month));
    }

	return ($dateBegin, $dateEnd);
}

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

    return undef unless ($date =~ m/^(\w+)\D+\d+\D+(\d\d\d\d)$/);
    my $year = $2;
    my $month = Decode_Month($1);

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

sub _processLines
{
    my $self        = shift;
    my $lines       = shift;
    my $prodtype    = shift;
    my $dateBegin   = shift;
    my $dateEnd     = shift;
    my $price       = shift;
    my $country     = shift;
    my $currency    = shift;
    my $offsets     = shift;
    my $version     = shift;
    my $fileName    = shift;
    my $dates = $dateBegin ? 1 : 0;
    my $month = 0;
	my $format = RPS::File::Sale::FORMAT_DOWNLOAD;

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

    if($version==8 && $fileName =~ /US/ && $prodtype eq "A") {
        $offsets->{artist} -= 1;
        $offsets->{units} -= 1;
        $offsets->{title} -= 1;
    }
    if($version==8 && $fileName =~ /US/ && $prodtype eq "T") {
        $offsets->{artist} += 1;
        $offsets->{units} += 1;
        $offsets->{title} += 1;
    }

	foreach my $line (@$lines)
    {
		my $artist	= $line->[$offsets->{artist}];
		my ($units)	= $line->[$offsets->{units}] =~ m/^(\d+)$/;
        my $title = $line->[$offsets->{title}];
        my $test_title = $title =~ s/(\d)|\.//g;

        my $code = exists $offsets->{code} ? $line->[$offsets->{code}] : '';
        $code =~ s/^indy_//;
        $code =~ s/_mp3$//;

		unless ($units && defined $price && ($code || $artist || $title)) {
            $linenum++;
            next;
        }
        my ($label,$upc,$isrc,$spid);
        $label      = $line->[$offsets->{label}] if(defined $offsets->{label});
        $upc        = $line->[$offsets->{upc}] if(defined $offsets->{upc});
        $upc        =~ s/^indy_//;
        $upc        =~ s/_mp3$//;
        $isrc       = $line->[$offsets->{isrc}] if(defined $offsets->{isrc});
        $spid       = $line->[$offsets->{spid}] if(defined $offsets->{spid});
        $isrc       =~ s/\-//g;

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

        # if the date range wasn't passed, it will be grabbed from each data row
        # the month will be used to index the price array
        unless ($dates)
        {
            ($dateBegin, $dateEnd, $month) = $self->_getDataRowDate($line->[$offsets->{date_col}]);
            unless ($dateBegin && $month)
            {
                $self->errstr("couldn't get dates");
                print STDERR 'date: '. $line->[$offsets->{date_col}] ."\n";
                return undef;
            }
            $sale->price($price->{$month});
        }
        else
        {
                    if($version == 7)
                    {
                        my $price = $line->[$offsets->{detail_price}];
                        my $deduction = $line->[$offsets->{detail_price} + 1];
                        $price -= $deduction;
                        $price /= $units;
                        $sale->price($price);
                    }
                    else{
                        $sale->price($price);
                    }
        }
        if($test_title eq "" && $version==11 && $line->[$offsets->{title}+1] ne "") {
            my $new_test_title = $line->[$offsets->{title}+1];
            $new_test_title =~ s/(\d)|\.//g;
            if($new_test_title ne "") {
                $title = $line->[$offsets->{title}+1];
            }
        }
		$sale->productType($prodtype);
		$sale->formatType($format);
		$sale->dateBegin($dateBegin);
		$sale->dateEnd($dateEnd);
		$sale->artistName($artist);

    if ($prodtype eq RPS::File::Sale::TYPE_ALBUM)
    {
		    $sale->upc($code);
        $sale->upc($upc) if(defined $offsets->{upc} && $upc ne "");
		    $sale->albumName($title);
    }
    elsif ($prodtype eq RPS::File::Sale::TYPE_TRACK)
    {
    		if ($version != 9)
    		{
            $sale->upc($upc) if(defined $offsets->{upc} && $upc ne "");
      	}
		    $sale->isrc($code);
        $sale->isrc($isrc) if(defined $offsets->{isrc} && $isrc ne "");
		    $sale->trackName($title);
    }

    $sale->labelName($label) if(defined $offsets->{label} && $label ne "");
    $sale->serviceProductID($spid) if(defined $offsets->{spid} && $spid ne "");
		$sale->units($units);
		$sale->countryCode($country);
		$sale->currencyCode($currency);
		$sale->lineNum($linenum);

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

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