package RPS::Import::YouTube;

use strict;

use Data::Dumper;

use lib '/app/tools/common/lib';
use Common::Date;
use Common::Util;
use Common::Consts;
use Common::Country;
use Math::BigFloat;
use Date::Calc qw(Days_in_Month Decode_Month);

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

# map version num to the field order
my %fieldMap =
(
	1 => {
        date_start          => 7,
        date_end            => 8,
        album               => 15,
        track               => 16,
        possible_track      => 10,
        service_product_id  => 14,
        units               => 19,
        price               => 21,
        currency            => 22,
	},
    2 => {
        date_start          => 7,
        date_end            => 8,
        track               => 13,
        artist              => 14,
        possible_track      => 10,
        service_product_id  => 10,
        units               => 18,
        price               => 20,
        currency            => 21,
    },
    3 => {
        date_start_col      => 1,
        date_end_col        => 1,
        date_start_row      => 28,
        date_end_row        => 29,
        artist              => 11,
        track               => 12,
        service_product_id  => 1,
        units               => 5,
        price               => 7,
        currency            => 8,
    },
    4 => {
        date_start_col      => 1,
        date_end_col        => 1,
        date_start_row      => 33,
        date_end_row        => 34,
        track               => 14,
        service_product_id  => 1,
        units               => 5,
        price               => 11,
        currency            => 12,
    },
    5 => {
        date_start_col      => 1,
        date_end_col        => 1,
        date_start_row      => 33,
        date_end_row        => 34,
        track               => 12,
        service_product_id  => 1,
        possible_track      => 1,
        units               => 3,
        price               => 9,
    },
    6 => {
        date_start_col      => 1,
        date_end_col        => 1,
        date_start_row      => 35,
        date_end_row        => 36,
        track               => 2,
        service_product_id  => 1,
        possible_track      => 1,
        units               => 9,
        price               => 11,
    },
    8 => {
        date_start          => 7,
        date_end            => 8,
        service_product_id  => 10,
        possible_track      => 10,
        isrc                => 15,
        upc                 => 17,
        artist              => 18,
        track               => 19,
        album               => 20,
        label               => 21,
        units               => 22,
        price               => 24,
        currency            => 25,
     },
     9 => {
        date_start_col      => 1,
        date_end_col        => 1,
        date_start_row      => 28,
        date_end_row        => 29,
        service_product_id  => 1,
        possible_track      => 1,
        units               => 5,
        price               => 7,
        currency            => 8,
        isrc                => 11,
        upc                 => 13,
        artist              => 14,
        track               => 15,
        album               => 16,
        label               => 17,
     },
     10 => {
        date_start_col      => 1,
        date_end_col        => 1,
        date_start_row      => 34,
        date_end_row        => 35,
        service_product_id  => 1,
        possible_track      => 1,
        units               => 4,
        price               => 10,
        multiple_claims     => 11,
        isrc                => 14,
        upc                 => 16,
        artist              => 17,
        track               => 18,
        album               => 19,
        label               => 20,
     },
     11 => {
        date_start_col      => 1,
        date_end_col        => 1,
        date_start_row      => 38,
        date_end_row        => 39,
        service_product_id  => 0,
        embeded_units       => 8,
        watched_units       => 9,        
        price               => 13,
        media_type          => 6,
        isrc                => 17,
        upc                 => 19,
        artist              => 20,
        track               => 21,
        album               => 22,
        label               => 23,
     },
     12 => {
        date_start_col      => 1,
        date_end_col        => 1,
        date_start_row      => 40,
        date_end_row        => 41,
        service_product_id  => 0,
        embeded_units       => 9,
        watched_units       => 10,
        currency_code_col   => 1,
        currency_code_row   => 44,
        price               => 14,
        media_type          => 7,
        isrc                => 19,
        upc                 => 21,
        artist              => 22,
        track               => 23,
        album               => 24,
        label               => 25,
     },
     13 => {
        date_start_col      => 1,
        date_end_col        => 1,
        date_start_row      => 39,
        date_end_row        => 40,
        service_product_id  => 0,
        embeded_units       => 9,
        watched_units       => 10,
        currency_code_col   => 1,
        currency_code_row   => 42,
        price               => 14,
        media_type          => 7,
        isrc                => 18,
        upc                 => 20,
        artist              => 21,
        track               => 22,
        album               => 23,
        label               => 24,
     },
     14 => {
        date_start_col      => 1,
        date_end_col        => 1,
        date_start_row      => 43,
        date_end_row        => 44,
        service_product_id  => 0,
        embeded_units       => 9,
        watched_units       => 10,
        currency_code_col   => 1,
        currency_code_row   => 46,
        price               => 14,
        media_type          => 7,
        custom_id           => 20,
        isrc                => 21,
        upc                 => 23,
        artist              => 24,
        track               => 25,
        album               => 26,
        label               => 27,
     },
     15 => {
        date_start_col      => 1,
        date_end_col        => 1,
        date_start_row      => 43,
        date_end_row        => 44,
        service_product_id  => 0,
        embeded_units       => 9,
        watched_units       => 10,
        currency_code_col   => 1,
        currency_code_row   => 46,
        price               => 14,
        media_type          => 7,
        custom_id           => 19,
        isrc                => 20,
        upc                 => 22,
        artist              => 23,
        track               => 24,
        album               => 25,
        label               => 26,
     },     
     16 => {
        date_start_col      => 1,
        date_end_col        => 1,
        date_start_row      => 6,
        date_end_row        => 7,
        label               => 36, #AK
        artist              => 33, #AH
        upc                 => 32, #AG
        album               => 35, #AJ
        isrc                => 30, #AE
        track               => 34, #AI
        units               => 11, #L
        currency_code_col   => 1,
        currency_code_row   => 10,
        price               => 18, #S
        media_type          => 9,  #J
     },    
     17 => {
        date_start_col      => 1,
        date_end_col        => 1,
        date_start_row      => 36,
        date_end_row        => 37,
        service_product_id  => 0,
        embeded_units       => 8,
        watched_units       => 9,        
        price               => 12,
        media_type          => 6,
        isrc                => 16,
        upc                 => 18,
        artist              => 19,
        track               => 20,
        album               => 21,
        label               => 22,
     },      
     18 => {
        date_start_col      => 1,
        date_end_col        => 1,
        date_start_row      => 6,
        date_end_row        => 7,
        currency_code_col   => 1,
        currency_code_row   => 10,

        label               => 37, # AL
        artist              => 34, # AI
        upc                 => 33, # AH
        album               => 36, # AK
        isrc                => 31, # AF
        track               => 35, # AJ
        embeded_units       => 13, # N
        watched_units       => 12, # M
        price               => 18, # S
        media_type          => 9,  # J
     },    
);

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

# This limits how many rows we want to look at when searching
# for the '# header table' section of a sales file.
#
use constant HEADER_LIMIT => 100;

#public methods

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

	my $lines = $args{lines};
    my $fileObj = $args{file};
    my $version = $args{file}->VersionNum();
    my $fileName = $fileObj->OrigFileName;
    my $track_start = "http://youtube.com/watch?v=";
    my ($dateBegin,$dateEnd);
    my $offsets = $fieldMap{$version};

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


    if((defined $offsets->{date_start_row}) &&
       (defined $offsets->{date_start_col}) &&
       (defined $offsets->{date_end_row}) &&
       (defined $offsets->{date_end_col}))
    {

        my ($f_dateBegin, $f_dateEnd);

        # Try to find the start/end dates in the header table of the sales
        # file using the field names.  This will allow some flexibility
        # should the date fields shift relative to the row offsets defined
        # in the fieldMap hash.  If this doesn't work, then we'll look for
        # the date using the row and column offsets.
        #
        my $headerFound;
        my $linenum = 1;
        foreach my $line (@$lines)
        {
            my $fieldName = $line->[0];
            $headerFound = 1  if ( $fieldName && $fieldName eq '# header table' );

            if( $headerFound )
            {
               $f_dateBegin = $line->[$offsets->{date_start_col}] if ( $fieldName eq 'report_period_start_date' );
               $f_dateEnd   = $line->[$offsets->{date_end_col}]   if ( $fieldName eq 'report_period_end_date' );
            }

            $linenum++;

            last if ( ($f_dateBegin && $f_dateEnd) || $linenum > HEADER_LIMIT );
        }


        # Use the default row/column offsets if we didn't find the dates
        # using the named fields above.
        #
        if( !$f_dateBegin || !$f_dateEnd )
        {
            ($f_dateBegin, $f_dateEnd) = (
                $lines->[$offsets->{date_start_row}]->[$offsets->{date_start_col}],
                $lines->[$offsets->{date_end_row}]->[$offsets->{date_end_col}]
            );
        }


       # Version 11 uses date in the format MM/DD/YY
	   if( $f_dateBegin =~ /(\d{1,2})\/(\d{1,2})\/(\d{4})/ ) {
	       $f_dateBegin = sprintf( "%02d/%02d/%04d", $1, $2, $3 );
	   } elsif( $f_dateBegin =~ /(\d{1,2})\/(\d{1,2})\/(\d{2})/ ) {
	       $f_dateBegin = sprintf( "%02d/%02d/20%02d", $1, $2, $3 );
	   }
	   
       if( $f_dateEnd =~ /(\d{1,2})\/(\d{1,2})\/(\d{4})/ ) {
	       $f_dateEnd = sprintf( "%02d/%02d/%04d", $1, $2, $3 );
	   } elsif( $f_dateEnd =~ /(\d{1,2})\/(\d{1,2})\/(\d{2})/ ) {
	       $f_dateEnd = sprintf( "%02d/%02d/20%02d", $1, $2, $3 );
	   }

       ($dateBegin, $dateEnd) =
       $self->_getDates($f_dateBegin." ".$f_dateEnd);

       if(($f_dateBegin =~ /\d{2}\D\d{2}\D\d{4}/) &&
       ($f_dateEnd =~ /\d{2}\D\d{2}\D\d{4}/) && (!$dateBegin || !$dateEnd)){
           ($dateBegin, $dateEnd) =
           $self->SUPER::_getDates(date_begin=>$f_dateBegin, date_end=>$f_dateEnd, type=>"us");
       }

	   if( $f_dateBegin =~ /^\d+$/ ) {
			my $start = new Common::Date(date => $f_dateBegin, type => 'excel');
		    my $end   = new Common::Date(date => $f_dateEnd, type => 'excel');

			($dateBegin, $dateEnd) = ( $start->monthBegin, $end->monthEnd );
	   }
    }


        my $linenum = 1;
        foreach my $line (@$lines)
        {
            my $track               = $line->[$offsets->{track}];
            my $possible_track      = $line->[$offsets->{possible_track}];
            my $album               = $line->[$offsets->{album}] if(defined $offsets->{album});
            my $artist              = $line->[$offsets->{artist}] if(defined $offsets->{artist});
            my $service_product_id  = $line->[$offsets->{service_product_id}]
                if(defined $offsets->{service_product_id});

            my $product_type        = RPS::File::Sale::TYPE_TRACK;
            my $units;

			# This is the header row in ver 12 & 13.  Skip it.
			if( $service_product_id && $service_product_id =~ /video_id/i ) {
				$linenum++;
				next;
			}

			if( defined $offsets->{embeded_units} ) {
				$units = $line->[$offsets->{embeded_units}] + $line->[$offsets->{watched_units}];
			} else {
			    $units = $line->[$offsets->{units}];
			}

            # JPK - Need to use the BigFloat package here, because these prices can be _extremely_ small.
            # In theory we support 8 decimal point precision (in the database), but perl will normally
            # resort to exponent notation once we get below 0.0009 or so.  This will cause problems...
            #
            my $f_price             = $line->[$offsets->{price}];
			$f_price = undef if( $f_price =~ /[a-z]/i );
			# In version 11 free tracks have '$-' in the price column;
			$f_price =~ s/\$-//g;
			$f_price =~ s/\$//g;

            my $country             = "US";
            my $currency;
            $currency               = $line->[$offsets->{currency}] if(defined $offsets->{currency});
            $currency               = "USD" if(!defined $offsets->{currency});
            my $upc                 = $line->[$offsets->{upc}] if(defined $offsets->{upc});
            my $isrc                = $line->[$offsets->{isrc}] if(defined $offsets->{isrc});
            my $client_product_id   = $line->[$offsets->{custom_id}] if(defined $offsets->{custom_id});
            my $label               = $line->[$offsets->{label}] if (defined $offsets->{label});
            my $format_type         = RPS::File::Sale::FORMAT_STREAM;
            my $free                = 0;
            my $multiple_claims     = $line->[$offsets->{multiple_claims}] if (defined $offsets->{multiple_claims});
            $track                  = $track_start . $possible_track if($track eq "" && $album eq "");

            if( defined $offsets->{currency_code_row} ) {
				$currency = $line->[$offsets->{currency_code_col}] if( $offsets->{currency_code_row} eq $linenum );
				die "Unable to determine currency code" unless( $currency );
			}

            if( $upc && $upc =~ /^upc$/i && $isrc && $isrc =~ /^isrc$/i )  # header line, skip
            {
				$linenum++;
				next;
            }

			my $mediaType;
			my $f_mediaType = $line->[$offsets->{media_type}] if( $offsets->{media_type} );

			if( $f_mediaType && $f_mediaType =~ /^Visual/i ) {
				$mediaType = RPS::DB::Item::MediaType::kMediaTypeVideo;
			} else {
				$mediaType = RPS::DB::Item::MediaType::kMediaTypeAudio;
			}


            if($label){
                $label =~ s/(.*) \(.*\)/$1/;
            }

            if ($units =~ /\d+/ &&
            (defined $line->[$offsets->{price}] && ($line->[$offsets->{price}] ne '')) &&
            ($track && $track ne "video_id" && $track !~ /commercial/ || $album) &&
            $currency && $currency !~ /currency/i &&
            (($version != 10) || (($version == 10) && ($multiple_claims)))) {
			    my $price = Math::BigFloat->new($f_price) if(defined $f_price );
                $price /= $units if($units>1);
                $free = 1 if($price == 0);

                $product_type = RPS::File::Sale::TYPE_ALBUM if($track eq $track_start);

                ($dateBegin,$dateEnd) = _getDates($line->[$offsets->{date_start}].
                " ".$line->[$offsets->{date_end}])
                if((defined $offsets->{date_start}) &&
                (defined $offsets->{date_end}));

                unless ($dateBegin && $dateEnd) {
                    print STDERR "Couldn't get dates from ".
                    $line->[$offsets->{date_start}]." ". $line->[$offsets->{date_end}]."\n";
                    $self->errstr("couldn't get dates from ".
                    $line->[$offsets->{date_start}]." " . $line->[$offsets->{date_end}]);
                    return undef;
                }

                my $sale = RPS::Import::SaleRec->new();
                $sale->productType($product_type);
                $sale->formatType($format_type);
                $sale->dateBegin($dateBegin);
                $sale->dateEnd($dateEnd);
                $sale->trackName($track) if($track ne "");
                $sale->albumName($album) if(defined $offsets->{album} && $album ne "");
                $sale->artistName($artist) if(defined $offsets->{artist} && $artist ne "");
                $sale->upc($upc) if(defined $offsets->{upc} && $upc ne "");
                $sale->isrc($isrc) if(defined $offsets->{isrc} && $isrc ne "");
                $sale->clientProductID($client_product_id) if(defined $offsets->{custom_id} && $client_product_id ne "");
                $sale->labelName($label) if (defined $offsets->{label} && $label ne "");
                $sale->units($units);
                $sale->price($price);
                $sale->free($free);
                $sale->mediaType($mediaType);
                $sale->countryCode($country);
                $sale->currencyCode($currency);
                $sale->lineNum($linenum);
                $self->_insertSale(sale => $sale);
            }
            #else { print STDERR "Skip-> l:".$linenum." u:".$units." p:".$price." t: ".$track." c:".$currency."<-Skip\n";}
            $linenum++;
    }
	return $linenum;
}

#
# Private methods
#


sub _getDates
{
    my $self = shift;
	my $date = shift;
	my ($beginDate,$endDate);
    #print STDERR "|>".$date."<|\n";
    if($date =~ m/(\d+)\D(\d+)\D(\d{4}) (\d+)\D(\d+)\D(\d{4})/) {
        $beginDate = $3."-".$1.".".$2;
        $endDate = $6."-".$4."-".$5;
    }
    elsif($date =~ m/(\d{4})\D(\d+)\D(\d+) (\d{4})\D(\d+)\D(\d+)/) {
        $beginDate = $1."-".$2."-".$3;
        $endDate = $4."-".$5."-".$6;
	    return ($beginDate, $endDate);
    }
    return undef;
}

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