package RPS::Import::UniversalTab;

use strict;

use Date::Calc qw(Days_in_Month);

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

use lib '/app/tools/data_classes/lib';
use Client::Service;

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

my %FORMAT_MAP = ();
my %MEDIA_TYPE = ();

# some service names have strange variations or decoration so map them to our id's
my %service_map = (
    'apple digital sales'                 => Client::Service::DSP_ITUNES,
    'digital kiosk'                       => Client::Service::DSP_DIGITALKIOSKTECH,
    'full audio/musicnow'                 => Client::Service::DSP_MUSICNOW,
    'listen/rhapsody'                     => Client::Service::DSP_REAL,
    'virtual music stores'                => Client::Service::DSP_VIRTUALMUSICSTORE,
    'erricsson inc.'                      => Client::Service::DSP_ERICSSON,
    'you tube'                            => Client::Service::DSP_YOUTUBE,
    'musicgremlin'                        => Client::Service::DSP_MUSICGREMLIN,
    'alltel communications'               => Client::Service::DSP_ALLTEL,
    'boost mobile/nextel'                 => Client::Service::DSP_BOOST,
    'microsoft'                           => Client::Service::DSP_MICROSOFT,
    'lagardere active north ametica'      => Client::Service::DSP_LAGARDEREACTIVE,
    'lagardere active north ametica, inc' => Client::Service::DSP_LAGARDEREACTIVE,
    'mod systems'                         => Client::Service::DSP_MODSYSTEMS,
    'broadband instruments'               => Client::Service::DSP_BROADBANDINSTS,
    'planet a networks'                   => Client::Service::DSP_PLANETA,
    'teen hollywood com'                  => Client::Service::DSP_TEENHOLLYWOOD,
    'teenhollywood'                       => Client::Service::DSP_TEENHOLLYWOOD,
    'cricket communications'              => Client::Service::DSP_CRICKET,
);

# map their product types to ours
my %type_map = (
    'album'          => RPS::File::Sale::TYPE_ALBUM,
    'complete album' => RPS::File::Sale::TYPE_ALBUM,
    'track'          => RPS::File::Sale::TYPE_TRACK,
);

my %field_map = (
    2 => {
        'album' => {
            service => 0,
            format  => 1,
            type    => 2,
            upc     => 3,
            artist  => 4,
            album   => 5,
            period  => 8,
            label   => 9,

            #blank          => 10,
            price    => 11,
            units    => 12,
            extprice => 13,
        },
        'track' => {
            service => 0,
            format  => 1,
            type    => 2,
            isrc    => 3,
            upc     => 4,
            artist  => 5,
            track   => 6,
            period  => 9,
            label   => 10,

            #blank          => 11,
            #price           => 12,
            #units           => 13,
            #extprice        => 14,
            price    => 11,
            units    => 12,
            extprice => 13,
        },
    },
    3 => {    # same as above but no blank col
        'album' => {
            service  => 0,
            format   => 1,
            type     => 2,
            upc      => 3,
            artist   => 4,
            album    => 5,
            period   => 8,
            label    => 9,
            price    => 10,
            units    => 11,
            extprice => 12,
        },
        'track' => {
            service  => 0,
            format   => 1,
            type     => 2,
            isrc     => 3,
            upc      => 4,
            artist   => 5,
            track    => 6,
            period   => 9,
            label    => 10,
            price    => 11,
            units    => 12,
            extprice => 13,
        },
    },
    4 => {
        'album' => {
            service  => 0,
            format   => 1,
            type     => 2,
            upc      => 3,
            artist   => 4,
            album    => 5,
            period   => 8,
            label    => 9,
            price    => 11,
            units    => 12,
            extprice => 13,
        },
        'track' => {
            service  => 0,
            format   => 1,
            type     => 2,
            isrc     => 3,
            upc      => 4,
            artist   => 5,
            track    => 6,
            period   => 9,
            label    => 10,
            price    => 11,
            units    => 12,
            extprice => 13,
        },

    },
);

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

    my $retval     = undef;
    my $sheets     = $args{sheets};
    my $sheetNames = $args{sheet_names};
    my $version    = $self->_version();

    $self->_setup();

    my %errors = ();
    for ( my $i = 0 ; $i < @$sheets ; $i++ ) {
        my $sheet     = $sheets->[$i];
        my $sheetName = $sheetNames->[$i];
        my $offsets;
        if ( $sheetName =~ /Album/i ) {
            $offsets = $field_map{$version}{'album'};
        } elsif ( $sheetName =~ /Track/i ) {
            $offsets = $field_map{$version}{'track'};
        }
        next unless defined($offsets);

        my $linenum = 0;
        foreach my $line (@$sheet) {
            if ( $sheetName !~ /Summary/i ) {
                $linenum++;

                if ( $linenum == 1 && $sheetName =~ /Track/ && ( $version == 4 || $version == 3 ) ) {
                    my @fields = @$line;
                    foreach ( my $x = 0 ; $x < @fields ; $x++ ) {
                        $offsets->{units}    = $x if ( $fields[$x] =~ /Track Sales Units/i );
                        $offsets->{extprice} = $x if ( $fields[$x] =~ /Track Sales Revenue/i );
                    }
                }

                my $raw_type = lc( $line->[ $offsets->{'type'} ] );
                my $type     = $type_map{$raw_type};
                my $isrc     = normalize_isrc( $line->[ $offsets->{'isrc'} ] ) if exists( $offsets->{'isrc'} );
                my $upc      = normalize_upc( $line->[ $offsets->{'upc'} ] );
                my $artist   = $line->[ $offsets->{'artist'} ];
                my $album    = $line->[ $offsets->{'album'} ] if exists( $offsets->{'album'} );
                my $track    = $line->[ $offsets->{'track'} ] if exists( $offsets->{'track'} );
                my ( $dateBegin, $dateEnd ) = $self->_getDates( $line->[ $offsets->{'period'} ] );
                my $label    = $line->[ $offsets->{'label'} ];
                my $units    = $line->[ $offsets->{'units'} ];
                my $extprice = $line->[ $offsets->{'extprice'} ];
                my $price;

                if ( defined $offsets->{extprice} ) {
                    $price = $extprice / $units if ( $units != 0 );
                    $price = $extprice          if ( $units == 0 );
                }
                my $free = 0;
                $free = 1 if ( $price == 0 );

                if ( $artist && ( $album || $track ) && ( $price != 0 || $units != 0 ) && $linenum > 1 ) {
                    my $mediaType = $line->[ $offsets->{'format'} ] =~ /video/i ? $MEDIA_TYPE{video} : $MEDIA_TYPE{audio};
                    my $serviceNm = lc $line->[ $offsets->{'service'} ];
                    $serviceNm =~ s/ \(.*[^\)]\)//;
                    $serviceNm =~ s/\,?\s+(inc|llc|corp|usa)\.?$//i;
                    $serviceNm =~ s/\.com//i;
                    $serviceNm =~ s/\s+(americas|broadcasting|entertainment|networks?|solutions|technologies)$//;

                    my $serviceID = $self->getServiceID( lc($serviceNm) ) || $RPS::Import::ServiceMap::SERVICE_ALIASES{ lc $serviceNm };

                    my $format   = $self->getFormatID( $line->[ $offsets->{'format'} ] );
                    my $raw_type = lc( $line->[ $offsets->{'type'} ] );
                    my $type     = $type_map{$raw_type};
                    my $isrc     = normalize_isrc( $line->[ $offsets->{'isrc'} ] ) if exists( $offsets->{'isrc'} );
                    my $upc      = normalize_upc( $line->[ $offsets->{'upc'} ] );
                    if ( !$serviceID ) {
                        $serviceID = $service_map{$serviceNm};
                    }
                    if ( !$serviceID ) {
                        my $service = $line->[ $offsets->{'service'} ];
                        if ( !$errors{$service} ) {
                            $self->warning();
                            print STDERR "unknown service: l:" . $linenum . " s:" . $service . "\n";
                            $errors{$service} = 1;
                        }
                    }

                    if ( !$format ) {
                        $self->errstr("unknown format");
                        print STDERR "unknown format: l: " . $linenum . " |->" . $line->[ $offsets->{format} ] . "<-|\n";
                        return undef;
                    }

                    if ( $sheetName =~ /album/i ) {
                        $type = RPS::File::Sale::TYPE_ALBUM;
                    } elsif ( $sheetName =~ /track/i ) {
                        $type = RPS::File::Sale::TYPE_TRACK;
                    }

                    if ( !( $dateBegin || $dateEnd ) ) {
                        $self->errstr("can't get dates");
                        print STDERR "invalid dates: $line->[$offsets->{period}]\n";
                        return undef;
                    }

                    my $has_no_sale = 0;
                    if ( $units == 0 && $price != 0 ) {
                        $has_no_sale = 1;
                        $units = ( $price < 0 ) ? -1 : 1;
                    }
                    $price *= -1 if ( $price < 0 && $units < 0 );

                    my $sale = RPS::Import::SaleRec->new();
                    $sale->serviceID($serviceID);
                    $sale->productType($type);
                    $sale->formatType($format);
                    $sale->dateBegin($dateBegin);
                    $sale->dateEnd($dateEnd);
                    $sale->upc($upc);
                    $sale->isrc($isrc);
                    $sale->labelName($label);
                    $sale->artistName($artist);
                    $sale->albumName($album);
                    $sale->trackName($track);
                    $sale->units($units);
                    $sale->price($price);
                    $sale->free($free);
                    $sale->lineNum($linenum);
                    $sale->countryCode('US');
                    $sale->mediaType($mediaType) unless $self->is_wmg;

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

                    if ( $has_no_sale > 0 ) {
                        my $sale = RPS::Import::SaleRec->new();
                        $sale->serviceID($serviceID);
                        $sale->productType($type);
                        $sale->formatType($format);
                        $sale->dateBegin($dateBegin);
                        $sale->dateEnd($dateEnd);
                        $sale->upc($upc);
                        $sale->isrc($isrc);
                        $sale->labelName($label);
                        $sale->artistName($artist);
                        $sale->albumName($album);
                        $sale->trackName($track);
                        $sale->free($free);
                        $sale->lineNum($linenum);
                        $sale->mediaType($mediaType) unless $self->is_wmg;
                        $sale->units(-1) if ( $units == 1 );
                        $sale->units(1)  if ( $units == -1 );
                        $sale->price(0);
                        $sale->countryCode('US');
                        $self->_insertSale( sale => $sale );
                    }
                }

                #else { print STDERR "skip sn:".$sheetName." l: $linenum r: $artist (a: $album or t: $track) u: $units p: $price\n"; }
            }
        }
    }

    return 1;
}

#
# Private methods
#

sub _getDates {
    my $self   = shift;
    my $period = shift;

    my $dateBegin;
    my $dateEnd;

    my ( $month, $year ) = $period =~ m/^UMG P(\d\d?) (\d\d) /i;

    if ( $month && $year ) {
        $year += 2000;

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

    return ( $dateBegin, $dateEnd );
}

=stop
sub getServiceID
{
    my $self = shift;
    my $serviceName = lc shift;

    # strip useless decoration
    $serviceName =~ s/\,?\s+(inc|llc|corp|usa)\.?$//i;
    $serviceName =~ s/\s+(americas|broadcasting|entertainment|networks?|solutions|technologies)$//;
    return $self->SUPER::getServiceID($serviceName) || $service_map{$serviceName};

}
=cut

sub getFormatID {
    my $self   = shift;
    my $format = lc shift;
    $format =~ s/\s\(.*[^\)]\)//;

    if ( $self->{clientID} == RPS::Import::Importer::WMG ) {
        return RPS::Import::WMG::Util::getWirelessFormatTypeID($format) || $FORMAT_MAP{$format};
    }

    # else
    return $FORMAT_MAP{$format};
}

sub _setup {
    my $self = shift;

    # some format names have strange variations or decoration
    %FORMAT_MAP = (
        'ad supported streams' => RPS::File::Sale::FORMAT_STREAM,
        'kiosk'                => RPS::File::Sale::FORMAT_DOWNLOAD,

        #'ota permanent downloads'           => RPS::File::Sale::FORMAT_DOWNLOAD,
        'permanent downloads'            => RPS::File::Sale::FORMAT_DOWNLOAD,
        'portable sub client plays'      => RPS::File::Sale::FORMAT_TETHERED,
        'portable sub device plays'      => RPS::File::Sale::FORMAT_TETHERED,
        'portable sub streams'           => RPS::File::Sale::FORMAT_STREAM,
        'programmed streaming'           => RPS::File::Sale::FORMAT_STREAM,
        'subscription mastertones'       => RPS::File::Sale::FORMAT_RINGTONE,
        'streams'                        => RPS::File::Sale::FORMAT_STREAM,
        'tethered/conditional downloads' => RPS::File::Sale::FORMAT_TETHERED,
        'standard mobile ringsounds'     => RPS::File::Sale::FORMAT_RINGTONE,
        'ota permanent downloads'        => RPS::File::Sale::FORMAT_RINGTONE,
    );

    # map the rest based on WMG or non-WMG
    if ( $self->is_wmg ) {
        require RPS::Import::WMG::Util;
        $FORMAT_MAP{'standard mobile ringsounds'} = RPS::File::Sale::FORMAT_RINGTONE,

          # the rest are handled by getWirelessFormatTypeID in Util
    } else {
        $FORMAT_MAP{'video downloads'}              = RPS::File::Sale::FORMAT_DOWNLOAD,    # was FORMAT_VIDEO (FB1324)
          $FORMAT_MAP{'video streams'}              = RPS::File::Sale::FORMAT_STREAM,      # was FORMAT_VIDEOSTREAM (FB1324)
                                                                                           # force all mobile types to ringtone
          $FORMAT_MAP{'mastertones'}                = RPS::File::Sale::FORMAT_RINGTONE,
          $FORMAT_MAP{'mobile images'}              = RPS::File::Sale::FORMAT_RINGTONE,
          $FORMAT_MAP{'mobile video streaming'}     = RPS::File::Sale::FORMAT_RINGTONE,
          $FORMAT_MAP{'ota video downloads'}        = RPS::File::Sale::FORMAT_RINGTONE,
          $FORMAT_MAP{'polyphonic ringtones'}       = RPS::File::Sale::FORMAT_RINGTONE,
          $FORMAT_MAP{'ringbacks'}                  = RPS::File::Sale::FORMAT_RINGTONE,
          $FORMAT_MAP{'standard mobile ringsounds'} = RPS::File::Sale::FORMAT_RINGTONE,

          eval {
            use lib '/app/tools/rps/lib';
            require RPS::DB::Item::MediaType;

            %MEDIA_TYPE = (
                video => RPS::DB::Item::MediaType::kMediaTypeVideo(),
                audio => RPS::DB::Item::MediaType::kMediaTypeAudio(),
            );
          };

    }
}

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