package RPS::Import::Universal::v73;

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 qw/RPS::Import::MapFaceBase RPS::Import::ImporterMixed/;

sub physical { 2 }

sub _fieldMapExtended {
    {
        mixed => {
            option1 => {
                serviceID      => 'D',
                countryCode    => 'B',
                productType    => 'I',
                formatType     => 'J',
                upc            => 'E',
                albumName      => 'F',
                isrc           => 'E',
                trackName      => 'F',
                units          => 'M',
                wholesalePrice => 'N',
                returns        => 'M',
                returnsRevenue => 'R',
                totalRevenue   => 'R',
                price          => 'R',
                mediaType      => 'I',
            },
        },
    };
}

sub _unverifiedFieldMapExtended {
    {
        mixed => {
            option1 => {
                _datePeriod => 'C',
                _netUnits   => 'M',
            },
        }
    };
}

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

sub currencyCode { 'GBP' }
sub priceLevel   { RPS::File::Sale::PLEVEL_UNKNOWN }
sub channel      { RPS::File::Sale::CHANNEL_RETAIL }

sub serviceID {
    my $self = shift;

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

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

    return Client::Service::DSP_UNKNOWN if $service =~ /^Digital Sales$/i;

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

sub countryCode {
    my $self = shift;

    my $name = $self->_getByFieldName('countryCode') || '';

    return 'MK' if $name =~ /^NORTH MACEDONIA$/i;

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

    $self->fail( "Unable to determine country from '$name'." );
}

sub saleDates {
    my $self = shift;

    # 201710-201712
    my $period = $self->_getByFieldName('_datePeriod') || '';
    my @dates = $period =~ /(\d{4})(\d{1,2})/g;
    $self->fail( "Unable to determine date from '$period'." ) unless @dates == 4;

    return $self->_getDates(
        date_begin => sprintf( "%04d-%02d-%02d", @dates[0 .. 1], 1 ),
        date_end   => sprintf( "%04d-%02d-%02d", @dates[2 .. 3], Days_in_Month( @dates[2 .. 3] ) ),
    );
}

sub productType {
    my $self = shift;

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

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

    # digital
    return RPS::File::Sale::TYPE_TRACK if $type =~ /^(?:Audio Track|E-Single)$/i;
    return RPS::File::Sale::TYPE_ALBUM if $type =~ /^E-Album$/i;

    $self->fail( "Unable to determine product_type from: '$type'." );
}

my %formatMap = (
    'digital allocations (download)'  => RPS::File::Sale::FORMAT_DOWNLOAD,
    'permanent download'              => RPS::File::Sale::FORMAT_DOWNLOAD,
    'timed out download'              => RPS::File::Sale::FORMAT_DOWNLOAD,
    'video tone'                      => RPS::File::Sale::FORMAT_DOWNLOAD,
    'subscription download'           => RPS::File::Sale::FORMAT_DOWNLOAD,
    'ad funded streaming'             => RPS::File::Sale::FORMAT_STREAM,
    'digital allocations (streaming)' => RPS::File::Sale::FORMAT_STREAM,
    'subscription streaming'          => RPS::File::Sale::FORMAT_STREAM,
    'cloud service'                   => RPS::File::Sale::FORMAT_STREAM,
    'allocation (streaming)'          => RPS::File::Sale::FORMAT_STREAM,
    'ad-funded streaming'             => RPS::File::Sale::FORMAT_STREAM,
    'ugc ad funded'                   => RPS::File::Sale::FORMAT_STREAM,
    'ugc subscription'                => RPS::File::Sale::FORMAT_STREAM,
    'mobile master tone'              => RPS::File::Sale::FORMAT_TETHERED,
    'ringback tone'                   => RPS::File::Sale::FORMAT_TETHERED,
    'timed-out download'              => RPS::File::Sale::FORMAT_TETHERED,
    'master tone'                     => RPS::File::Sale::FORMAT_TETHERED,
    'synchronisation fees'            => 'ERROR',
    'third party'                     => 'ERROR',
    'clip income'                     => RPS::File::Sale::FORMAT_PERFORMANCE,
    'broadcasting'                    => RPS::File::Sale::FORMAT_PERFORMANCE,
);

sub formatType {
    my $self = shift;

    my $type = lc( $self->_getByFieldName('formatType') || '' );
    if ( exists $formatMap{$type} && $formatMap{$type} ne 'ERROR' ) {
        return $formatMap{$type};
    }

    $self->fail( "Unable to determine format_type from: $type." );
}

sub upc {
    my $self = shift;

    my $upc = $self->_getByFieldName('upc') || '';
    if ( $self->productType eq RPS::File::Sale::TYPE_ALBUM || !$self->isDigitalProduct( $self->productType ) ) {
        return $upc;
    }

    return;
}

sub albumName {
    my $self = shift;

    my $albumName = $self->_getByFieldName('albumName') || '';
    if ( $self->productType eq RPS::File::Sale::TYPE_ALBUM || !$self->isDigitalProduct( $self->productType ) ) {
        return $albumName;
    }

    return;
}

sub isrc {
    my $self = shift;

    my $isrc = $self->_getByFieldName('isrc') || '';
    return unless $self->productType eq RPS::File::Sale::TYPE_TRACK;

    return $isrc;
}

sub trackName {
    my $self = shift;

    my $trackName = $self->_getByFieldName('trackName') || '';
    return unless $self->productType eq RPS::File::Sale::TYPE_TRACK;

    return $trackName;
}

sub mediaType {
    my $self = shift;

    my $type = $self->_getByFieldName('mediaType') || '';
    if ( $type =~ /^(?:Audio Track|E-Album|E-Single|CD|LP)$/i ) {
        return RPS::DB::Item::MediaType::kMediaTypeAudio;
    }

    $self->fail( "Unable to determine media_type from: $type." );
}

# 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') )
    && $_[0]->netUnits
}


sub _mapFaceServiceID   { 'serviceID' }
sub _mapFaceCountryCode { }
sub _mapFaceProductType { }
sub _mapFaceFormatType  { }
sub _mapFaceMediaType   { }


1;
