package RPS::Import::OrchardPub2;

use strict;

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

use lib '/app/tools/data_classes/lib';

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

sub _headerIdentifier { ( countryCode => 'Territory' ) }

sub _fieldMap {
    my $self = shift;
    
    my %fieldMap =
    (
        14 => {
            dateBegin        => 1,
            serviceID        => 2,
            countryCode      => 3,
            upc              => 5,
            serviceProductID => 4,
            clientProductID  => 6,
            labelName        => 7,
            artistName       => 8,
            albumName        => 9,
            trackName        => 10,
            isrc             => 11,
            trackNum         => 13,
            units            => 14,
            formatType       => 17,
            price            => 20,
            currencyCode     => 24,
        },
        15 => {
            dateBegin        => 1,
            serviceID        => 2,
            countryCode      => 3,
            upc              => 4,
            serviceProductID => 5,
            clientProductID  => 6,
            labelName        => 7,
            artistName       => 8,
            albumName        => 9,
            trackName        => 10,
            isrc             => 11,
            trackNum         => 13,
            units            => 14,
            formatType       => 15,
            price            => 16,
            currencyCode     => 17,
        },
        16 => {
            dateBegin        => 1,  # B
            serviceID        => 2,  # C
            countryCode      => 3,  # D
            upc              => 4,  # E
            serviceProductID => 5,  # F
            clientProductID  => 6,  # G
            labelName        => 8,  # I
            artistName       => 9,  # J
            albumName        => 10, # K
            trackName        => 11, # L
            isrc             => 12, # M
            trackNum         => 14, # O
            units            => 15, # P
            formatType       => 18, # S
            price            => 21, # V
            currencyCode     => 25, # Z
        },
        20 => {
            dateBegin        => 'B',
            serviceID        => 'C',
            countryCode      => 'D',
            upc              => 'F',
            serviceProductID => 'E',
            clientProductID  => 'G',
            labelName        => 'H',
            artistName       => 'I',
            albumName        => 'J',
            trackName        => 'K',
            isrc             => 'L',
            trackNum         => 'N',
            units            => 'O',
            formatType       => 'R',
            price            => 'U',
            currencyCode     => 'Z',
        },
        21 => {
            dateBegin        => 'B',
            serviceID        => 'C',
            countryCode      => 'D',
            clientProductID  => 'G',
            labelName        => 'I',
            artistName       => 'J',
            albumName        => 'K',
            trackName        => 'L',
            isrc             => 'M',
            trackNum         => 'O',
            units            => 'P',
            formatType       => 'S',
            price            => 'V',
            currencyCode     => 'AA',
        },
        22 => { # similar to version 20, but different revenue and upc columns
            dateBegin        => 'B',
            serviceID        => 'C',
            countryCode      => 'D',
            upc              => 'E',
            serviceProductID => 'E',
            clientProductID  => 'G',
            labelName        => 'H',
            artistName       => 'I',
            albumName        => 'J',
            trackName        => 'K',
            isrc             => 'L',
            trackNum         => 'N',
            units            => 'O',
            formatType       => 'R',
            price            => 'AA',
            currencyCode     => 'Z',
        },
    );         
        
    return $fieldMap{$self->_version()};
}

sub _unverifiedFieldMap {
    my $self = shift;
    
    my %fieldMap =
    (
        14 => {
            ringFee        => 21,
            pubFee         => 22,
            omsFee         => 23,
        },
        20 => {
            ringFee        => 'V',
            cloudFee       => 'W',
            pubFee         => 'X',
            omsFee         => 'Y',
            adjGross       => 'S',
        },
        21 => {
            manufacturersUPC => 'F',
            orchardUPC     => 'E',
            ringFee        => 'W',
            cloudFee       => 'X',
            pubFee         => 'Y',
            omsFee         => 'Z',
        },
        22 => {
# following are N/A for version 22
#            ringFee        => 'V',
#            cloudFee       => 'W',
#            pubFee         => 'X',
#            omsFee         => 'Y',
#            adjGross       => 'S',
        },
    );         
        
    return $fieldMap{$self->_version()};
}

my %formatMap = (
    'AS' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'AV' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'CL' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },    
    'DA' => {
        format_type  => RPS::File::Sale::FORMAT_DOWNLOAD,
        product_type => RPS::File::Sale::TYPE_ALBUM,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'DR' => {
        format_type  => RPS::File::Sale::FORMAT_RINGTONE,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'DT' => {
        format_type  => RPS::File::Sale::FORMAT_DOWNLOAD,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'DV' => {
        format_type  => RPS::File::Sale::FORMAT_DOWNLOAD,
        product_type => RPS::File::Sale::TYPE_ALBUM,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'NR' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'RB' => {
        format_type  => RPS::File::Sale::FORMAT_TETHERED,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'RC' => {
        format_type  => RPS::File::Sale::FORMAT_PERFORMANCE,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },    
    'S' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'TA' => {
        format_type  => RPS::File::Sale::FORMAT_TETHERED,
        product_type => RPS::File::Sale::TYPE_ALBUM,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },    
    'TD' => {
        format_type  => RPS::File::Sale::FORMAT_TETHERED,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'UA' => {
        format_type  => RPS::File::Sale::FORMAT_DOWNLOADUPGRADE,
        product_type => RPS::File::Sale::TYPE_ALBUM,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'UT' => {
        format_type  => RPS::File::Sale::FORMAT_DOWNLOADUPGRADE,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },    
    'VR' => {
        format_type  => RPS::File::Sale::FORMAT_TETHERED,
        product_type => RPS::File::Sale::TYPE_ALBUM,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
);

sub countryCode {
    my $self = shift;
    
    my $name = $self->_getByFieldName( 'countryCode' );
    my $country = Common::Country->Get( $name );
	if ($country) {
		return $country->alpha2();
	} else {
		return $name;
	}        
}

sub serviceID {
    my $self = shift;
	my $service = $self->_getByFieldName( 'serviceID' );
	
    my $serviceID = $self->getServiceID(lc ($service)) || $RPS::Import::ServiceMap::SERVICE_ALIASES{ lc $service };	

    return $serviceID if( $serviceID );

    return $self->handleError("Unknown service: $service", RPS::DB::Item::SaleImportError::kErrorService);
}

sub currencyCode {
    my $self = shift;
    
    my $code = $self->_getByFieldName( 'currencyCode' );

    if ( $code =~ /^(\w{3})/ ) {
        return $1;     
    } else {
        return $code;
    } 
}

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

    if ( $trackName !~ /^Full Album$/i ) {
        return $trackName;     
    }
}

sub upc {
    my $self = shift;
    
    my $upc;

    my $manufacturerUPC = (defined $self->_getByFieldName('manufacturerUPC'))  ? $self->_getByFieldName('manufacturerUPC') : undef;
    my $orchardUPC = (defined $self->_getByFieldName('orchardUPC'))  ? $self->_getByFieldName('orchardUPC') : undef;

    if( $manufacturerUPC || $orchardUPC )
    {
        $upc = ($manufacturerUPC) ? $manufacturerUPC : $orchardUPC;
    }
    else
    {
        $upc = $self->_getByFieldName( 'upc' );

        if ( !$upc ) {
            $upc = $self->_getByFieldName( 'serviceProductID' );       
        }
    }
    
    return $upc;
}

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

    # If the product type is track, or something other than album then let
    # the ISRC through if it looks like an ISRC (e.g., starts with a letter).
    # The 'other than album' can occur if we don't have an explicit entry
    # in the formatMap hash (in which case we'll rely on MapFace to determine
    # the product type).
    #
    return $isrc if( ( $self->productType eq RPS::File::Sale::TYPE_TRACK or
                       $self->productType ne RPS::File::Sale::TYPE_ALBUM ) &&
                     $isrc =~ /^[a-z]/i)
}

sub units {
    my $self = shift;
    
    my $units = $self->_getByFieldName( 'units' );
    $units    =~ s/\.0+$//g; # remove any trailing decimal zeroes
    $units    =~ s/,//g;
    
    my $price = $self->price;

    $units = abs($units);
    
    if ($price < 0) {
        $units *= -1;   
    }
    
    return $units;
}

sub price {
    my $self = shift;
    
    my $price = $self->_getByFieldName( 'price' );
    $price    =~ s/\$//g;
    $price    =~ s/,//g; 
    
    # If the template doesn't have the ring/cloud/pub/oms fields, then
    # default them to zero.
    #
    my $ringFee  = (defined $self->_getByFieldName( 'ringFee' ))  ? $self->_getByFieldName( 'ringFee' )  : 0;
    my $cloudFee = (defined $self->_getByFieldName( 'cloudFee' )) ? $self->_getByFieldName( 'cloudFee' ) : 0;
    my $pubFee   = (defined $self->_getByFieldName( 'pubFee' ))   ? $self->_getByFieldName( 'pubFee' )   : 0;
    my $omsFee   = (defined $self->_getByFieldName( 'omsFee' ))   ? $self->_getByFieldName( 'omsFee' )   : 0;

    # Look at the adjusted gross if no revenue reported
    #
    my $adjGross  = (defined $self->_getByFieldName( 'adjGross' )) ? $self->_getByFieldName( 'adjGross' ) : 0;
    $price = $adjGross if( !defined $price || $price == 0 );

    
    $ringFee  =~ s/\$//g;
    $cloudFee =~ s/\$//g;
    $pubFee   =~ s/\$//g;
    $omsFee   =~ s/\$//g;    
    
    $ringFee *= -1 if($ringFee<0);
    $cloudFee *= -1 if($cloudFee<0);
    $pubFee  *= -1 if($pubFee<0);
    $omsFee  *= -1 if($omsFee<0);    
    
    $price = $price - $ringFee - $cloudFee - $pubFee - $omsFee;
    
    return $price;
}

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

    my $formatType = $formatMap{ $_formatType }->{ format_type };
    
    if ($formatType) {               
        return $formatType
    } else {
        return $_formatType;
    }
}

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

    my $productType = $formatMap{ $_formatType }->{ product_type };
    
    if ($productType) {               
        return $productType
    } else {
        return $_formatType;
    }
}

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

    my $mediaType = $formatMap{ $_formatType }->{ media_type };
    
    if ($mediaType) {               
        return $mediaType
    } else {
        return $_formatType;
    }
}

sub _getDates
{   
    my $self = shift;
    my $date = $self->_getByFieldName( 'dateBegin' );
    my ($month, $year);
	my $offset = 0;

    if ( $date =~ m/^(\d+)$/ )
    {
        $date = Spreadsheet::ParseExcel::Utility::ExcelFmt( "yyyy-mm-dd", $date );
    }

    if( $date =~ /^(\d{4})-(\d{1,2})-(\d{1,2})$/ ) # YYYY-MM-DD
    {
        $month = $2;
        $year  = $1;
    }
    elsif ($date =~ m/^(\d{4})q([1234]$)/i)
    {
        $month = $2 * 3;
        $year = $1;
		$offset = 2;
    }
    elsif ($date =~ m/Q([1234])(\d\d)/i)
    {
        $month = $1 * 3;
        $year = $2 + 2000;
		$offset = 2;
    }
    elsif ($date =~ m/^(\d{4})m(\d{1,2})$/i)
    {
        $month = $2;
        $year = $1;
    }
    elsif ($date =~ m/^(\d{4})-(\d{1,2})-(\d{1,2})$/i)
    {
        $month = $2;
        $year = $1;
    }
    elsif( $date =~ m/(\w*) (\d{4})/ )
    {
        my %months = (Jan => 1, Feb => 2, Mar => 3, Apr => 4, May => 5, Jun => 6,
                      Jul => 7, Aug => 8, Sep => 9, Oct => 10, Nov => 11, Dec => 12);
        ($month, $year) = $date =~ m/(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\w* (\d{4})/i;
        $month = $months{$month};
    }
    elsif( $date =~ m/(\w*)-(\d{4})/ )
    {
        my %months = (Jan => 1, Feb => 2, Mar => 3, Apr => 4, May => 5, Jun => 6,
                      Jul => 7, Aug => 8, Sep => 9, Oct => 10, Nov => 11, Dec => 12);
        ($month, $year) = $date =~ m/(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\w*-(\d{4})/i;
        $month = $months{$month};
    }
    elsif( $date =~ m/(\w{3})-(\d{2})/ )
    {
        my %months = (Jan => 1, Feb => 2, Mar => 3, Apr => 4, May => 5, Jun => 6,
                      Jul => 7, Aug => 8, Sep => 9, Oct => 10, Nov => 11, Dec => 12);
        ($month, $year) = $date =~ m/(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\w*-(\d{2})/i;
        $month = $months{$month};
        $year += 2000;
    }


    return unless ($year && $month);
    return (
        sprintf("%04d-%02d-01", $year, $month - $offset),
		sprintf("%04d-%02d-%02d", $year, $month, Days_in_Month($year, $month))
    );
}

sub _mapFaceCompatibleVersions {
	return (14,15,16,18,20,21,22);
}

sub _mapFaceServiceID {
	return ('serviceID');
}

sub _mapFaceCountryCode {
	return ('countryCode');
}

sub _mapFaceProductType {
	return ('formatType');
}

sub _mapFaceFormatType {
	return ('formatType');
}

sub _mapFaceMediaType {
	return ('formatType');
}


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