package RPS::Import::AbsoluteDistribution::v1;

use strict;
use warnings;

use lib '/app/tools/common/lib';
use Common::Assert;
use Common::UTF8;

use lib '/app/tools/rps/lib';
use RPS::Import::ServiceMap;
use base qw/RPS::Import::MapFaceBase RPS::Import::Importer/;

sub _fieldMap {
    my $self = shift;

    my %map = (
        1 => {
            labelName        => 'B',
            serviceID        => 'H',
            dateBegin        => 'G',
            productType      => 'I',
            formatType       => 'O',
            serviceProductID => 'M',
            clientProductID  => 'M',
            upc              => 'L',
            isrc             => 'K',
            trackName        => 'E',
            albumName        => 'F',
            price            => 'W',
            units            => 'T',
            countryCode      => 'J',
        },
        2 => {
            labelName        => 'B',
            serviceID        => 'H',
            dateBegin        => 'G',
            productType      => 'I',
            formatType       => 'O',
            serviceProductID => 'M',
            clientProductID  => 'M',
            upc              => 'L',
            isrc             => 'K',
            trackName        => 'E',
            albumName        => 'F',
            price            => 'Y',
            units            => 'V',
            countryCode      => 'J',
        },
    );

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

sub _unverifiedFieldMap {
    my $self = shift;

    my %map = (
        1 => {
            trackArtist => 'C',
            albumArtist => 'D',
        },
        2 => {
            trackArtist => 'C',
            albumArtist => 'D',
        },
    );

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

sub _headerIdentifier { ( dateBegin => 'strMonthSold' ) }

sub currencyCode { 'GBP' }

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

    $self->fail("Service name not defined") unless ($service);

    return Client::Service::DSP_GOOGLE         if $service =~ /^Google\s?Play/i;
    return Client::Service::DSP_BOOMPLAY_MUSIC if $service =~ /^Boomplay/i;
    return Client::Service::DSP_QOBUZ          if $service =~ /^Qobuz/i;
    return Client::Service::DSP_SOUNDCLOUD     if $service =~ /^SoundCloud/i;
    return Client::Service::DSP_APPLE_MUSIC    if $service =~ /^Apple Beats/i;
    return Client::Service::DSP_DOUYIN         if $service =~ /^Douyin/i;
    return Client::Service::DSP_YOUTUBE        if $service =~ /^YouTube/i;
    return Client::Service::DSP_FACEBOOK       if $service =~ /^Facebook/i;
    return Client::Service::DSP_TIDAL          if $service =~ /^TIDAL Rebate/i;
    return Client::Service::DSP_META           if $service =~ /^Meta/i;
    return Client::Service::DSP_TIKTOK         if $service =~ /^TikTok/i;

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

    return $serviceID if $serviceID;

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

sub artistName {
    my $self = shift;
    if ( $self->productType eq RPS::File::Sale::TYPE_TRACK ) {
        return $self->_getByFieldName('trackArtist');
    } elsif ( $self->productType eq RPS::File::Sale::TYPE_ALBUM ) {
        return $self->_getByFieldName('albumArtist');
    }
}

sub trackName {
    my $self = shift;
    return ( $self->productType eq RPS::File::Sale::TYPE_TRACK ) ? $self->_getByFieldName('trackName') : undef;
}

sub isrc {
    my $self = shift;
    return ( $self->productType eq RPS::File::Sale::TYPE_TRACK ) ? $self->_getByFieldName('isrc') : undef;
}

sub countryCode {
    my $self  = shift;

    my $cname = $self->_getByFieldName('countryCode') || '';
    return 'KR' if $cname =~ /KO/i;
    return 'US' if $cname =~ /OT/i;

    unless ($cname) {
        # Country not specified; return US if this is YouTube or Amazon Ad Supported
        my $service = $self->_getByFieldName('serviceID');
        return 'US' if ( $service =~ /youtube/i );
        return 'US' if ( $service =~ /Amazon Ad Supported/i );
    } else {
        my $o = Common::Country->Get($cname);
        return $o->alpha2() if $o;
    }

    $self->handleError( "Unknown country code: '$cname'", RPS::DB::Item::SaleImportError::kErrorCountry );

    return $cname;
}

sub saleDates {
    my $self = shift;

    my $dt = $self->_getByFieldName('dateBegin') || '';

    # 31-12-2019
    if ( $dt =~ /^(\d{1,2})[\/-](\d{1,2})[\/-](\d{4})$/ ) {
        $dt = sprintf  "%04d-%02d-%02d", $3, $2, $1;
        return $self->_getDates( date_begin => $dt );
    }
    # 2019-12-31
    if ( $dt =~ /^\d{4}-\d{2}-\d{2}$/ ) {
        return $self->_getDates( date_begin => $dt );
    }

   $self->fail("Unable to determine dateBegin from: '$dt'");
}

sub productType {
    my $self = shift;

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

    if (   $type =~ /^Album.Plus \(DRM-free\)$/i
        || $type =~ /^ALBUM$/i
        || $type =~ /^(?:Bundle|I)$/i ) {
        return RPS::File::Sale::TYPE_ALBUM;
    } elsif ( $type =~ /^Song.Match Download.Plus \(DRM-free\)$/i
        || $type =~ /^Song.Match Download.Standard \(DRM-protected\)$/i
        || $type =~ /^Music video.Match Download.Plus \(DRM-free\)$/i
        || $type =~ /^Music video.Match Download.Standard \(DRM-/i
        || $type =~ /^Music video.Plus \(DRM-free\)$/i
        || $type =~ /^Song.Plus \(DRM-free\)$/i
        || $type =~ /^(?:H|J|S|V)3|H$/i
        || $type =~ /^(?:track|J)$/i ) {
        return RPS::File::Sale::TYPE_TRACK;
    }

    $self->fail("Unknown product type: '$type'");

}

sub formatType {
    my $self = shift;

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

    # RSD-8961
    if ($type =~ /^product$/i) {
        return RPS::File::Sale::FORMAT_STREAM if $serviceID =~ /(?:Meta-Rev Share Video|Snap|Meta-Dividend Payment)/i;
    }

    # RSD-5939 && RSD-8713
    if ( $serviceID =~ /^Pandora \(Combined Subscription\-T\d\)$/i ) {
        return RPS::File::Sale::FORMAT_STREAM;
    } elsif ( $serviceID =~ /^Pandora( \(Ad Supported\-T\d\))?$/i ) {
        return RPS::File::Sale::FORMAT_PERFORMANCE;
    } elsif ( $serviceID =~ /^Boomplay/i && $type =~ /^Transaction Type$/i ) {
        return RPS::File::Sale::FORMAT_STREAM;
    } elsif ( $serviceID =~ /^Facebook - [AU]/i && $type =~ /^Product$/i ) {
        return RPS::File::Sale::FORMAT_STREAM;
    } elsif ( $serviceID =~ /(?:Meta|TikTok)/i && $type =~ /^Product$/i ) {
        return RPS::File::Sale::FORMAT_STREAM;
    }

    if ( $type =~ /^(audio|itunes) match$/i
        || $type =~ /^SFTP Upload$/i
        || $type =~ /^Streaming$/i
        || $type =~ /^standard.unlimited.streaming$/i
        || $type =~ /^premium.unlimited.streaming(?:.12m)?$/i
        || $type =~ /^Type_Of_Play$/i
        || $type =~ /^Audio Stream$/i
        || $type =~ /^ad-supported-semi-interactive$/i
        || $type =~ /^Renewal \(RM2\)$/i
        || $type =~ /^stream$/i ) {
        return RPS::File::Sale::FORMAT_STREAM;
    } elsif ( $type =~ /^download(?: \(RM3\))?$/i ) {
        return RPS::File::Sale::FORMAT_DOWNLOAD;
    } elsif ( $type =~ /^Tethered download$/i ) {
        return RPS::File::Sale::FORMAT_TETHERED;
    }

    # RSD-5656
    if ( !$type && $self->serviceID eq Client::Service::DSP_HKBN_MUSICONE ) {
        return RPS::File::Sale::FORMAT_STREAM;
    }

    $self->fail("Could not parse format type from '$type'");
}

sub mediaType {
    my $self = shift;

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

    if ( $type =~ /^(audio|itunes) match$/i
        || $type =~ /^download$/i
        || $type =~ /^Transaction Type$/i
        || $type =~ /^Streaming$/i
        || $type =~ /^standard.unlimited.streaming$/i
        || $type =~ /^premium.unlimited.streaming(?:.12m)?$/i
        || $type =~ /^Type_Of_Play$/i
        || $type =~ /^Tethered download$/i
        || $type =~ /^Audio Stream$/i
        || $type =~ /^ad-supported-semi-interactive$/i
        || $type =~ /^Renewal \(RM2\)$/i
        || $type =~ /^Download \(RM3\)$/i
        || $type =~ /^stream$/i ) {
        return RPS::DB::Item::MediaType::kMediaTypeAudio;
    } elsif ( $type =~ /^SFTP Upload$/i ) {
        return RPS::DB::Item::MediaType::kMediaTypeVideo;
    }

    # RSD-8961
    if ($type =~ /^product$/i) {
        return RPS::DB::Item::MediaType::kMediaTypeVideo if $serviceID =~ /Meta-Rev Share Video/i;
        return RPS::DB::Item::MediaType::kMediaTypeAudio if $serviceID =~ /^Facebook - (?:AL|UGC)$/i;
        return RPS::DB::Item::MediaType::kMediaTypeAudio if $serviceID =~ /(?:Snap|Meta-Incentive Pool|TikTok|Meta-Dividend Payment|Meta-Facebook)/i;
    }

    # RSD-5656 && RSD-8713
    if ( !$type && $self->serviceID eq Client::Service::DSP_HKBN_MUSICONE ) {
        return RPS::DB::Item::MediaType::kMediaTypeAudio;
    } elsif ( $serviceID =~ /^Facebook - [AU]/i && $type =~ /^Product$/i ) {
        return RPS::DB::Item::MediaType::kMediaTypeAudio;
    }

    $self->fail("Could not parse media type from '$type'");
}

sub price     {
    my $self = shift;

    my $price = $self->_getByFieldName('price') || 0;
    return sprintf "%.8f", abs($price);
}

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

sub _isValidSaleRecord {
    my $self = shift;

    my $labelName   = lc($self->_getByFieldName('labelName')   || '');
    my $trackArtist = lc($self->_getByFieldName('trackArtist') || '');

    return if $labelName eq 'x' && $trackArtist eq 'x';
    return if $labelName =~ /total/i || $trackArtist =~ /total/i;

    return unless $labelName && $self->price && $self->units;

    return $self->SUPER::_isValidSaleRecord();
}

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


1;
