package RPS::Import::ADA::v15;

use strict;
use Data::Dumper;

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

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::MapFaceBase';
use base 'RPS::Import::Importer';

sub _headerIdentifier { ( dateBegin => 'Company' ) }

sub _validateFieldMap {}

sub _fieldMap {
    
    my $self = shift;
    
    my $sheetName = $self->_normalizeSheetName( lc $self->{sheetname} );
    
    my %fieldMaps = (
        'digital' => {
            dateBegin        => 0,
            label           => 1,
            formatType     => 3,
            serviceID     => 4,
            upc             => 5,
            clientProductID => 6,
            productType => 7,
            artistName      => 8,
            trackName       => 9,
            albumName       => 9,
            units           => 12,
            price           => 14,
        },
        'streams' => {
            dateBegin        => 0,
            label           => 1,
            formatType     => 3,
            serviceID     => 4,
            upc             => 5,
            clientProductID => 6,
            productType => 7,
            artistName      => 8,
            trackName       => 9,
            albumName       => 9,
            units           => 11,
            price           => 13,
        },
        'wireless' => {
            dateBegin        => 0,
            label           => 1,
            formatType     => 3,
            serviceID     => 4,
            upc             => 5,
            clientProductID => 6,
            productType => 7,
            artistName      => 8,
            trackName       => 9,
            albumName       => 9,
            units           => 12,
            price           => 14,
        },

        'wmi' => {
            dateBegin        => 0,
            label           => 1,  # B
            formatType     => 3,  # D
            serviceID     => 4,  # E
            countryCode    => 5,  # F
            artistName      => 6,  # G
            trackName       => 7,
            albumName       => 7,
            upc             => 8,  # I
            clientProductID => 9,  # J
            productType => 10, # K
            units           => 13, # N
            price           => 15, # P
        },
    );
    
    $sheetName = 'wmi' if( lc $sheetName eq 'w.m.i.' );
    if ($fieldMaps{$sheetName}) {
        return $fieldMaps{$sheetName};
    } else {
        print STDERR "ADA v15: Illegal sheet '$sheetName'\n";            
        die "Sheet '$sheetName' is not valid"; 
    }
}

my %mediaCodeMap = (
   'emdalbum' => {
      product_type => RPS::File::Sale::TYPE_ALBUM,
      format_type  => RPS::File::Sale::FORMAT_DOWNLOAD,
      media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
   },
   'emdalbumstreaming' => {
      product_type => RPS::File::Sale::TYPE_ALBUM,
      format_type  => RPS::File::Sale::FORMAT_STREAM,
      media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
   },
   'emdtrack' => {
      product_type => RPS::File::Sale::TYPE_TRACK,
      format_type  => RPS::File::Sale::FORMAT_DOWNLOAD,
      media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
   },
   'emdtrackstreaming' => {
      product_type => RPS::File::Sale::TYPE_TRACK,
      format_type  => RPS::File::Sale::FORMAT_STREAM,
      media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
   },
   'evd' => {
      product_type => RPS::File::Sale::TYPE_TRACK,  # default; may be overriden if UPC is set
      format_type  => RPS::File::Sale::FORMAT_DOWNLOAD, # was FORMAT_VIDEO (FB1324)
      media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
   },
   'evdstreaming' => {
      product_type => RPS::File::Sale::TYPE_TRACK,
      format_type  => RPS::File::Sale::FORMAT_STREAM, # was FORMAT_VIDEOSTREAM (FB1324)
      media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
   },

   # Ringtones
   'emastertone' => {
      product_type => RPS::File::Sale::TYPE_TRACK,
      format_type  => RPS::File::Sale::FORMAT_RINGTONE,
      media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
   },
   'eringback' => {
      product_type => RPS::File::Sale::TYPE_TRACK,
      format_type  => RPS::File::Sale::FORMAT_RINGTONE,
      media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
   },
   'usergenmastertone' => {
      product_type => RPS::File::Sale::TYPE_TRACK,
      format_type  => RPS::File::Sale::FORMAT_RINGTONE,
      media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
   },

   'usergenmastertonestreaming' => {
      product_type => RPS::File::Sale::TYPE_TRACK,
      format_type  => RPS::File::Sale::FORMAT_STREAM,
      media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
   },
);

sub _getDateBegin { shift->{_dateBegin} }

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

    Log->info( "Starting _preProcess" );
    $self->SUPER::_preProcess(%args);

    foreach my $line(@{ $args{lines} }) {

        $self->{line} = $line;

        # Get the date from the header
        #
		my $dateHeader = $line->[0];
		if( $dateHeader =~ /through (\w*) (\d{4})/ || $dateHeader =~ /^(\w*) (\d{4})$/) {
            $self->{_dateBegin} = "$1 $2";    
            last;		    
		}
    }
}

sub countryCode {
    my $self = shift;

    if (defined $self->_getByFieldName( 'countryCode' )) {
        my $countryName = $self->_getByFieldName( 'countryCode' );
        my $country = Common::Country->Get( $countryName );
        if ($country) {
            return $country->alpha2();
        } else {
            return $countryName;
        }                  
    } else {
        return 'US';
    }
}

sub isrc {
    my $self = shift;
    
    my $productTypeCode = $self->_getByFieldName( 'productType' );
    my $productCode = $self->_getByFieldName( 'clientProductID' );

    if ( $productTypeCode =~ /isrc/i )
    {
        return Common::Util::normalize_isrc($productCode);
    }  
}

sub albumName {
    my $self = shift;
    my $productTypeCode = $self->_getByFieldName( 'productType' );
    my $name = $self->_getByFieldName( 'albumName' );
    if ( $productTypeCode =~ /upc/i )
    {    
        return $name;
    } elsif ($productTypeCode !~ /isrc/i) {
        return $self->handleError( "Unknown product type code: $productTypeCode", RPS::DB::Item::SaleImportError::kErrorNonqualifying );   
    }
}

sub trackName {
    my $self = shift;
    my $productTypeCode = $self->_getByFieldName( 'productType' );
    my $name = $self->_getByFieldName( 'trackName' );
    if ( $productTypeCode =~ /isrc/i )
    {    
        return $name;
    }
}

sub serviceID {
    my $self = shift;
    my $service = $self->_getByFieldName( 'serviceID' ) || return;
    my $serviceID = $self->getServiceID( $service ) || $RPS::Import::ServiceMap::SERVICE_ALIASES{ lc $service };
    
    return $serviceID if( $serviceID );
    
    # Let's keep trying.
    # Trying to get the Korean names to match up...
    my $serviceCopy = $service;
    $serviceCopy =~ s/(.|\n)/sprintf("%02lx", ord $1)/eg;  
    $serviceID = $RPS::Import::ServiceMap::SERVICE_ALIASES{ lc $serviceCopy };   
                    
    return $serviceID if( $serviceID );              
    
    if ( $service =~ /[[:^ascii:]]/ ) {
        # Case 15436 - defaulting service names with incompatible characters to ADA
        return Client::Service::DSP_ADA;
    }             
                      
    return $self->handleError("Unknown service: $service", RPS::DB::Item::SaleImportError::kErrorService);
}


# in case price is zero and units are negative, Perl accomodates a -0 value,
# but the price validitor doesn't like that format. So if price is a negative
# zero, skip return 0;
sub unitPrice {
    my $self = shift;
    return 0 if( $self->price == 0 );
    return $self->SUPER::unitPrice();
}


sub units {
    my $self = shift;
    my $units = $self->SUPER::units();
    $units =~ s/,//g;
    
    my $price = $self->SUPER::price();

    # We used to error out if negative units were detected with positive revenue, but now
    # we'll follow the sign of the revenue to determine the sign of the units (FB15168).
    #
    if( $price && $units )
    {
        if( $price < 0 )
        {
            $units = 0 - $units if( $units > 0 ); # price is negative, force negative units
        }
        else
        {
            $units = abs($units) if( $units < 0 ); # price is positive, force positive units
        }
    }


    if ($price < 0 && $units > 0)
    {
        $units *= -1;
    }

    return $units;
}

sub free {
    my $self = shift;
    my $price = $self->_getByFieldName( 'price' );
    return ( $price == 0 ) ? 1 : 0;
}


sub formatType {
    my $self = shift;
    my $mediaCode = $self->_getByFieldName( 'formatType' );

    if ( $mediaCode ) {
        my $formatType  = $mediaCodeMap{ lc $mediaCode }->{ format_type };

        if ($formatType)
        {               
            return $formatType;
        } else {
            return $mediaCode;
        }
    }
}

sub productType           {
    my $self = shift;
    my $mediaCode   = $self->_getByFieldName( 'formatType' );

    if ( $mediaCode ) 
    {
        my $productType;
        my $productCode = $self->_getByFieldName( 'clientProductID' );
  
        if ( $productCode =~ /upc/i && $mediaCode =~ /^evd$/i) 
        {        
            $productType = RPS::File::Sale::TYPE_ALBUM; # FB16678
        } 
        else 
        {
            $productType  = $mediaCodeMap{ lc $mediaCode }->{ product_type };
        }

        if ($productType)
        {               
            return $productType;
        } else {
            return $mediaCode;
        }
    }
}

sub mediaType           {
    my $self = shift;
    my $mediaCode   = $self->_getByFieldName( 'formatType' );

    if ( $mediaCode ) {
        my $mediaType  = $mediaCodeMap{ lc $mediaCode }->{ media_type };

        if ($mediaType)
        {               
            return $mediaType
        } else {
            return $mediaCode;
        }
    }
}

sub _normalizeSheetName {
    my $self = shift;
    my $sname = shift;
    my $name;

    $name = $sname;
    if ( $sname =~ /^d-downloads$/i )
    {
        $name = "digital";
    }
    elsif ( $sname =~ /^d-streams$/i )
    {
        $name = "streams";
    }
    elsif ( $sname =~ /^d-wireless$/i )
    {
        $name = "wireless";
    }
    elsif ( $sname =~ /^d-intl$/i )
    {
        $name = "wmi";
    }
    return $name;
}

sub _getDates
{
    my ($self, %args) = @_;
    my $date = $args{date_begin};
    
    my ($month,$year,$dateBegin,$dateEnd);
    if($date =~ /through (\w*) (\d{4})/) {
        $year = $2;
    } elsif( $date =~ /(\w*) (\d{4})/ ) {
        $year = $2;
    }
    $month = "01" if($date =~ /jan/i);
    $month = "02" if($date =~ /feb/i);
    $month = "03" if($date =~ /mar/i);
    $month = "04" if($date =~ /apr/i);
    $month = "05" if($date =~ /may/i);
    $month = "06" if($date =~ /jun/i);
    $month = "07" if($date =~ /jul/i);
    $month = "08" if($date =~ /aug/i);
    $month = "09" if($date =~ /sep/i);
    $month = "10" if($date =~ /oct/i);
    $month = "11" if($date =~ /nov/i);
    $month = "12" if($date =~ /dec/i);
    if($month ne "" && $year ne "") {
        $dateBegin = $year."-".$month."-01";
        $dateEnd = $year."-".$month."-".Days_in_Month($year,$month);
        return ($dateBegin, $dateEnd);
    }
    return undef;
}

sub _isValidSaleRecord 
{
    my $self = shift;
    my $dateBegin = $self->_getByFieldName( 'dateBegin' );

    return undef if ( $dateBegin =~ /^TOTAL$/i);

    my $units = $self->SUPER::units();   
    my $price = $self->SUPER::price();    
    
    return undef if (!$units && !$price && !$dateBegin);
    
    return $self->SUPER::_isValidSaleRecord();
}



## MapFace Stuff

sub _mapFaceServiceID {
	return ('serviceID');
}

sub _mapFaceCountryCode {
	return ('countryCode');
}

sub _mapFaceProductType {
	return ('formatType');
}

sub _mapFaceFormatType {
	return ('formatType');
}

sub _mapFaceMediaType {
	return ('formatType');
}


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