package RPS::Import::Moderati;

use strict;

use Date::Calc qw(Days_in_Month);
use Spreadsheet::ParseExcel;

use lib '/app/tools/common/lib';
use Common::Util qw(normalize_upc normalize_isrc normalize_date);

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';

use constant DATE_ROW => 3;
use constant DATE_COL => 3;

my %field_map = (
    1 => {
        'vendorid' => 4,
        'track'    => 5,
        'artist'   => 6,
        'isrc'     => 8,
        'units'    => 13,
        'price'    => 21,
    },
    2 => {
        'vendorid' => 4,
        'track'    => 5,
        'artist'   => 6,
        'isrc'     => 9,
        'units'    => 15,
        'price'    => 25,
    },
    3 => {
        'service'  => 0,
        'vendorid' => 4,
        'track'    => 5,
        'artist'   => 6,
        'format'   => 7,
        'isrc'     => 9,
        'upc'      => 10,
        'units'    => 15,
        'retail'   => 16,
        'price'    => 23,
    },
    4 => {
        'service'  => 0,
        'vendorid' => 3,
        'track'    => 4,
        'artist'   => 5,
        'units'    => 8,
        'retail'   => 13,
        'price'    => 22,
    },
    5 => {
        service  => 1,
        vendorid => 5,
        track    => 6,
        artist   => 7,
        isrc     => 10,
        units    => 16,
        price    => 24,
    },
    6 => {
        service  => 0,
        vendorid => 4,
        track    => 5,
        artist   => 6,
        format   => 7,
        isrc     => 9,
        upc      => 10,
        units    => 11,
        retail   => 16,
        price    => 23,
    },
    7 => {
        service   => 0,
        vendor_id => 4,
        track     => 5,
        artist    => 6,
        units     => 10,
        retail    => 13,
        price     => 22,
    },
    8 => {
        service  => 0,
        vendorid => 4,
        track    => 5,
        artist   => 6,
        format   => 7,
        isrc     => 10,
        upc      => 11,
        units    => 12,
        retail   => 17,
        price    => 24,
    },
);

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

    my $lines    = $args{lines};
    my $fileObj  = $args{file};
    my $version  = $self->_version();
    my $fileName = $fileObj->OrigFileName;

    #my $fileName = $args{OrigFileName}; # for cmd-line testing
    return undef unless ($lines);

    my $offsets = $field_map{$version};
    my ( $dateBegin, $dateEnd );

    if ( $version == 5 || $version == 8 ) {
        ( $dateBegin, $dateEnd ) = $self->_getDates( $lines->[3]->[4] );
    } else {
        ( $dateBegin, $dateEnd ) = $self->_getDates($fileName) if ( $version != 5 );
    }

    unless ( $dateBegin && $dateEnd ) {
        $self->errstr("couldn't get dates");
        print STDERR "date cell: " . $lines->[DATE_ROW]->[DATE_COL] . "\n";
        return 0;
    }

    $self->_setDefaultFormat($fileName);
    my $billToID = 0;    # only used for WMG

    if ( $self->{clientID} == RPS::Import::Importer::WMG )    # warner
    {
        # check for warner specific stuff
        require RPS::Import::WMG::Util;

        my @billTo = RPS::Import::WMG::Util::getWirelessBillto( $self->{fileServiceID} );
        unless ( $billTo[0] ) {
            $self->warning();
            print STDERR "unknown billto mapping: $self->{fileServiceID}\n";
        }
        $billToID = $billTo[0];

        $fileObj->Atomic(1);
        $fileObj->Save();
    }

    my $linenum = 1;
    my %errors;

    foreach my $line (@$lines) {
        my $vendor_id = $line->[ $offsets->{vendorid} ];
        my $artist    = $line->[ $offsets->{artist} ];
        $artist =~ s/\s*\(Warner Music.*?\)//;    # useless decoration
        my $track = $line->[ $offsets->{track} ];
        $track =~ s/\s*-\s*2X$//;                 # useless decoration
        my $isrc = defined $offsets->{isrc} ? normalize_isrc( $line->[ $offsets->{isrc} ] ) : '';
        my $upc  = defined $offsets->{upc}  ? normalize_upc( $line->[ $offsets->{upc} ] )   : '';
        my ($units) = $line->[ $offsets->{units} ] =~ m/^(\-?\d+)$/;
        my $total_price = $self->numeric( $line->[ $offsets->{price} ] );

        if ( $units && $total_price && $artist && $track ) {

            my ( $formatType, $formatName, $serviceID, $retail );
            if ( $version =~ /^3|4|5|6|7|8$/ ) {
                ( $formatType, $formatName ) = $self->_getFormat( $line->[ $offsets->{format} ] );
                my $service = $self->_cleanupServiceName( $line->[ $offsets->{service} ] );
                substr( $formatName, 0, 0 ) = 'brew ' if ( $service =~ m/brew/i );
                $retail = $self->numeric( $line->[ $offsets->{retail} ] );

                unless ( $serviceID = $self->getServiceID($service) || $errors{$service} ) {
                    $self->errstr( 'unknown service (' . $linenum . ') ' . $service );
                    print STDERR "unknown service $service\n";
                    $errors{$service} = 1;
                }
            } else {
                ( $formatType, $formatName ) = $self->_getFormat($track);
            }

            my $price = $total_price / $units;
            my $ppdRate = $retail ? $price / $retail : undef;
            my $priceType;

            if ( $self->{clientID} == RPS::Import::Importer::WMG && $serviceID )    # warner
            {
                unless ( RPS::Import::WMG::Util::getWirelessSellto( $serviceID, $billToID ) || $errors{$serviceID} ) {
                    $self->warning();
                    print STDERR "unknown sellto mapping: $serviceID ($billToID)\n";
                    $errors{$serviceID} = 1;
                }

                unless ( $priceType = RPS::Import::WMG::Util::getWirelessPriceType($formatName) ) {
                    unless ( $errors{$formatName} ) {
                        $self->warning();
                        print STDERR "unknown format mapping: $formatName\n";
                        $errors{$formatName} = 1;
                    }
                }
            }

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

            $sale->serviceID($serviceID);
            $sale->productType(RPS::File::Sale::TYPE_TRACK);
            $sale->formatType($formatType);
            $sale->dateBegin($dateBegin);
            $sale->dateEnd($dateEnd);
            $sale->serviceProductID($vendor_id);
            $sale->upc($upc);
            $sale->isrc($isrc);
            $sale->artistName($artist);
            $sale->trackName($track);
            $sale->units($units);
            $sale->price($price);
            $sale->wholesaleRate($ppdRate);
            $sale->retail($retail);
            $sale->lineNum($linenum);
            $sale->priceType($priceType);
            $sale->countryCode('US');

            #$args{dumper}($sale);  ## for cmd-line testing
            $self->_insertSale( sale => $sale );
        }    #else { print STDERR "skip: u: $units p: $total_price a: $artist t: $track ($linenum)\n"; }
        $linenum++;
    }

    return $linenum;
}

#
# Private methods
#

sub _getDates {
    my $self = shift;
    my $date = shift;
    $date =~ s/\s//g;

    if ( $date =~ /(\d\d\d\d)\D+(\d+)\D+(\d+)\D+(\d\d\d\d)\D+(\d+)\D+(\d+)/ ) {    # YYYY-MM-DD to YYYY-MM-DD
        my $dateBegin = $1 . "-" . sprintf( "%02d", $2 ) . "-" . sprintf( "%02d", $3 );
        my $dateEnd   = $4 . "-" . sprintf( "%02d", $5 ) . "-" . sprintf( "%02d", $6 );
        return ( $dateBegin, $dateEnd );
    } elsif ( $date =~ /Q(\d)(\d{2})/ ) {
        my $year = 2000 + $2;
        my $qtr  = $1;
        return $self->_quarterDates( $qtr, $year );
    } elsif ( $date =~ /(\d{4})Q(\d)/ ) {
        my $year = $1;
        my $qtr  = $2;
        return $self->_quarterDates( $qtr, $year );
    } elsif ( $date =~ /(\d+)\D+(\d+)\D+(\d+)\D+(\d+)\D+(\d+)\D+(\d+)/ ) {
        $date =~ m/(\d+)\D+(\d+)\D+(\d+)\D+(\d+)\D+(\d+)\D+(\d+)/;
        my $dateBegin = "20" . $3 . "-" . sprintf( "%02d", $1 ) . "-" . sprintf( "%02d", $2 );
        my $dateEnd   = "20" . $6 . "-" . sprintf( "%02d", $4 ) . "-" . sprintf( "%02d", $5 );
        return ( $dateBegin, $dateEnd );
    }
}

sub _quarterDates {
    my $self = shift;
    my $qtr  = shift;
    my $year = shift;

    my ( $dateBegin, $dateEnd );
    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 );
    } else {
        return undef;
    }
    return ( $dateBegin, $dateEnd );
}

sub _setDefaultFormat {
    my $self     = shift;
    my $fileName = lc $_[0];

    # Due to format mapping and retiring in FB1324, the default format type is now ringtone
    #
    ( $self->{defaultFormatType}, $self->{defaultFormatName} ) =
      ( RPS::File::Sale::FORMAT_RINGTONE, 'ringtone' );
}

sub _getFormat {
    my $self  = shift;
    my $track = lc $_[0];

    return $track =~ m/\(\s*voice\s*ring/ ? ( RPS::File::Sale::FORMAT_RINGTONE, 'voiceringer' ) :    # was FORMAT_VOICERINGER (FB1324)
      ( $self->{defaultFormatType}, $self->{defaultFormatName} );
}

sub _cleanupServiceName {
    my $self = shift;
    my $svc  = lc $_[0];
    if ( $svc =~ /modtones/ ) {
        $svc =~ s/www\.modtones\.com\s*-\s*//;
        $svc =~ s/\s*-\s*modtones.*$//;
        $svc = "att";
    } elsif ( $svc =~ /at&t/ ) {
        $svc =~ s/at\&t.*$/at\&t/;
        $svc = "att";
    }
    $svc =~ s/'d/d/;    # amp'd

    if    ( $svc =~ s/^u\.s\.\s*/us / )        { }
    elsif ( $svc =~ s/mobile\s*espn/espn/ )    { }
    elsif ( $svc =~ s/\s\(cingular// )         { }
    elsif ( $svc =~ s/\dmy.*$// )              { }
    elsif ( $svc =~ s/\svzw.*$// )             { }
    elsif ( $svc =~ s/at\&t.*$/att/ )          { }
    elsif ( $svc =~ s/at&t\s+mmode/mmode/ )    { }
    elsif ( $svc =~ s/\s*-\s*.*?brand$// )     { }
    elsif ( $svc =~ s/\s*wallpaper// )         { }
    elsif ( $svc =~ s/^.+on-deck\W+(\w+)/$1/ ) { }
    elsif ( $svc =~ s/\W+on-deck$// )          { }
    elsif ( $svc =~ s/_dj$// )                 { }
    elsif ( $svc =~ s/\sringbacks//i )         { }

    return $svc;
}

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