package RPS::Import::Sony::v42;

use strict;
use warnings;
use utf8;
use charnames qw(:full);

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

use parent 'RPS::Import::ImporterMixed';

sub physical { 2 }

sub _fieldMapExtended {
    {
        mixed => {
            option1 => {
                serviceID    => 'N',
                countryCode  => 'I',
                artistName   => 'E',
                upc          => 'C',
                albumName    => 'D',
                trackName    => 'D',
                units        => 'AC',
                priceLevel   => 'O',
                currencyCode => 'A5',
                totalRevenue => 'AE',
                price        => 'AE',
                mediaType    => 'J',
            },
         },
    };
}

sub _unverifiedFieldMapExtended {
    {
        mixed => {
            option1 => {
                _period              => 'AF',
                _productTypePhys     => 'J',
                _productTypeDig      => 'K',
                _distributionManner  => 'L',
                _distributionChannel => 'M',
                _netUnits            => 'AC',
            }
        }
    }
};

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

# channel => manner => format
my %formatMap = (
    'breakage'                        => {
        'breakage'                                       => RPS::File::Sale::FORMAT_STREAM,
        'digital breakage - conditional download'        => RPS::File::Sale::FORMAT_STREAM,
        'digital breakage - mobile'                      => RPS::File::Sale::FORMAT_STREAM,
        'digital breakage - meta'                        => "Error: License income",
        'digital breakage - online'                      => RPS::File::Sale::FORMAT_STREAM,
        'digital breakage - subscription'                => RPS::File::Sale::FORMAT_STREAM,
        'digital breakage ad supported streaming'        => RPS::File::Sale::FORMAT_STREAM,
        'digital breakage paid subscription streaming'   => RPS::File::Sale::FORMAT_STREAM,
        'digital settlement - conditional download'      => RPS::File::Sale::FORMAT_STREAM,
        'digital settlement paid subscription streaming' => RPS::File::Sale::FORMAT_STREAM,
        'digital settlement - online download'           => RPS::File::Sale::FORMAT_STREAM,
        'digital settlement - ad supported streaming'    => RPS::File::Sale::FORMAT_STREAM,
        'digital settlement - webcast'                   => RPS::File::Sale::FORMAT_STREAM,
    },
    'download'                        => {
        'download'                                       => RPS::File::Sale::FORMAT_DOWNLOAD,
        'digital custom ringtones'                       => RPS::File::Sale::FORMAT_RINGTONE,
    },
    'other digital'                   => {
        'digital locker streams'                         => RPS::File::Sale::FORMAT_STREAM,
        'digital paid subscription streaming'            => RPS::File::Sale::FORMAT_STREAM,
        'digital locker downloads'                       => RPS::File::Sale::FORMAT_DOWNLOAD,
        'digital - subscription'                         => RPS::File::Sale::FORMAT_DOWNLOAD,
        'digital subscription permanant download'        => RPS::File::Sale::FORMAT_DOWNLOAD,
        'digital conditional download'                   => RPS::File::Sale::FORMAT_TETHERED,
        'digital custom ringtones'                       => RPS::File::Sale::FORMAT_RINGTONE,
        'digital ephemeral'                              => RPS::File::Sale::FORMAT_EPHEMERAL,
        'ephemeral'                                      => RPS::File::Sale::FORMAT_EPHEMERAL,
        'meta'                                           => "Error: License income",
    },
    'digital other'                   => {
        'digital custom ringtones'                       => RPS::File::Sale::FORMAT_RINGTONE,
    },
    'perm. downloads - albums'        => {
        'digital - online download'                      => RPS::File::Sale::FORMAT_DOWNLOAD,
        'digital custom ringtones'                       => RPS::File::Sale::FORMAT_RINGTONE,
        'digital subscription permanant download'        => RPS::File::Sale::FORMAT_DOWNLOAD,
        'd2c digital download'                           => RPS::File::Sale::FORMAT_DOWNLOAD,
    },
    'perm. downloads - tracks'        => {
        'digital - online download'                      => RPS::File::Sale::FORMAT_DOWNLOAD,
        'digital subscription permanant download'        => RPS::File::Sale::FORMAT_DOWNLOAD,
        'd2c digital download'                           => RPS::File::Sale::FORMAT_DOWNLOAD,
    },
    'physical'                        => {
        'physical'                                       => RPS::File::Sale::TYPE_PHYSICAL,
    },
    'physical - albums'               => {
        'regular trade'                                  => RPS::File::Sale::TYPE_PHYSICAL,
    },
    'streaming - ad supported'        => {
        'digital - subscription'                         => RPS::File::Sale::FORMAT_STREAM,
        'digital ad supported streaming'                 => RPS::File::Sale::FORMAT_STREAM,
    },
    'streaming'                       => {
        'stream'                                         => RPS::File::Sale::FORMAT_STREAM,
    },
    'streaming - subscription'        => {
        'digital paid subscription streaming'            => RPS::File::Sale::FORMAT_STREAM,
    },
    'synch licensing/ancillary/other' => {
        '3rd'                                            => "Error: License income",
    },
    'equity gain' => {
        'equitygn'                                       => RPS::File::Sale::FORMAT_STREAM,
        'equity'                                         => RPS::File::Sale::FORMAT_STREAM,
    },
);

sub saleDates {
    my $self = shift;

    # YYYY H[\d]
    my $period = $self->_getByFieldName('_period') || '';
    if ( $period =~ /^(\d{4})\s+H([1|2])$/i ) {
        return $2 == 1
            ? ( sprintf("%04d-%02d-%02d", $1, 1, 1), sprintf("%04d-%02d-%02d", $1, 6, 30) )
            : ( sprintf("%04d-%02d-%02d", $1, 7, 1), sprintf("%04d-%02d-%02d", $1, 12, 31) )
    }

    return $self->fail("Unable to determine date from: '$period'." );
}

sub serviceID {
    my $self = shift;

    my $service = lc( $self->_getByFieldName('serviceID') || '' );
    return Client::Service::DSP_SONY      if $service =~ /^(?:Not Avail|prx5|psb9)$/i;
    return Client::Service::DSP_MEO_MUSIC if $service =~ /^meo\s/i;
    return Client::Service::DSP_KUACK     if $service =~ /^pow0_kuack media group per/i;

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

    $self->fail( "Unknown service: '$service'." );
}

sub productType {
    my $self = shift;

    # physical
    my $typePhys            = $self->_getByFieldName('_productTypePhys')     || '';
    my $distributionManner  = $self->_getByFieldName('_distributionManner')  || '';
    my $distributionChannel = $self->_getByFieldName('_distributionChannel') || '';
    if (   $typePhys =~ /^(?:CD-LP|CD Longplay)$/i
        && $distributionManner =~ /^Regular Trade$/i
        && $distributionChannel =~ /^(?:Physical(?: \- Albums|Physical)?)$/i
    ) {
        return RPS::File::Sale::TYPE_CD;
    } elsif ( $typePhys =~ /^(?:CD-LP|V-LP)$/i && $distributionManner =~ /^3RD$/i && $distributionChannel =~ /^Synch Licensing\/Ancillary\/Other$/i ) {
         $self->fail( "Unknown product type: license income." );
    }

    # digital
    my $typeDig = $self->_getByFieldName('_productTypeDig') || '';
    my $productType;
    if ( $typeDig =~ /^(?:Track|Other)$/i ) {
        $productType =  RPS::File::Sale::TYPE_TRACK if $typePhys =~ /^(?:AudBndle|AudTrack|Ringtone|MSTR|RBT|Ringback|Digital Audio (?:Track|Longplay)|DAB)$/i;
    } elsif ( $typeDig =~ /^(?:Album)$/i ) {
        $productType = RPS::File::Sale::TYPE_ALBUM if $typePhys =~ /^(?:Audio LP|Digital Audio Longplay)$/i;
    }

    return $productType
        ? $productType
        : $self->fail( "Unknown product type: '$typePhys <=> $typeDig'." );
}

sub formatType {
    my $self = shift;

    my $channel = lc( $self->_getByFieldName('_distributionChannel') || '' );
    my $manner  = lc( $self->_getByFieldName('_distributionManner')  || '' );

    my $service = $self->_getByFieldName('serviceID') || '';
    return RPS::File::Sale::FORMAT_PERFORMANCE if $service =~ /^SoundExchange$/i;

    if ( exists $formatMap{$channel} && exists $formatMap{$channel}{$manner} ) {
        $self->fail( $formatMap{$channel}{$manner} ) if $formatMap{$channel}{$manner} =~ /^Error/;
        return $formatMap{$channel}{$manner};
    }

    $self->fail( "Unknown format type: '$channel <=> $manner'." );
}

sub albumName {
    my $self = shift;

    return !$self->isDigitalProduct( $self->productType ) || $self->productType eq RPS::File::Sale::TYPE_ALBUM
        ? $self->_getByFieldName('albumName')
        : undef;
}

sub trackName {
    my $self = shift;

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

sub channel { RPS::File::Sale::CHANNEL_RETAIL }

sub priceLevel {
    my $self = shift;

    my $level = $self->_getByFieldName('priceLevel') || '';
    return RPS::File::Sale::PLEVEL_FULL   if $level =~ /^Full$/i;
    return RPS::File::Sale::PLEVEL_MID    if $level =~ /^Mid$/i;
    return RPS::File::Sale::PLEVEL_BUDGET if $level =~ /^(?:Budget|Bud)$/i;

    return $level;
}

sub currencyCode {
    my $self = shift;

    return $self->{_currency_code} if $self->{_currency_code};

    my $text = $self->_getByFieldName('currencyCode') || '';
    if ( my ($sign) = $text =~ /(\p{Sc})/ ) {
        return $self->{_currency_code} = 'USD' if $sign && $sign =~ /\N{DOLLAR SIGN}/;
        return $self->{_currency_code} = 'EUR' if $sign && $sign =~ /\N{EURO SIGN}/;
        return $self->{_currency_code} = 'GBP' if $sign && $sign =~ /\N{POUND SIGN}/;
    }

    $self->fail( "Unknown currency code." );
}

sub countryCode {
    my $self = shift;

    # if countryCode is blank, default to US
    my $name = $self->_getByFieldName('countryCode');
    $name = 'SVK' if $name =~ /^Slovakia/i;
    $name = 'DOM' if $name =~ /^Dominican.*/i;
    $name = 'CIV' if $name =~ /^Ivory Coast/i;
    $name = 'VGB' if $name =~ /^Virgin Islands \(Brit\.\)$/i;
    $name = 'COG' if $name =~ /^Congo Rep.*/i;
    $name = 'COD' if $name =~ /^DR Congo \(Zaire\)?$/i;
    $name = 'KGZ' if $name =~ /^Kyrgyztan/i;
    $name = 'BRN' if $name =~ /^Brunei Darussal$/i;
    $name = 'KNA' if $name =~ /^St\. Kitts\s?&\s?Nevis/i;
    $name = 'ATG' if $name =~ /^Antigua & Barbu.*/i;
    $name = 'LCA' if $name =~ /^St\. Lucia/i;
    $name = 'KOR' if $name =~ /^Rep.?ublic Korea/i;
    $name = 'BIH' if $name =~ /^Bosnia-Herzego\.$/i;
    $name = 'FLK' if $name =~ /^Falkland Island$/i;
    $name = 'LAO' if $name =~ /^Laos$/i;
    $name = 'GNQ' if $name =~ /^Equat\. Guinea/i;
    $name = 'PNG' if $name =~ /^Papua NewGuinea$/i;
    $name = 'STP' if $name =~ /^Sao Tom\x{e9} & Prin$/i;
    $name = 'VCT' if $name =~ /^St\. Vincent&Gre$/i;
    $name = 'CAF' if $name =~ /^African Republ\.$/i;
    $name = 'MMR' if $name =~ /^Myanmar \(Burma\)$/i;
    $name = 'VIR' if $name =~ /^Virgin Islands \(USA\)$/i;
    $name = 'WLF' if $name =~ /^Wallis and Futu$/i;
    $name = 'SPM' if $name =~ /^St\. Pierre&Miqu$/i;
    $name = 'PLW' if $name =~ /^Belau \(Palau\)$/i;
    $name = 'MYT' if $name =~ /^Mahore\/Mayotte$/i;
    $name = 'FSM' if $name =~ /^Micronesia$/i;

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

    $self->fail( "Unknown country code '$name'." );
}

sub mediaType { RPS::DB::Item::MediaType::kMediaTypeAudio }

# 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('units') || $_[0]->_getByFieldName('price');
}

1;
