package RPS::Import::NugsRevised;

#Created from specs in Fog Bugz Case 9654
# !!! JPK- What?  That case is all about the RSFormat importer...

use strict;

use Date::Calc qw(Days_in_Month Decode_Month);

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

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 %field_map = (
#    1 =>
#    {
#        label              => 0,
#        service_id         => 1,
#        country            => 3,
#        date_begin         => 4,
#        date_end           => 5,
#        product_type       => 6,
#        format             => 7,
#        service_product_id => 9,
#        client_product_id  => 10,
#        artist             => 11,
#        upc                => 13,
#        album              => 14,
#        isrc               => 15,
#        track_number       => 16,
#        track              => 17,
#        units              => 18,
#        currency_code      => 19,
#        free               => 22,
#        price              => 24,
#        media_type         => 25,

#    },
#);
my %fieldMap = (
digital => {
            single => {
                date_row               => 5,
                date_col               => 0,
                service_product_id     => 0,
                title                  => 1,
                units                  => 3,
                returns                => 7,
                price                  => 11,
            },
            multiple => {
                date_row               => 5,
                date_col               => 0,
                service_product_id     => 1,
                title                  => 2,
                units                  => 4,
                returns                => 8,
                price                  => 11,
            },
        },
physical => {
            single => {
                date_row           => 5,
                date_col           => 0,
                service_product_id => 0,
                title              => 1,
                retail_price       => 2,
                sales              => 3,
                sales_revenue      => 4,
                returns            => 7,
                returns_revenue    => 8,
                shipping_fee       => 9,
                service_fee        => 10,
                total_revenue      => 11,
            },
             multiple => {
                date_row           => 5,
                date_col           => 0,
                service_product_id => 1,
                title              => 2,
                sales              => 4,
                sales_revenue      => 5,
                returns            => 8,
                returns_revenue    => 9,
                shipping_fee       => 10,
                service_fee        => 11,
                total_revenue      => 12,
            },
         },
);

#public methods

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

    my $fileName = $args{file}->OrigFileName();

    if($fileName =~ /digital/i ){
        return _importDigital($self, @_);
    }
    elsif($fileName =~ /physical/i ){
        return _importPhysical($self, @_);
    }
    else{
        $self->errstr("Could not determine product type from filename: $fileName");
        print STDERR "Could not determine product type from filename: $fileName\n";
        return undef;
    }

    #my %args = @_;

    #return undef unless ($lines);

    #my $lines = $args{lines};
    #my $version = $args{file}->VersionNum();
    #my $fileName = $args{file}->OrigFileName();
    #my @sheets = @{ $args{sheets} };

    #my $linenum = 1;

    #my $offsets = $field_map{$version};
    #my %errors = ();

}

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

    my $lines = $args{lines};
    my $version = $args{file}->VersionNum();
    my $fileName = $args{file}->OrigFileName();
    my @sheets = @{ $args{sheets} };
    my $sheet_names = $args{sheet_names};
    my $sheet_count = 0;

    return undef unless ($lines);

    my $linenum = 1;

    #my $offsets = $field_map{$version};
    my %errors = ();

    my $currencyCode = "USD";
    my $countryCode  = "US";
    my $format       = RPS::File::Sale::FORMAT_DOWNLOAD;
    my $mediaType    = RPS::DB::Item::MediaType::kMediaTypeAudio;

    foreach my $sheet(@{ $args{sheets} }) {
        $linenum = 1;
        my $sheet_name = $sheet_names->[$sheet_count];
        my $offsets;


        #print STDERR "Processing sheet: $sheet_name\n";

        if($sheet_name !~ /total/i) {
            if($sheet_name =~ /single/i){

                $offsets = $fieldMap{"digital"}{"single"};

            }
            elsif($sheet_name =~ /package/i){

                $offsets = $fieldMap{"digital"}{"multiple"};

                my $price_col = _getPriceCol($sheet);

                if($price_col){
                    $offsets->{price} = _getPriceCol($sheet);
                    #print STDERR "Got price column: $price_col\n";
                }
                else{
                    $self->errstr("Could not get 'NET REVENUE' column for package tab");

                    print STDERR "Could not get 'NET REVENUE' column for package tab\n";

                    return undef;

                }

            }
            else{

                $self->errstr("Could not determine tab type(single or multiple): ".
                $sheet_names->[$sheet_count]);

                print STDERR "Could not determine tab type(single or multiple): ".
                $sheet_names->[$sheet_count]."\n";

                return undef;
            }

            my ($dateBegin, $dateEnd);
            my $f_date = $sheet->[$offsets->{date_row}]->[$offsets->{date_col}];

            if($f_date =~ /^report period:\D*(\d{1,2})\D(\d{4})$/i){
                my $month = sprintf("%02d",$1);
                my $year = $2;

                ($dateBegin, $dateEnd) =
                $self->_getDates(date_begin=>"$year-$month-01", type=>"iso");
            }

            unless($dateBegin && $dateEnd){
                if ($fileName =~ /(\d)Q(\d{4})/) {
                    my $quarter = "q" . $1 . " " . $2;
                    ($dateBegin, $dateEnd) =
                    $self->_getDates(date_begin=>$quarter, type=>"quarter");                                
                } else {               
                    ($dateBegin, $dateEnd) =
                    $self->_getDates(date_begin=>$fileName, type=>"text");
                }
            }

            unless($dateBegin && $dateEnd){
                $self->errstr("Could not get dates from: $f_date");

                print STDERR "Could not get dates from: $f_date\n";

                return undef;
            }

            foreach my $line (@$sheet) {
                my $serviceProductID = $line->[$offsets->{service_product_id}];
                my $title = $line->[$offsets->{title}];
                my $units = $line->[$offsets->{units}];
                my $returns = $line->[$offsets->{returns}];
                my $price = $line->[$offsets->{price}];

                my $productType;
                #$product    = RPS::File::Sale::TYPE_ALBUM if($price > .99 && $sales_type eq "digital");
                $title =~ /^([A-Za-z]+).*/;
                my $shortCode = $1;

                if($shortCode && ($shortCode eq lc $shortCode)){
                    #print STDERR "Found short code album: $shortCode line num: $linenum\n";
                    $productType = RPS::File::Sale::TYPE_TRACK;
                }
                elsif($shortCode && ($shortCode eq uc $shortCode)){
                    #print STDERR "Found short code track: $shortCode line num: $linenum\n";
                    $productType = RPS::File::Sale::TYPE_ALBUM;
                }

                if($serviceProductID && $title &&
                $units =~ /\d+/ && $price =~ /\d+/ && $title !~ /total/i){

                    unless($productType){
                        $self->errstr("Could not process short code from: ".
                        "$title at line number: $linenum");

                        print STDERR "Could not process short code from: ".
                        "$title at line number: $linenum\n";

                        return undef;
                    }

                    my $sale = RPS::Import::SaleRec->new();
                    $sale->serviceProductID($serviceProductID);
                    $sale->albumName($title) if($productType eq RPS::File::Sale::TYPE_ALBUM);
                    $sale->trackName($title) if($productType eq RPS::File::Sale::TYPE_TRACK);

                    $sale->dateBegin($dateBegin);
                    $sale->dateEnd($dateEnd);
                    $sale->countryCode($countryCode);
                    $sale->currencyCode($currencyCode);
                    $sale->productType($productType);
                    $sale->formatType($format);
                    $sale->mediaType($mediaType);
                    $sale->lineNum($linenum);

                    if(($units == 0) && ($price != 0)){

                        if($price < 0){
                            $sale->units(-1);
                            $sale->price(abs $price);
                            $self->_insertSale(sale => $sale);

                            $sale->units(1);
                            $sale->price(0);
                            $self->_insertSale(sale => $sale);
                        }
                        elsif($price > 0){
                            $sale->units(1);
                            $sale->price($price);
                            $self->_insertSale(sale => $sale);

                            $sale->units(-1);
                            $sale->price(0);
                            $self->_insertSale(sale => $sale);
                        }
                    }
                    else{

                        if(($units > 0) && ($price > 0)){
                            $price /= $units;
                        }
                        elsif(($units > 0) && ($price < 0)){
                            $price = (abs $price)/$units;
                            $units *= -1;
                        }
                        elsif(($units < 0) && ($price > 0)){
                            $price = $price / (abs $units);
                        }
                        elsif(($units < 0) && ($price < 0)){
                            $price = (abs $price) / (abs $units);
                        }

                        $sale->units($units);
                        $sale->free(1) if($price == 0);
                        $sale->price($price) if($price != 0);
                         #$args{dumper}($sale);  ## for cmd-line testing
                        $self->_insertSale(sale => $sale);
                    }
                }

                $linenum++;
            }


        }
        $sheet_count++;
    }

    return $linenum;
}

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

    my $lines = $args{lines};
    my $version = $args{file}->VersionNum();
    my $fileName = $args{file}->OrigFileName();
    my $fileObj = $args{file};
    my @sheets = @{ $args{sheets} };
    my $sheet_names = $args{sheet_names};
    my $sheet_count = 0;

    return undef unless ($lines);

    my $linenum = 1;

    #my $offsets = $field_map{$version};
    my %errors = ();

    my $currencyCode = "USD";
    my $countryCode  = "US";
    my $productType = RPS::File::Sale::TYPE_CD;
    my $mediaType   = RPS::DB::Item::MediaType::kMediaTypeAudio;
    my $channel     = RPS::File::Sale::CHANNEL_MAILORDER;
    my $priceLevel  = RPS::File::Sale::PLEVEL_FULL;

    foreach my $sheet(@{ $args{sheets} }) {
        $linenum = 1;
        my $sheet_name = $sheet_names->[$sheet_count];
        my $offsets;

        #print STDERR "Processing sheet: $sheet_name\n";

        if($sheet_name !~ /total/i) {
            if($sheet_name =~ /single/i){

                $offsets = $fieldMap{"physical"}{"single"};

            }
            elsif($sheet_name =~ /cd sales/i){
                $offsets = $fieldMap{"physical"}{"single"};
            }
            elsif($sheet_name =~ /package/i){

                $offsets = $fieldMap{"physical"}{"multiple"};

                my $price_col = _getPriceCol($sheet);

                if($price_col){
                    $offsets->{price} = _getPriceCol($sheet);
                    #print STDERR "Got price column: $price_col\n";
                }
                else{
                    $self->errstr("Could not get 'NET REVENUE' column for package tab");

                    print STDERR "Could not get 'NET REVENUE' column for package tab\n";

                    return undef;

                }

            }
            else{

                $self->errstr("Could not determine tab type(single or multiple): ".
                $sheet_names->[$sheet_count]);

                print STDERR "Could not determine tab type(single or multiple): ".
                $sheet_names->[$sheet_count]."\n";

                return undef;
            }

            my ($dateBegin, $dateEnd);
            my $f_date = $sheet->[$offsets->{date_row}]->[$offsets->{date_col}];

            if($f_date =~ /^report period:\D*(\d{1,2})\D(\d{4})$/i){
                my $month = sprintf("%02d",$1);
                my $year = $2;

                ($dateBegin, $dateEnd) =
                $self->_getDates(date_begin=>"$year-$month-01", type=>"iso");
            }

            unless($dateBegin && $dateEnd){
                if ($fileName =~ /(\d)Q(\d{4})/) {
                    my $quarter = "q" . $1 . " " . $2;
                    ($dateBegin, $dateEnd) =
                    $self->_getDates(date_begin=>$quarter, type=>"quarter");                                
                } else {               
                    ($dateBegin, $dateEnd) =
                    $self->_getDates(date_begin=>$fileName, type=>"text");
                }
            }

            unless($dateBegin && $dateEnd){
                $self->errstr("Could not get dates from: $f_date");

                print STDERR "Could not get dates from: $f_date\n";

                return undef;
            }

            foreach my $line (@$sheet) {
                my $serviceProductID = $line->[$offsets->{service_product_id}];
                my $title = $line->[$offsets->{title}];
                my $sales = $line->[$offsets->{sales}];
                my $salesRevenue = $line->[$offsets->{sales_revenue}];
                my $returns = $line->[$offsets->{returns}];
                my $returnsRevenue = $line->[$offsets->{returns_revenue}];
                my $retailPrice = $line->[$offsets->{retail_price}];

                my $shippingFee = $line->[$offsets->{shipping_fee}]
                if(defined $offsets->{shipping_fee});

                my $serviceFee  = $line->[$offsets->{service_fee}]
                if(defined $offsets->{service_fee});
                my $f_totalRevenue = $line->[$offsets->{total_revenue}];

                $salesRevenue -= $shippingFee if(defined $offsets->{shipping_fee});
                $salesRevenue -= $serviceFee  if(defined $offsets->{service_fee});

                my $totalRevenue = $salesRevenue - $returnsRevenue;

                #print STDERR "Line number: $linenum Total revenue: $f_totalRevenue ".
                #"calculated revenue: $totalRevenue\n";


                if($serviceProductID && $title &&
                $sales =~ /\d+/ && $totalRevenue =~ /\d+/ &&
                $title !~ /total/i){

                    # !!! I don't know why we're doing this check, or if this is even valid.
                    #
#                    if($f_totalRevenue != $totalRevenue){
#                        $self->errstr("Total revenue in file $f_totalRevenue ".
#                        "does not match calculated total revenue $totalRevenue ".
#                        "at line number: $linenum");
#
#                        print STDERR "Total revenue in file $f_totalRevenue".
#                        "does not match calculated total revenue $totalRevenue ".
#                        "at line number: $linenum\n";
#                        return undef;
#                    }

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

                    $sale->dateBegin($dateBegin);
                    $sale->dateEnd($dateEnd);
                    $sale->countryCode($countryCode);
                    $sale->currencyCode($currencyCode);
                    $sale->productType($productType);
                    $sale->mediaType($mediaType);
                    $sale->retailPrice($retailPrice);

                    $sale->channel($channel);
                    $sale->priceLevel($priceLevel);
                    $sale->sales($sales);
                    $sale->salesRevenue($salesRevenue);
                    $sale->returns($returns);
                    $sale->returnsRevenue($returnsRevenue);
                    $sale->totalRevenue($totalRevenue);
                    $sale->lineNum($linenum);
                    $self->_insertSale(sale => $sale);
                }
                #else{print STDERR
                #"linenum: $linenum Svc prod ID: $serviceProductID title: ".
                #"$title sales: $sales total revenue: $totalRevenue\n"}


                $linenum++;
            }


        }
        $sheet_count++;
    }

    $fileObj->Physical(1);
    $fileObj->Save();

    return $linenum;
}


sub _getPriceCol{
    my $sheet = shift;

    foreach my $line (@$sheet) {
        my @line_array = @$line;
        my $line_size = @line_array;

        foreach my $col(0..($line_size - 1)){
            if($line_array[$col] =~ /net revenue/i){
                return $col;
            }
        }
    }

    return undef;

}

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