package RPS::Import::Distrokid::v2;

use strict;
use warnings;

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

use Date::Calc qw(Days_in_Month);
use parent qw/RPS::Import::MapFaceBase RPS::Import::Importer/;

sub _headerIdentifier { isrc=> 'ISRC' }

sub _fieldMap {
    {
        serviceID    => 'C',
        countryCode  => 'L',
        dateBegin    => 'B',
        dateEnd      => 'B',
        productType  => 'K',
        formatType   => 'C',
        artistName   => 'D',
        upc          => 'H',
        albumName    => 'F',
        isrc         => 'G',
        trackName    => 'E',
        units        => 'I',
        currencyCode => 'N',
        price        => 'N',
        mediaType    => 'C',
    }
}

sub _processHeader {
    my $self   = shift;

    # looking for currency code
    my $code = $self->_getByFieldName('price') || 0;

    if ( $code =~ /^Earnings \((\w{3})\)$/i ) {
        $self->{_currencyCode} = $1;
    }
    return $self->SUPER::_processHeader(@_);
}

sub countryCode {
    my $self = shift;

    my $code = $self->_getByFieldName('countryCode') || '';
    my $country = Common::Country->Get($code);
    return $country->alpha2 if $country;

    return 'ZZ' if $code =~ /^OU$/i;

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

sub currencyCode {
    my $self = shift;
    return $self->{_currencyCode};
}

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->handleError( "Unknown service: '$service'", RPS::DB::Item::SaleImportError::kErrorService );
}

sub saleDates {
    my $self = shift;

    my $dt = $self->_getByFieldName('dateBegin') || '';
    my ($startDate, $endDate, $year, $month);

    if ( $dt =~ /^(\d{4})-(\d{1,2})$/ ) {   # YYYY-MM
        $year  = $1;
        $month = $2;
    }
    elsif ( $dt =~ /^(\d{1,2})\/\d{1,2}\/(\d{4})$/ ) { ## MM/DD/YYYY
        $month = $1;
        $year  = $2;
    }
    elsif ( $dt =~ /^(\d{4})-(\d{1,2})-\d{1,2}$/ ) { # YYYY-MM-DD
        $year  = $1;
        $month = $2;
    }
    else {
        return $self->fail( "Unknown date format: '$dt'");
    }

    $startDate = sprintf( "%04d-%02d-%02d", $year, $month, 1 );
    $endDate = sprintf( "%04d-%02d-%02d", $year, $month, Days_in_Month( $year, $month ) );

    return ( $startDate, $endDate );
}

sub productType {
    my $self = shift;

    my $type = $self->_getByFieldName('productType') || '';
    return RPS::File::Sale::TYPE_TRACK if $type =~ /^Song$/;
    return RPS::File::Sale::TYPE_ALBUM if $type =~ /^Album$/;

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

my %formatMap = (
    "amazon (downloads)" => RPS::File::Sale::FORMAT_DOWNLOAD,
    "amazon prime (streaming)" => RPS::File::Sale::FORMAT_STREAM,
    "amazon unlimited (streaming)" => RPS::File::Sale::FORMAT_STREAM,
    "apple music" => RPS::File::Sale::FORMAT_STREAM,
    "audiomack" => RPS::File::Sale::FORMAT_STREAM,
    "deezer" => RPS::File::Sale::FORMAT_STREAM,
    "iheart radio" => RPS::File::Sale::FORMAT_STREAM,
    "itunes" => RPS::File::Sale::FORMAT_STREAM,
    "itunes match" => RPS::File::Sale::FORMAT_STREAM,
    "kkbox" => RPS::File::Sale::FORMAT_STREAM,
    "lyricfind" => RPS::File::Sale::FORMAT_STREAM,
    "netease" => RPS::File::Sale::FORMAT_STREAM,
    "pandora" => RPS::File::Sale::FORMAT_STREAM,
    "resso" => RPS::File::Sale::FORMAT_STREAM,
    "snap" => RPS::File::Sale::FORMAT_STREAM,
    "spotify" => RPS::File::Sale::FORMAT_STREAM,
    "tidal" => RPS::File::Sale::FORMAT_STREAM,
    "tiktok" => RPS::File::Sale::FORMAT_STREAM,
    "youtube (ads)" => RPS::File::Sale::FORMAT_STREAM,
    "youtube (audio)" => RPS::File::Sale::FORMAT_STREAM,
    "youtube (red)" => RPS::File::Sale::FORMAT_STREAM,
    "apple beats 1 radio" => RPS::File::Sale::FORMAT_PERFORMANCE,
);

sub formatType {
    my $self = shift;

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

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

sub mediaType {
    my $self = shift;

    my $type = $self->_getByFieldName('mediaType') || '';
    return ($type =~ /video/i ? RPS::DB::Item::MediaType::kMediaTypeVideo : RPS::DB::Item::MediaType::kMediaTypeAudio);
}

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

sub _isValidSaleRecord {
    my $self = shift;

    return 1 if ($self->units || $self->price) && $self->currencyCode;
    return 0;
}

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

1;
