package RPS::Import::IndependentDistribution::v1;

use strict;
use warnings;

use lib '/app/tools/rps/lib';
use RPS::Import::ServiceMap;
use Date::Calc qw(Days_in_Month);

use base qw(RPS::Import::MapFaceBase RPS::Import::Importer);

sub _fieldMap {
    my $self = shift;

    my %map = (
        1 => {
            serviceID       => 'Q',
            countryCode     => 'S',
            dateBegin       => 'B',
            productType     => 'K',
            formatType      => 'R',
            clientProductID => 'I',
            artistName      => 'D',
            upc             => 'G',
            albumName       => 'E',
            isrc            => 'H',
            trackName       => 'F',
            units           => 'T',
            currencyCode    => 'X',
            free            => 'R',
            price           => 'Z',
            mediaType       => 'K',
        },
        2 => {
            labelName       => 'C',
            serviceID       => 'S',
            countryCode     => 'U',
            dateBegin       => 'B',
            dateEnd         => 'B',
            productType     => 'M',
            formatType      => 'T',
            clientProductID => 'K',
            artistName      => 'D',
            upc             => 'G',
            albumName       => 'E',
            isrc            => 'H',
            trackName       => 'F',
            units           => 'V',
            currencyCode    => 'Z',
            free            => 'T',
            price           => 'AB',
            mediaType       => 'M',
        },
        3 => {
            serviceID       => 'Q',
            countryCode     => 'S',
            dateBegin       => 'B',
            dateEnd         => 'B',
            productType     => 'K',
            formatType      => 'R',
            clientProductID => 'I',
            artistName      => 'D',
            upc             => 'G',
            albumName       => 'E',
            isrc            => 'H',
            trackName       => 'F',
            units           => 'T',
            currencyCode    => 'X',
            free            => 'R',
            price           => 'Z',
            mediaType       => 'K',
        },
        4 => {
            labelName       => 'C',
            serviceID       => 'Q',
            countryCode     => 'S',
            dateBegin       => 'B',
            dateEnd         => 'B',
            productType     => 'K',
            formatType      => 'R',
            clientProductID => 'I',
            artistName      => 'D',
            upc             => 'G',
            albumName       => 'E',
            isrc            => 'H',
            trackName       => 'F',
            units           => 'T',
            currencyCode    => 'X',
            free            => 'R',
            price           => 'Z',
            mediaType       => 'K',
        }
    );

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

sub _headerIdentifier { ( upc => qr/(?:UPC|Parent Asset Identifier)/ ) }

sub _processHeader {
    my $self = shift;
    my $currencyCode = $self->_getByFieldName('currencyCode') || '';
    unless ($self->{_currencyCode}) {
        ($self->{_currencyCode}) = ($currencyCode =~ /^Net Revenue in (\w{3})$/i);
    }

    return $self->SUPER::_processHeader(@_);
}

sub currencyCode { shift->{_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 countryCode {
    my $self = shift;

    my $name = lc( $self->_getByFieldName('countryCode') || '' );

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

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

my %months = (
    'jan' => 1, 'feb' => 2, 'mar' => 3, 'apr' => 4, 'may' => 5, 'jun' => 6,
    'jul' => 7, 'aug' => 8, 'sep' => 9, 'oct' => 10, 'nov' => 11, 'dec' => 12,
);
sub saleDates {
    my $self = shift;

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

    # MMM-YY
    if ( $date =~ /^([a-z]{3})-(\d{2})$/i) {
        my ($month, $year) = ($months{lc($1)}, 2000 + $2);
        my $dateBegin = sprintf( "%04d-%02d-01", $year, $month );
        my $dateEnd = sprintf( "%04d-%02d-%02d", $year, $month, Days_in_Month( $year, $month ));
        return ( $dateBegin, $dateEnd );
    }

    # MM/DD/YYYY
    if ( $date =~ /^(\d{2})\/(\d{2})\/(\d{4})$/ ) {
        my $dateBegin = sprintf( "%04d-%02d-%02d", $3, $1, $2 );
        my $dateEnd = sprintf( "%04d-%02d-%02d", $3, $1, Days_in_Month( $3, $1 ));
        return ( $dateBegin, $dateBegin );
    }

    # YYYY-MM
    if ( $date =~ /^(\d{4})-(\d{2})$/) {
        my $dateBegin = sprintf( "%04d-%02d-01", $1, $2 );
        my $dateEnd = sprintf( "%04d-%02d-%02d", $1, $2, Days_in_Month( $1, $2 ));
        return ( $dateBegin, $dateEnd );
    }

    $self->fail("Cannot parse date from: '$date'");
}

sub productType {
    my $self = shift;

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

    $self->handleError( "Unknown product type: $type", RPS::DB::Item::SaleImportError::kErrorProductType );
}

my %format_map = (
    'ad-supported streaming' => RPS::File::Sale::FORMAT_STREAM,
    'breakage'               => RPS::File::Sale::FORMAT_STREAM,
    'locker service'         => RPS::File::Sale::FORMAT_STREAM,
    'subscription streaming' => RPS::File::Sale::FORMAT_STREAM,
    'subscription radio'     => RPS::File::Sale::FORMAT_STREAM,
    'unmonetized'            => RPS::File::Sale::FORMAT_STREAM,
    'ad-supported radio'     => RPS::File::Sale::FORMAT_PERFORMANCE,
    'download'               => RPS::File::Sale::FORMAT_DOWNLOAD,
    'non interactive radio'  => RPS::File::Sale::FORMAT_PERFORMANCE,
    'claimed ugc'            => RPS::File::Sale::FORMAT_STREAM,
    'tethered download'      => RPS::File::Sale::FORMAT_TETHERED,
    'other'                  => RPS::File::Sale::FORMAT_STREAM,
    'performance'            => RPS::File::Sale::FORMAT_PERFORMANCE,
    'performance income'     => RPS::File::Sale::FORMAT_PERFORMANCE,
);

sub formatType {
    my $self = shift;

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

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

sub mediaType {
    my $self = shift;

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

    return RPS::DB::Item::MediaType::kMediaTypeAudio if $type =~ /^(?:Album|Tracks?)$/i;
    return RPS::DB::Item::MediaType::kMediaTypeVideo if $type =~ /^Video$/i;

    $self->handleError( "Unknown media type: $type", RPS::DB::Item::SaleImportError::kErrorMediaType );
}

sub free {
    my $self = shift;

    my $free = $self->_getByFieldName('free') || '';
    my $price = $self->_getByFieldName('price') || 0;

    return 1 if ($free =~ /^Unmonetized$/i && $price == 0);
}

sub _isValidSaleRecord {
    my $self = shift;

    return $self->_getByFieldName('price') || $self->_getByFieldName('units');

    return 0;
}

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

1;
