package RPS::Import::Stem::v1;

use strict;
use warnings;

use Client::Service;
use Date::Calc qw(Add_Delta_Days Days_in_Month);

use lib '/app/tools/rps/lib';
use RPS::Import::ServiceMap;

use parent qw/RPS::Import::MapFaceBase RPS::Import::Importer/;

sub _fieldMap {
    my $self = shift;

    my %map = (
        1 => {
            serviceID   => 'S',
            countryCode => 'O',
            formatType  => 'T',
            artistName  => 'M',
            upc         => 'H',
            isrc        => 'I',
            trackName   => 'L',
            price       => 'Z',
            mediaType   => 'J',
        },
        2 => {
            serviceID   => 'T',
            countryCode => 'P',
            productType => 'I',
            formatType  => 'U',
            artistName  => 'M',
            upc         => 'H',
            isrc        => 'I',
            trackName   => 'L',
            price       => 'Y',
            mediaType   => 'J',
        },
        3 => {
            serviceID   => 'S',
            countryCode => 'O',
            productType => 'I',
            formatType  => 'T',
            artistName  => 'M',
            upc         => 'H',
            isrc        => 'I',
            trackName   => 'L',
            price       => 'X',
            mediaType   => 'J',
        }
    );

    return $map{ $self->version };
}

sub _unverifiedFieldMap {
    my $self = shift;

    my %map = (
        1 => {
            _year           => 'P',
            _month          => 'Q',
            _units_download => 'U',
            _units_views    => 'V',
        },
        2 => {
            _year           => 'Q',
            _month          => 'R',
            _units_download => 'V',
            _units_views    => 'W',
        },
        3 => {
            _year           => 'P',
            _month          => 'Q',
            _units_download => 'U',
            _units_views    => 'V',
        },
    );

    return $map{ $self->version };
}

sub _headerIdentifier { upc => 'upc' }

sub currencyCode { 'USD' }

sub serviceID {
    my $self = shift;

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

    return $self->_version == 2
        ? $self->handleError( "Unknown service: '$service'", RPS::DB::Item::SaleImportError::kErrorService )
        : $self->fail("Unable to determine service from: '$service' ");
}

sub countryCode {
    my $self = shift;

    my $code = $self->_getByFieldName('countryCode') || '';
    return 'US' if $code =~ /^(?:WW|LL)$/i;

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

    $self->_version == 2
        ? $self->handleError( "Unknown country: '$code'.", RPS::DB::Item::SaleImportError::kErrorCountry )
        : $self->fail("Unable to determine country from: '$code'");

    return $code;
}

sub saleDates {
    my $self = shift;

    my $y = $self->_getByFieldName('_year')  || 0;
    my $m = $self->_getByFieldName('_month') || 0;

    return
        sprintf( "%04d-%02d-%02d", $y, $m, 1 ),
        sprintf( "%04d-%02d-%02d", $y, $m, Days_in_Month( $y, $m ) );
}

sub productType {
    my $self = shift;

    return RPS::File::Sale::TYPE_TRACK if $self->_getByFieldName('isrc');

    $self->fail("Unable to determine product type since ISRC is empty.");
}

sub formatType {
    my $self = shift;

    my $type = $self->_getByFieldName('formatType') || '';
    return RPS::File::Sale::FORMAT_DOWNLOAD    if $type =~ /^Downloads?$/i;
    return RPS::File::Sale::FORMAT_STREAM      if $type =~ /^(?:
        Sub\ Streams |
        Ad\ Streams |
        Locker |
        Youtube\ Adjustments |
        Video\ (?:Views|Creations) |
        Streams |
        Spotify\ Discovery\ Discount |
        (?:Student|Trial)\ Streams |
        Saavn\ Merlin\ Subscription\ Streams |
        Spotify\ Discovery\ Discount
    )$/ix;
    return RPS::File::Sale::FORMAT_PERFORMANCE if $type =~ /^Web Radio$/i;

    return $self->_version == 2
        ? $self->handleError( "Unknown format_type: '$type'.", RPS::DB::Item::SaleImportError::kErrorFormatType )
        : $self->fail("Unable to determine format_type from: '$type'.");
}

sub mediaType {
    my $self = shift;

    my $type = $self->_getByFieldName('mediaType') || '';
    return RPS::DB::Item::MediaType::kMediaTypeAudio if $type =~ /^(?:sound_recording|composition)$/i;
    return RPS::DB::Item::MediaType::kMediaTypeVideo if $type =~ /^music_video$/i;

    return $self->_version == 2
        ? $self->handleError( "Unknown media_type: '$type'.", RPS::DB::Item::SaleImportError::kErrorMediaType )
        : $self->fail("Unable to determine media_type from: '$type' ");
}

sub artistName {
    my $self = shift;

    my $name = $self->_getByFieldName('artistName') || '';
    my @artists = $name =~ /primary:([^,]+)/i;
    my $artistNames = join ', ', grep {$_ !~ /^\s+$/} @artists;

    return $artistNames;
}

sub price { abs( shift->_getByFieldName('price') || 0 ) }
sub unitPrice { abs( shift->SUPER::unitPrice ) }

sub units {
    my $self = shift;

    my $price = $self->_getByFieldName('price') || 0;
    my $units_download = $self->_getByFieldName('_units_download') || 0;
    my $units_views = $self->_getByFieldName('_units_views') || 0;

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

    return $units;
}

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

1;
