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.
###
