package RPS::Import::Wasabeat;

use strict;

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

use lib '/app/tools/common/lib';
use Common::Consts qw(%COUNTRY_CODE);

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 %fieldMap = (
    1 => {
        date    => 3,
        product => 5,
        track   => 7,
        mix     => 8,
        artist  => 9,
        remixer => 10,
        album   => 12,
        catalog => 6,
        upc     => 14,
        isrc    => 20,
        label   => 24,
        units   => 37,
        price   => 30,
    },
);

my %product_map = (
    "ALBUM"    => RPS::File::Sale::TYPE_ALBUM,
    "RELEASE"  => RPS::File::Sale::TYPE_ALBUM,
    "TRACK"    => RPS::File::Sale::TYPE_TRACK,
    "MIX"      => RPS::File::Sale::TYPE_TRACK,
    "MOBILE"   => RPS::File::Sale::TYPE_TRACK,
    "*RELEASE" => RPS::File::Sale::TYPE_ALBUM,
);

sub _importLines {
    my $self        = shift;
    my %args        = @_;
    my $fileObj     = $args{file};
    my $version     = $args{file}->VersionNum();
    my $fileName    = $args{file}->OrigFileName();
    my $serviceID   = $args{file}->ServiceID;
    my $sheet_count = 0;

    return undef unless ( defined $args{sheets} && defined $version );

    my $offsets      = $fieldMap{$version};
    my $sheet_names  = $args{sheet_names};
    my $header_found = 0;
    my $linenum      = 1;
    my ( $fileNameDateBegin, $fileNameDateEnd );

    #  We need to grab a default date from the overview page.
    #
    my $defaultYear = '';
    my $defaultDate = '';
    foreach my $sheet ( @{ $args{sheets} } ) {
        if ( $sheet_names->[$sheet_count] =~ /overview/i ) {
            foreach my $line (@$sheet) {
                my @line_array = @$line;

                #if ($line->[2] =~ /term/i)
                #{
                #	$defaultDate = $line->[3];
                #}

                my $array_size = @line_array;

                foreach my $index ( 0 .. ( $array_size - 1 ) ) {
                    if ( $line_array[$index] =~ /term/i ) {
                        $defaultYear = $line_array[ $index + 1 ];
                    }

                }
            }
        }
        $sheet_count++;
    }

    if ( $defaultYear =~ /\d{4}/ ) {
        if ( $fileName =~ /Q(\d)/ ) {
            my $quarter = $1;

            $defaultDate = "$defaultYear Q$quarter";
        }
    }

    # if there's no 'overview' page then try to get the default year
    # from the filename.
    #
    if ( '' eq $defaultYear ) {
        if ( $fileName =~ /Q(\d)_(\d\d\d\d)\.csv$/ ) {
            my $quarter = $1;
            $defaultYear = $2;
            $defaultDate = "$defaultYear Q$quarter";
        }
    }

    ( $fileNameDateBegin, $fileNameDateEnd ) = _getDates( $defaultDate, $linenum );

    $sheet_count = 0;

    foreach my $sheet ( @{ $args{sheets} } ) {
        $linenum = 1;
        if ( $sheet_names->[$sheet_count] !~ /overview/i ) {

            foreach my $line (@$sheet) {
                my $country   = "JP";
                my $f_product = uc $line->[ $offsets->{product} ];
                my $product   = $product_map{$f_product};
                my $format    = RPS::File::Sale::FORMAT_DOWNLOAD;
                my $catalog   = $line->[ $offsets->{catalog} ];
                my $artist    = $line->[ $offsets->{artist} ];
                my $track     = $line->[ $offsets->{track} ];
                my $album     = $line->[ $offsets->{album} ];
                my $currency  = "JPY";
                my $price     = $line->[ $offsets->{price} ];
                my $units     = $line->[ $offsets->{units} ];
                my $label     = $line->[ $offsets->{label} ];
                my $isrc      = Common::Util::normalize_isrc( $line->[ $offsets->{isrc} ] );
                my $upc       = $line->[ $offsets->{upc} ];
                $price /= $units if ( $units != 0 );

                if (   $units
                    && $country
                    && $price
                    && ( $track || $album || $isrc )
                    && $artist ne "artist"
                    && ( $line->[ $offsets->{date} ] ne "" || $defaultDate ne "" ) ) {

                    my ( $dateBegin, $dateEnd );

                    my $f_date = $line->[ $offsets->{date} ];

                    #print STDERR "date in file: $f_date\n";

                    if ( !( defined $fileNameDateBegin && defined $fileNameDateEnd ) ) {

                        #print STDERR "Getting dates for $f_date\n";

                        if ( $f_date =~ /(\d{2})(\d{2})(\d{4})/ ) {
                            $f_date = "$1/$2/$3";
                        }

                        ( $dateBegin, $dateEnd ) = $self->SUPER::_getDates( date_begin => $f_date, type => 'us' );
                    } else {
                        ( $dateBegin, $dateEnd ) = ( $fileNameDateBegin, $fileNameDateEnd );
                    }

                    unless ( defined $dateBegin && defined $dateEnd ) {
                        print STDERR "Couldn't get dates from term: $defaultYear and file name: $fileName\n";
                        $self->errstr("Couldn't get dates from term: $defaultYear and file name: $fileName");
                        return undef;
                    }

                    if ( !$product ) {
                        print STDERR "Unknown product type: $f_product at line number: $linenum\n";
                        $self->errstr("Unknown product type: $f_product at line number: $linenum");
                        return undef;
                    }

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

                    $sale->mediaType(2) if ( $format =~ /video/i );
                    $sale->productType($product);
                    $sale->dateBegin($dateBegin);
                    $sale->dateEnd($dateEnd);
                    $sale->trackName($track) if ( $track ne "" );
                    $sale->artistName($artist);
                    $sale->formatType($format);
                    $sale->albumName($album) if ( defined $offsets->{album} );
                    $sale->labelName($label);
                    $sale->serviceProductID($catalog) if ( defined $offsets->{catalog} );
                    $sale->units($units);
                    $sale->price($price);
                    $sale->upc($upc) if ( defined $offsets->{upc} );
                    $sale->isrc($isrc);
                    $sale->countryCode($country);
                    $sale->currencyCode($currency);
                    $sale->lineNum($linenum);

                    $self->_insertSale( sale => $sale );
                }

#else { print STDERR "skip l:" . $linenum . " - a:".$artist." i:".$isrc." c:".$country." u:".$units." p:".$price." t:".$track." a:".$album."\n"; }
                $linenum++;
            }
        }
        $sheet_count++;
    }
    return $linenum;
}

#
# Private methods
#

sub _getDates {
    my ( $syear, $eyear, $smonth, $emonth, $passed_date, $dateBegin, $dateEnd );
    $passed_date = shift;
    my $linenum = shift;

    #print STDERR "passed date: $passed_date line: $linenum\n";
    #print "$passed_date\n";
    if ( $passed_date =~ /(\d+)\.(\d+)/ ) {
        my ( $begin_year, $begin_month, $begin_day ) = Add_Delta_Days( 1900, 1, 1, $1 - 2 );

        return ( $begin_year . "-" . $begin_month . "-01",
            $begin_year . "-" . $begin_month . "-" . Days_in_Month( $begin_year, $begin_month ) );
    } elsif ( $passed_date =~ m/(\d+)\D(\d+)\D(\d{4}) \d{2}:\d{2}:\d{2}/ ) {
        return ( $3 . "-" . sprintf( "%02d", $2 ) . "-01", $3 . "-" . sprintf( "%02d", $2 ) . "-" . Days_in_Month( $3, $2 ) );
    } elsif ( $passed_date =~ m/(\d+)\D(\d+)\D(\d{4})/ ) {
        return ( $3 . "-" . sprintf( "%02d", $2 ) . "-01", $3 . "-" . sprintf( "%02d", $2 ) . "-" . Days_in_Month( $3, $2 ) );
    } elsif ( $passed_date =~ m/(\d{4})\D(\d+)\D(\d+)/ ) {
        return ( $1 . "-" . sprintf( "%02d", $2 ) . "-01", $1 . "-" . sprintf( "%02d", $2 ) . "-" . Days_in_Month( $1, $2 ) );
    } elsif ( $passed_date =~ m/(\d{4})(\d{2})(\d{2})/ ) {
        return ( $1 . "-" . $2 . "-01", $1 . "-" . $2 . "-" . Days_in_Month( $1, $2 ) );
    } elsif ( $passed_date =~ m/(\w{3})\. (\d{4})/ || $passed_date =~ m/(\w{4}) (\d{4})/ || $passed_date =~ m/(\w+)\-(\d{2})/ ) {
        my $year      = $2;
        my %month_map = (
            janv  => 1,
            fevr  => 2,
            mars  => 3,
            avr   => 4,
            mai   => 5,
            juin  => 6,
            juil  => 7,
            aout  => 8,
            sept  => 9,
            'oct' => 10,
            nov   => 11,
            dec   => 12,
        );
        if ( $year < 100 ) {
            $year += 2000;
        }
        return ( $year . "-" . sprintf( "%02d", $month_map{ lc($1) } ) . "-01",
            $year . "-" . sprintf( "%02d", $month_map{ lc($1) } ) . "-" . Days_in_Month( $year, $month_map{ lc($1) } ) );
    } elsif ( $passed_date =~ m/(\d{4}) Q(\d)/ ) {
        $syear = $1;
        $eyear = $1;
        if ( $2 == 1 ) {
            $smonth = "01";
            $emonth = "03";
        } elsif ( $2 == 2 ) {
            $smonth = "04";
            $emonth = "06";
        } elsif ( $2 == 3 ) {
            $smonth = "07";
            $emonth = "09";
        } elsif ( $2 == 4 ) {
            $smonth = "10";
            $emonth = "12";
        }
        if ( $smonth && $syear && $emonth && $eyear ) {
            return ( $syear . "-" . $smonth . "-01", $eyear . "-" . $emonth . "-" . Days_in_Month( $eyear, $emonth ) );
        }
    } elsif ( $passed_date =~ m/(\d{4}) (\d)Q/ ) {
        $syear = $1;
        $eyear = $1;
        if ( $2 == 1 ) {
            $smonth = "01";
            $emonth = "03";
        } elsif ( $2 == 2 ) {
            $smonth = "04";
            $emonth = "06";
        } elsif ( $2 == 3 ) {
            $smonth = "07";
            $emonth = "09";
        } elsif ( $2 == 4 ) {
            $smonth = "10";
            $emonth = "12";
        }
        if ( $smonth && $syear && $emonth && $eyear ) {
            return ( $syear . "-" . $smonth . "-01", $eyear . "-" . $emonth . "-" . Days_in_Month( $eyear, $emonth ) );
        }
    }

    return undef;
}

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