package RPS::Import::Rykodisc;

use strict;

use Date::Calc qw(Days_in_Month Decode_Month);

use lib '/app/tools/common/lib';
use Common::Util;
use Common::Log;
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 => {
        'outlet'   => 7,
        'r_price'  => 9,
        'freepct'  => 10,
        'upc'      => 11,
        'format'   => 12,
        'artist'   => 15,
        'album'    => 16,
        'label'    => 18,
        'sales'    => 19,
        'returns'  => 20,
        'psales'   => 24,
        'preturns' => 25,
        'ptotal'   => 26,
    },
    2 => {
        'service'      => 0,
        'artist'       => 1,
        'date_begin'   => 2,
        'date_end'     => 3,
        'upc_isrc'     => 4,
        'product_type' => 5,
        'track'        => 6,
        'label'        => 7,
        'upc'          => 8,
        'album'        => 9,
        'units'        => 14,
        'price'        => 15,
        'revenue'      => 16,
        'country'      => 17,
        'format'       => 18,
        'format_type'  => 23,
    },
);

#public methods

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

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

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

    my $offsets = $field_map{$version};

    my $dateBegin;
    my $dateEnd;

    # For physical sales files only, we have to grab the date from the file name.
    if ( $version == 1 ) {
        $fileObj->Physical(1);

        ( $dateBegin, $dateEnd ) = $self->_getDatesFromFileName($fileName);

        unless ( $dateBegin && $dateEnd ) {
            $self->errstr( "couldn't get dates from " . $fileName );
            print STDERR "couldn't get dates from $fileName\n";
            return undef;
        }
    }

    my $linenum = 1;

    foreach my $line (@$lines) {

        if ( $version == 1 ) {

            # physical sales
            #
            if ( $line->[ $offsets->{freepct} ] eq "100" ) {
                ## skip totally free entries
                $linenum++;
                next;
            }
            my $price_level  = RPS::File::Sale::PLEVEL_FULL;
            my $channel      = RPS::File::Sale::CHANNEL_RETAIL;
            my $retail_price = $line->[ $offsets->{r_price} ];
            my $outlet       = $line->[ $offsets->{outlet} ];
            my $upc          = $line->[ $offsets->{upc} ];
            my $artist       = $line->[ $offsets->{artist} ];
            my $album        = $line->[ $offsets->{album} ];
            my $label        = $line->[ $offsets->{label} ];
            my $config       = $line->[ $offsets->{format} ];
            my $prodtype;

            if ( $config eq "CD" || $config eq "C3" || $config eq "CM" ) {
                $prodtype = RPS::File::Sale::TYPE_CD;
            } elsif ( $config eq "A" ) {
                $prodtype = RPS::File::Sale::TYPE_LP;
            } elsif ( $config eq "S" ) {
                $prodtype = RPS::File::Sale::TYPE_LP;
            } elsif ( $config eq "DV" ) {
                $prodtype = RPS::File::Sale::TYPE_DVD;
            } elsif ( $config eq "CX" ) {
                $prodtype = RPS::File::Sale::TYPE_DVD_CD_SET;
            } elsif ( $config eq "DVDCD" ) {
                $prodtype = RPS::File::Sale::TYPE_DVD_CD_SET;
            }

            my ($sales)         = $line->[ $offsets->{sales} ] =~ m/^(-?\d+)$/;
            my ($returns)       = $line->[ $offsets->{returns} ] =~ m/^(-?\d+)$/;
            my ($sales_price)   = $line->[ $offsets->{psales} ] =~ m/^(-?\d*\.?\d*)$/;
            my ($returns_price) = $line->[ $offsets->{preturns} ] =~ m/^(-?\d*\.?\d*)$/;
            my ($total_price)   = $line->[ $offsets->{ptotal} ] =~ m/^(-?\d*\.?\d*)$/;

            ## clean up album name
            $album =~ s/\([^\(]*$//;

            if ( $prodtype && ( $sales || $returns || $total_price ) && $album ) {
                my $sale = RPS::Import::SaleRec->new();

                $sale->productType($prodtype);
                $sale->dateBegin($dateBegin);
                $sale->retailPrice($retail_price);
                $sale->dateEnd($dateEnd);
                $sale->outlet($outlet);
                $sale->upc($upc);
                $sale->artistName($artist);
                $sale->albumName($album);
                $sale->labelName($label);
                $sale->sales($sales);
                $sale->salesRevenue($sales_price);
                $sale->returns($returns);
                $sale->returnsRevenue($returns_price);
                $sale->totalRevenue($total_price);
                $sale->priceLevel($price_level);
                $sale->channel($channel);
                $sale->configuration($config);
                $sale->countryCode('US');
                $sale->lineNum($linenum);

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

                #print STDERR "skipping $linenum - a: $album , s: $sales , r: $returns , \$$total_price\n";
            }
            $linenum++;
        } else {

            # digital sales
            #

            # Skip the header...
            #
            if ( 'start_date' eq lc( $line->[ $offsets->{'date_begin'} ] ) ) {
                $linenum++;
                next;
            }

            my $prodtype;
            if ( $line->[ $offsets->{'product_type'} ] eq 'ISRC' ) {
                $prodtype = RPS::File::Sale::TYPE_TRACK;
            } else {
                $prodtype = RPS::File::Sale::TYPE_ALBUM;
            }

            my $format;
            if ( $line->[ $offsets->{'format'} ] eq 'eMastertone' ) {
                $format = RPS::File::Sale::FORMAT_RINGTONE;    # was FORMAT_MASTERTONE (FB1324)
            } elsif ( $line->[ $offsets->{'format'} ] eq 'eRingback' ) {
                $format = RPS::File::Sale::FORMAT_RINGBACK;
            } elsif ( $line->[ $offsets->{'format'} ] eq 'EMD' ) {
                if ( $line->[ $offsets->{'format_type'} ] eq 'Streaming' ) {
                    $format = RPS::File::Sale::FORMAT_STREAM;
                } elsif ( $line->[ $offsets->{'format_type'} ] eq 'PayAsYouGo' ) {
                    $format = RPS::File::Sale::FORMAT_DOWNLOAD;
                }
            }

            my $dateBegin = $line->[ $offsets->{'date_begin'} ];
            my $dateEnd   = $line->[ $offsets->{'date_end'} ];

            # Call the inherited method to normalize the dates.
            #
            ( $dateBegin, $dateEnd ) = $self->_getDates( date_begin => $dateBegin, date_end => $dateEnd );

            #
            # Quick sanity check for dates
            #				  unless ($dateBegin && $dateEnd) {
            #			        $self->errstr("couldn't get dates");
            #			        print STDERR "filename: $fileName\n";
            #			        return undef;
            #			    }

            #					$dateBegin = substr($dateBegin, 6, 4)."-".substr($dateBegin, 0, 2)."-".substr($dateBegin, 3, 2);
            #					$dateEnd = substr($dateEnd, 6, 4)."-".substr($dateEnd, 0, 2)."-".substr($dateEnd, 3, 2);

            my $upc = Common::Util::normalize_upc( $line->[ $offsets->{'upc'} ] );

            my $isrc;
            my $track;
            if ( $line->[ $offsets->{'product_type'} ] eq 'ISRC' ) {

                # we only want to populate these if we are dealing with a track
                $isrc  = Common::Util::normalize_isrc( $line->[ $offsets->{'upc_isrc'} ] );
                $track = $line->[ $offsets->{'track'} ];
            }

            my $country      = $line->[ $offsets->{'country'} ];
            my $currencyCode = "USD";
            my $artist       = $line->[ $offsets->{'artist'} ];
            my $album        = $line->[ $offsets->{'album'} ];
            my $label        = $line->[ $offsets->{'label'} ];
            my ($units)      = $line->[ $offsets->{'units'} ] =~ m/^(-?\d+)$/;
            my $revenue      = $line->[ $offsets->{'revenue'} ];
            my $serviceID    = $self->getServiceID( $line->[ $offsets->{'service'} ] );

            if ( $prodtype && $units && ( $artist || $album || $track ) ) {
                my $price = $revenue / $units;

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

                $sale->productType($prodtype);
                $sale->formatType($format);
                $sale->dateBegin($dateBegin);
                $sale->dateEnd($dateEnd);
                $sale->upc($upc);
                $sale->isrc($isrc);
                $sale->artistName($artist);
                $sale->albumName($album);
                $sale->trackName($track);
                $sale->labelName($label);
                $sale->units($units);
                $sale->currencyCode($currencyCode);
                $sale->countryCode($country);
                $sale->price($price);
                $sale->lineNum($linenum);
                $sale->serviceID($serviceID);
                $sale->free(1) if ( $price == 0 );

                $self->_insertSale( sale => $sale );
            }
            $linenum++;
        }
    }
    return $linenum;
}

#
# Private methods
#

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

    my ( $dateBegin, $dateEnd, $month, $year );

    if ( $date =~ m/\s(\d+)-(\d{4})\s/ ) {
        $month     = $1;
        $year      = $2;
        $dateBegin = sprintf( "%04d-%02d-%02d", $year, $month, 1 );
        $dateEnd   = sprintf( "%04d-%02d-%02d", $year, $month, Days_in_Month( $year, $month ) );
    } elsif ( $date =~ m/\s(\d+)-(\d{2})\s/ ) {
        $month     = $1;
        $year      = "20" . $2;
        $dateBegin = sprintf( "%04d-%02d-%02d", $year, $month, 1 );
        $dateEnd   = sprintf( "%04d-%02d-%02d", $year, $month, Days_in_Month( $year, $month ) );
    } elsif ( $date =~ m/(\w*)\s*(\d{4})\s*Sales/ ) {

        $month = Decode_Month($1);
        $year  = $2;

        $dateBegin = sprintf( "%04d-%02d-%02d", $year, $month, 1 );
        $dateEnd = sprintf( "%04d-%02d-%02d", $year, $month, Days_in_Month( $year, $month ) );
    } else {
        return undef;
    }

    return ( $dateBegin, $dateEnd );
}

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