package RPS::Import::Sony::v39;

use strict;
use warnings;

use lib '/app/tools/rps/lib';
use RPS::Import::ServiceMap;
use Date::Calc qw(Days_in_Month Add_Delta_Days Decode_Month);

use parent 'RPS::Import::MapFaceBase';
use parent 'RPS::Import::ImporterMixed';

sub physical { 2 }

sub _fieldMapExtended {
    {
        mixed => {
            option1 => {
                labelName       => 'A3',
                serviceID       => 'AE',
                countryCode     => 'S',
                formatType      => 'T',
                artistName      => 'J',
                upc             => 'I',
                albumName       => 'K',
                isrc            => 'O',
                trackName       => 'R',
                units           => 'AB',
                channel         => 'T',
                priceLevel      => 'W',
                currencyCode    => 'E',
                wholesalePrice  => 'U',
                totalRevenue    => 'AC',
                price           => 'AC',
                mediaType       => 'N',
                productType     => 'N',
            },
         },
    };
}

sub _unverifiedFieldMapExtended {
    {
        mixed => {
            option1 => {
                _period   => 'H',
                _netUnits => 'AB',
            }
        }
    }
};

sub _headerIdentifierExtended {
    {
        mixed => {
            option1 => {
                upc => 'Product Number',
            },
        },
    };
}

my %quarters = (
    1 => { begin_month => 1,  end_month => 3  },
    2 => { begin_month => 4,  end_month => 6  },
    3 => { begin_month => 7,  end_month => 9  },
    4 => { begin_month => 10, end_month => 12 },
);

my %formatMap = (
    'digital breakage online'                        => RPS::File::Sale::FORMAT_DOWNLOAD,
    'digital downloads permanent'                    => RPS::File::Sale::FORMAT_DOWNLOAD,
    'digital ad supported streaming'                 => RPS::File::Sale::FORMAT_STREAM,
    'digital breakage conditional'                   => RPS::File::Sale::FORMAT_STREAM,
    'digital breakage metadata'                      => RPS::File::Sale::FORMAT_STREAM,
    'digital breakage streaming paid'                => RPS::File::Sale::FORMAT_STREAM,
    'digital paid subscription streaming'            => RPS::File::Sale::FORMAT_STREAM,
    'digital settlement ad supported streaming'      => RPS::File::Sale::FORMAT_STREAM,
    'digital settlement conditional'                 => RPS::File::Sale::FORMAT_STREAM,
    'digital settlement online'                      => RPS::File::Sale::FORMAT_STREAM,
    'digital settlement paid subscription streaming' => RPS::File::Sale::FORMAT_STREAM,
    'digital download conditional'                   => RPS::File::Sale::FORMAT_TETHERED,
    'digital locker downloads'                       => RPS::File::Sale::FORMAT_TETHERED,
    'digital telecommunication sale'                 => RPS::File::Sale::FORMAT_TETHERED,
    'sync'                                           => 'ERROR',
    'pp&b label and performer share'                 => RPS::File::Sale::FORMAT_PERFORMANCE,
    'digital breakage add supported streaming'       => RPS::File::Sale::FORMAT_STREAM,
    'digital conditional download'                   => RPS::File::Sale::FORMAT_TETHERED,
    'digital locker sales'                           => RPS::File::Sale::FORMAT_TETHERED,
    'digital settlement paid subscription str'       => RPS::File::Sale::FORMAT_STREAM,
    'ephemeral'                                      => RPS::File::Sale::FORMAT_EPHEMERAL,
    'digital breakage paid supported streamin'       => RPS::File::Sale::FORMAT_STREAM,
    'ppb'                                            => RPS::File::Sale::FORMAT_PERFORMANCE,
    'digital online download'                        => RPS::File::Sale::FORMAT_DOWNLOAD,
    'digital locker streams'                         => RPS::File::Sale::FORMAT_STREAM,
    'digitl mobile subscription permanent dow'       => RPS::File::Sale::FORMAT_DOWNLOAD,
    'digital breakage mobile'                        => RPS::File::Sale::FORMAT_STREAM,
    'digital telecommunications sale'                => RPS::File::Sale::FORMAT_TETHERED,
    'digital settlement ad supported streamin'       => RPS::File::Sale::FORMAT_STREAM,
    'pp&b-broadcasting _ producer - audio'           => RPS::File::Sale::FORMAT_PERFORMANCE,
    'ppb - blank media levy (pmb)'                   => RPS::File::Sale::FORMAT_PERFORMANCE,
    'pp&b - public performance - producer and'       => RPS::File::Sale::FORMAT_PERFORMANCE,
    'public performance - video - producer'          => RPS::File::Sale::FORMAT_PERFORMANCE,
    'public performance & broadcasting - prod'       => RPS::File::Sale::FORMAT_PERFORMANCE,
    'pp&b - broadcasting-producer-video'             => RPS::File::Sale::FORMAT_PERFORMANCE,
    'digital settlement conditional download'        => RPS::File::Sale::FORMAT_TETHERED,
    'equity gain'                                    => RPS::File::Sale::FORMAT_STREAM,
    'digital telecommunications sale (dor)'          => RPS::File::Sale::FORMAT_TETHERED,
);

sub labelName {
    my $self = shift;

    my $label = $self->_getByFieldName('labelName') || '';
    $label =~ s/^.*: (.+)$/$1/;

    return $label;
}

sub serviceID {
    my $self = shift;

    if ( !$self->isDigitalProduct( $self->productType ) ) {
        return Client::Service::DSP_SONY;
    }

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

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

sub countryCode {
    my $self = shift;

    my $name = $self->_getByFieldName('countryCode') || '';
    $name =~ s/^\s+|\s+$//g;

    my $oCountry = Common::Country->Get($name);
    return $oCountry->alpha2() if $oCountry ;

    $self->handleError("Unknown country: '$name'.", RPS::DB::Item::SaleImportError::kErrorCountry );
    return $name;
}

sub saleDates {
    my $self = shift;

    # YYYY Q[\d]
    my $period = $self->_getByFieldName('_period') || '';
    my ($dateBegin, $dateEnd);
    if ( $period =~ /^(\d{4})\s+Q(\d)$/i ) {
        $dateBegin = sprintf( "%04d-%02d-%02d", $1, $quarters{$2}{begin_month}, 1 );
        $dateEnd   = sprintf( "%04d-%02d-%02d", $1, $quarters{$2}{end_month}, Days_in_Month($1, $quarters{$2}{end_month}) );
    } elsif ( $period =~ /^(\d{4})\s+(\d+)$/i ) {
        $dateBegin = sprintf( "%04d-%02d-%02d", $1, $2, 1 );
        $dateEnd   = sprintf( "%04d-%02d-%02d", $1, $2, Days_in_Month($1, $2) );
    }

    return $self->_getDates( date_begin => $dateBegin, date_end => $dateEnd );

    return $self->handleError("Unable to determine date from: '$period'.", RPS::DB::Item::SaleImportError::kErrorNonqualifying );
}

sub productType {
    my $self = shift;

    my $type = $self->_getByFieldName('productType') || '';

    # physical
    return RPS::File::Sale::TYPE_CD if $type =~ /^CD Longplay$/i;

    # digital
    my $isrc = $self->_getByFieldName('isrc') || 'n/a';
    if ( $type =~ /^Digital (?:Audio|Video) Track|Mastertone$/i ) {
        return RPS::File::Sale::TYPE_TRACK;
    } elsif ( $type =~ /^Digital (?:Audio Longplay|Video Longform)$/i ) {
        # exception for 'Digital Audio Longplay'
        return RPS::File::Sale::TYPE_TRACK if $isrc !~ /^N\/A$/i && $type =~ /^Digital Audio Longplay$/i;
        return RPS::File::Sale::TYPE_ALBUM;
    } elsif ( $type =~ /^Master Use$/i ) {
        return $self->handleError( "Product type is incorrect: '$type'.", RPS::DB::Item::SaleImportError::kErrorNonqualifying );
    }

    return $self->handleError( "Product type not set: '$type'.", RPS::DB::Item::SaleImportError::kErrorProductType );
}

sub formatType {
    my $self = shift;

    my $type = lc( $self->_getByFieldName('formatType') || '' );
    if ( exists $formatMap{$type} && $formatMap{$type} ne 'ERROR' ) {
        return $formatMap{$type};
    } elsif ( exists $formatMap{$type} && $formatMap{$type} eq 'ERROR' ) {
        return $self->handleError( "Product format error: '$type'", RPS::DB::Item::SaleImportError::kErrorNonqualifying );
    }

    return $self->handleError( "Couldn't determine product format '$type': ", RPS::DB::Item::SaleImportError::kErrorFormatType );
}

sub upc {
    my $self = shift;

    return $self->_getByFieldName('upc') if !$self->isDigitalProduct( $self->productType );
}

sub channel {
    my $self = shift;

    my $channel = $self->_getByFieldName('formatType') || '';
    if ( $channel =~ /^Regular Trade$/i ) {
        return RPS::File::Sale::CHANNEL_RETAIL;
    }

    return $channel;
}


sub priceLevel {
    my $self = shift;

    my $level = $self->_getByFieldName('priceLevel') || '';
    return RPS::File::Sale::PLEVEL_FULL   if $level =~ /^Full$/i;
    return RPS::File::Sale::PLEVEL_MID    if $level =~ /^Mid$/i;
    return RPS::File::Sale::PLEVEL_BUDGET if $level =~ /^Budget$/i;

    return $level;
}

sub mediaType {
    my $self = shift;

    my $type = $self->_getByFieldName('mediaType') || '';
    if ( $type =~ /^CD Longplay|Digital Audio (?:Longplay|Track)|Mastertone$/i ) {
        return RPS::DB::Item::MediaType::kMediaTypeAudio;
    } elsif ( $type =~ /^Digital Video (?:Longform|Track)$/i ) {
        return RPS::DB::Item::MediaType::kMediaTypeVideo;
    }

    return $self->handleError( "Media type not set: '$type'", RPS::DB::Item::SaleImportError::kErrorMediaType );
}

sub isrc {
    my $self = shift;

    my $isrc = $self->_getByFieldName('isrc') || '';
    return $isrc if $isrc !~ /^N\/A$/i;
}

# digital
sub price     { abs( shift->_getByFieldName('price') || 0 ) }
sub unitPrice { abs shift->SUPER::unitPrice }
sub units {
    my $self = shift;

    my $units = $self->_getByFieldName('units') || 0;
    my $price = $self->_getByFieldName('price') || 0;

    if ( $price > 0 ) {
        $units = $units ? abs($units) : 1;
    } elsif ( $price < 0 ) {
       $units = $units ? -1 * abs($units) : -1;
    }

    return $units;
}

# physical
sub netUnits       { $_[0]->_getByFieldName('_netUnits')    || 0 }
sub totalRevenue   { $_[0]->_getByFieldName('totalRevenue') || 0 }
sub sales          { $_[0]->netUnits     > 0 ? $_[0]->netUnits         : 0 }
sub salesRevenue   { $_[0]->totalRevenue > 0 ? $_[0]->totalRevenue     : 0 }
sub returns        { $_[0]->netUnits     < 0 ? abs $_[0]->netUnits     : 0 }
sub returnsRevenue { $_[0]->totalRevenue < 0 ? abs $_[0]->totalRevenue : 0 }

sub _isValidSaleRecord {
    return $_[0]->_getByFieldName('trackName') || $_[0]->_getByFieldName('albumName');
}

# mapFace
sub _mapFaceServiceID   { 'serviceID' }
sub _mapFaceCountryCode { 'countryCode' }
sub _mapFaceProductType { 'productType' }
sub _mapFaceFormatType  { 'formatType' }
sub _mapFaceMediaType   { 'mediaType' }


1;