package RPS::Import::Universal::v69;

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::ImporterMixed';

sub physical { 2 }

sub _fieldMapExtended {
    {
        mixed => {
            option1 => {
                serviceID      => 'G',
                countryCode    => 'F',
                formatType     => 'H',
                upc            => 'A',
                albumName      => 'B',
                isrc           => 'A',
                trackName      => 'B',
                units          => 'I',
                channel        => 'H',
                totalRevenue   => 'S',
                price          => 'S',
                mediaType      => 'C',
            },
        },
    };
}

sub _unverifiedFieldMapExtended {
    {
        mixed => {
            option1 => {
                _datePeriod   => 'E',
                _netUnits     => 'I',
                _ppd          => 'M',
                _exchangeRate => 'R',
            },
        }
    };
}

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

sub currencyCode { 'EUR' }
sub priceLevel   { RPS::File::Sale::PLEVEL_UNKNOWN }

sub serviceID {
    my $self = shift;

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

    my $service = lc( $self->_getByFieldName('serviceID') || '' );
    if ( $service =~ /universal music/i || $service =~ /digital sales/i ) {
        return Client::Service::DSP_UNIVERSAL;
    }

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

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

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 $formatType = $self->_getByFieldName('formatType') || '';
    my $mediaType  = $self->_getByFieldName('mediaType')  || '';

    # order is important
    # physical
    my $physType = $formatType . '_' . $mediaType;
    if ( $physType =~ /^(?:MAIL_D1|D2C_(?:D1|F3)|NORMAL RETAIL_(?:D1|D8|F3)|TV ADVERTISED RETAIL_D1)$/i ) {
        return RPS::File::Sale::TYPE_CD;
    } elsif ( $physType =~ /^NORMAL RETAIL_D5$/i ) {
        return RPS::File::Sale::TYPE_CD_SIN;
    } elsif ( $physType =~ /^(?:NORMAL RETAIL|MAIL|D2C)_P1$/i ) {
        return RPS::File::Sale::TYPE_DVD;
    } elsif ( $physType =~ /^(?:NORMAL RETAIL|MAIL)_(?:N8|P8)$/i ) {
        return RPS::File::Sale::TYPE_DVD_CD_SET;
    } elsif ( $physType =~ /^(?:D2C_(?:L6|M1)|NORMAL RETAIL_(?:L5|L6|M1)|TV ADVERTISED RETAIL_L6)$/i ) {
        return RPS::File::Sale::TYPE_LP;
    } elsif ( $physType =~ /^(?:NORMAL RETAIL|D2C)_S(?:5|6)$/i ) {
        return RPS::File::Sale::TYPE_LP5;
    } elsif ( $physType =~ /^NORMAL RETAIL_V1$/i ) {
        return RPS::File::Sale::TYPE_VHS;
    } elsif ( $physType =~ /^(?:NORMAL RETAIL|D2C)_R5$/i ) {
        return RPS::File::Sale::TYPE_BLURAY;
    }

    #digital
    my $digType = $mediaType . '_' . $formatType;
    if ( $digType =~ /^D|N(?:1|5|8)_(?:PERMANENT DOWNLOAD|DIGITAL ALLOCATIONS \(DOWNLOAD\))$/i ) {
        return RPS::File::Sale::TYPE_ALBUM;
    } elsif ( $mediaType =~ /^B|P(?:1|4)$/i ) {
        return RPS::File::Sale::TYPE_ALBUM;
    } elsif ( $mediaType =~ /^B2|ID|IV$/i ) {
        return RPS::File::Sale::TYPE_TRACK;
    }

    $self->fail( "Unable to determine product_type from: '$formatType' and '$mediaType'." );

}

sub formatType {
    my $self = shift;

    my $type = $self->_getByFieldName('formatType') || '';
    if ( $type =~ /^(?:DIGITAL ALLOCATIONS|PERMANENT|TIMED OUT|VIDEO) \(?DOWNLOAD|TONE\)?$/i ) {
        return RPS::File::Sale::FORMAT_DOWNLOAD;
    } elsif ( $type =~ /^(?:AD FUNDED|DIGITAL ALLOCATIONS|SUBSCRIPTION|CLOUD) \(?STREAMING|MOBILE|SERVICE\)?$/i ) {
        return RPS::File::Sale::FORMAT_STREAM;
    } elsif ( $type =~ /^UGC (?:AD FUNDED|SUBSCRIPTION)|D2C DIGITAL$/i ) {
        return RPS::File::Sale::FORMAT_STREAM;
    } elsif ( $type =~ /^(?:MOBILE MASTER|RINGBACK) TONE$/i || $type =~ /^subscription download$/i ) {
        return RPS::File::Sale::FORMAT_TETHERED;
    } elsif ( $type =~ /^(?:CLIP INCOME|BROADCASTING)$/i ) {
        return RPS::File::Sale::FORMAT_PERFORMANCE;
    }

    $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 isrc {
    my $self = shift;

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

    return $isrc;
}

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 trackName {
    my $self = shift;

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

    return $trackName;
}

sub channel {
    my $self = shift;

    my $channel = $self->_getByFieldName('channel') || '';
    if ( $channel =~ /^(?:NORMAL|TV ADVERTISED) RETAIL$/i ) {
        return RPS::File::Sale::CHANNEL_RETAIL;
    } elsif ( $channel =~ /^D2C$/i ) {
        return RPS::File::Sale::CHANNEL_DIRECT;
    } elsif ( $channel =~ /^MAIL$/i ) {
        return RPS::File::Sale::CHANNEL_MAILORDER;
    }

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

sub wholesalePrice {
    my $self = shift;

    my $ppd  = $self->_getByFieldName('_ppd')          || 0;
    my $rate = $self->_getByFieldName('_exchangeRate') || 1;

    return $ppd * $rate;
}

sub mediaType {
    my $self = shift;

    my $type = $self->_getByFieldName('mediaType') || '';
    if ( $type =~ /^(?:B(?:1|2|3)|D(?:1|5|8)|ID|L(?:5|6)|M1|N8|P8|S5|S6|F3)$/i ) {
        return RPS::DB::Item::MediaType::kMediaTypeAudio;
    } elsif ( $type =~ /^B4|IV|P1|V1|R5$/i ) {
        return RPS::DB::Item::MediaType::kMediaTypeVideo;
    }

    $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
}


1;
