package RPS::Import::Curve::v2;

use strict;
use warnings;

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

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

sub physical { 2 }

sub _fieldMapExtended {
    {
        mixed => {
            option1 => {
                countryCode     => 'H',
                dateBegin       => 'D',
                formatType      => 'V',
                clientProductID => 'J',
                upc             => 'I',
                albumName       => 'K',
                isrc            => 'P',
                trackName       => 'Q',
                units           => 'X',
                priceLevel      => 'W',
                totalRevenue    => 'AT',
                price           => 'AT',
                mediaType       => 'V',
            }
        }
    };
}

sub _unverifiedFieldMapExtended {
    {
        mixed => {
            option1 => {
                _productTypePhys   => 'V',
                _productTypeDig    => 'B',
                _releaseArtistName => 'M',
                _trackArtistName   => 'S',
                _netUnits          => 'X',
                # we should use the allowed field names or add new ones to
                # /app/tools/rps/templates/mapface/map.xsl
                service            => 'F', # physical
                retailer           => 'E', # digital
            }
        }
    };
}

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

sub currencyCode { 'USD' }

sub serviceID {
    my $self = shift;

    my $servicePhys = lc( $self->_getByFieldName('service') || '' );
    my $serviceDig  = lc( $self->_getByFieldName('retailer')  || '' );
    my $service = $self->isDigitalProduct( $self->productType ) ? $serviceDig : $servicePhys;

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

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

sub countryCode {
    my $self = shift;

    my $name = lc( $self->_getByFieldName('countryCode') || '' );
    return "ZZ" if $name eq "ww";

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

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

    return $name;
}

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

sub saleDates {
    my $self = shift;

    # Sat Feb 01 2020 00:00:00 GMT+0000 (UTC)
    my $date = $self->_getByFieldName('dateBegin') || '';
    if ( my ($m, $d, $y) = $date =~ /([a-z]{3}) (\d{1,2}) (\d{4}) \d{2}:\d{2}:\d{2}/i ) {
        return $self->_getDates( date_begin => sprintf( "%04d-%02d-%02d", $y, $months{lc $m}, $d ) );
    }

    # 2020-04-01
    if ( my ($y, $m, $d) = $date =~ /(\d{4})[-\/\.](\d{1,2})[-\/\.](\d{1,2})/ ) {
        return $self->_getDates( date_begin => sprintf( "%04d-%02d-%02d", $y, $m, $d ) );
    }

    # MM/DD/YYYY
    if ( my ($m, $d, $y) = $date =~ /(\d{1,2})[-\/\.](\d{1,2})[-\/\.](\d{2,4})/ ) {
        $y = length($y) == 2 && $y >= 20 ? "20$y" : $y;
        return $self->_getDates( date_begin => sprintf( "%04d-%02d-%02d", $y, $m, $d ) );
    }

    $self->fail( "Unable to determine dates of a sale from: '$date'" );
}

sub productType {
    my $self = shift;

    # physical
    my $typePhys = $self->_getByFieldName('_productTypePhys') || '';
    return RPS::File::Sale::TYPE_CASS       if $typePhys =~ /^Cassette$/i;
    return RPS::File::Sale::TYPE_CASS       if $typePhys =~ /^MC Album$/i;
    return RPS::File::Sale::TYPE_CD         if $typePhys =~ /^CD( Album)?$/i;
    return RPS::File::Sale::TYPE_LP         if $typePhys =~ /^3?LP$/i;
    return RPS::File::Sale::TYPE_LP         if $typePhys =~ /^Vinyl$/i;
    return RPS::File::Sale::TYPE_LP         if $typePhys =~ /^vinyl album 12/i;
    return RPS::File::Sale::TYPE_LP         if $typePhys =~ /^Long Play Record$/i;
    return RPS::File::Sale::TYPE_DVD_CD_SET if $typePhys =~ /^CD\/DVD Combo$/i;
    return RPS::File::Sale::TYPE_DBL_CD     if $typePhys =~ /^2CD$/i;

    # digital
    my $typeDig = $self->_getByFieldName('_productTypeDig')  || '';
    return RPS::File::Sale::TYPE_TRACK if $typeDig =~ /^Track$/i;
    return RPS::File::Sale::TYPE_ALBUM if $typeDig =~ /^Release$/i;

    $self->fail("Unbale to determine productType from: '$typePhys' or '$typeDig'");
}

my %formatMediaTypes = (
    '90 day family free trial' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    '90 day free trial' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'ad-funded stream' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'ad supported streaming' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'album download' => {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'art track' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'att 2018 bundle' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'audio download' => {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'concession stream' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'cloud storage stream' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'download (album)' => {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'download (track)' => {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'download' => {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'fb from ig crosspost' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'fb lite camera - music sticker through fb lite app' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'fb music overlay - music sticker' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'fb ugc - organic user generated content' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'fb ugc live - organic user generated content' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'fb profile - profile song' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'fb lasso blue - blue reels' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'hifi' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'ig question - sticker' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'ig music overlay - sticker' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'ig story camera clips - reels' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'ig ugc live - organic user generated content' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'ig ugc - organic user generated content' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'performance income' => {
        format_type => RPS::File::Sale::FORMAT_PERFORMANCE,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'premium download' => {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'premium album download' => {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'premium stream (family)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'premium stream (individual)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'premium stream (prime)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'premium stream (student)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'premium stream (trial)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'premium stream' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'premium track download'=> {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'prime day 2019 echo extended trial' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'prime paid' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'stream (discounted)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'stream' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'subscription streaming' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'telco stream' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'track download' => {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'trial stream' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'video premium stream' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'video streaming' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'video download' => {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'video ad-funded stream' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'hi-fi streaming' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type  => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
);

sub formatType {
    my $self = shift;

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

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

sub mediaType {
    my $self = shift;

    return if !$self->isDigitalProduct( $self->productType );

    my $type = lc( $self->_getByFieldName('mediaType') || '' );
    if ( exists $formatMediaTypes{$type}{media_type} ) {
        return $formatMediaTypes{$type}{media_type};
    }

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

sub artistName {
    my $self = shift;

    my $releaseArtistName = $self->_getByFieldName('_releaseArtistName') || '';
    my $trackArtistName   = $self->_getByFieldName('_trackArtistName')   || '';

    # physical
    return $releaseArtistName if !$self->isDigitalProduct( $self->productType );

    # digital
    return $releaseArtistName if $self->productType eq RPS::File::Sale::TYPE_ALBUM;
    return $trackArtistName   if $self->productType eq RPS::File::Sale::TYPE_TRACK;
}

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

    # math round
    $units += .00000001 if $units =~ /^\d+\.5\d*$/;
    $units = sprintf "%.0f", $units;

    return $units;
}

# physical
sub priceLevel         { RPS::File::Sale::PLEVEL_FULL }
sub channel            { RPS::File::Sale::CHANNEL_RETAIL }
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 (defined $_[0]->totalRevenue || defined $_[0]->price) && ( $_[0]->trackName || $_[0]->albumName );
}

# mapFace
sub _mapFaceProductType { }
sub _mapFaceServiceID   { 'service', 'retailer' }
sub _mapFaceCountryCode { 'countryCode' }
sub _mapFaceFormatType  { 'formatType' }
sub _mapFaceMediaType   { 'mediaType' }


1;
