package RPS::Import::Empire::v1;

use strict;
use warnings;

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

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

sub physical { 2 }

sub _fieldMapExtended {
    my $self = shift;

    my %map = (
        1 => {
            digital => {
                option1 => {
                    labelName       => 'D',
                    serviceID       => 'C',
                    countryCode     => 'M',
                    dateBegin       => 'B',
                    productType     => 'L',
                    formatType      => 'L',
                    clientProductID => 'F',
                    artistName      => 'H',
                    upc             => 'E',
                    albumName       => 'G',
                    isrc            => 'I',
                    trackName       => 'J',
                    units           => 'N',
                    price           => 'Q',
                    mediaType       => 'L'
                },
            },
        },
        2 => {
            mixed => {
                option1 => {
                    labelName       => 'D',
                    serviceID       => 'C',
                    countryCode     => 'M',
                    dateBegin       => 'B',
                    productType     => 'L',
                    formatType      => 'L',
                    clientProductID => 'F',
                    artistName      => 'H',
                    upc             => 'E',
                    albumName       => 'G',
                    isrc            => 'I',
                    trackName       => 'J',
                    units           => 'N',
                    price           => 'O',
                    totalRevenue    => 'O',
                    mediaType       => 'L'
                },
            },
        },
    );

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


sub _unverifiedFieldMapExtended {
    my $self = shift;

    my %map = (
        2 => {
            mixed => {
                option1 => {
                    _netUnits => 'N',
                },
            },
        },
    );

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

sub _headerIdentifierExtended {
    my $self = shift;

    my %map = (
        1 => {
            digital => {
                option1 => {
                    upc => 'UPC_EAN',
                },
            },
        },
        2 => {
            mixed => {
                option1 => {
                    upc => 'UPC_EAN',
                },
            },
        },
    );

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

sub currencyCode { 'USD' }
sub channel      { RPS::File::Sale::CHANNEL_RETAIL }
sub priceLevel   { RPS::File::Sale::PLEVEL_UNKNOWN }

sub countryCode {
    my $self = shift;

    my $code = $self->_getByFieldName("countryCode") || '';

    if ( $self->isDigitalProduct( $self->productType ) ) {
        return "US" if !$code && $self->formatType eq RPS::File::Sale::FORMAT_STREAM;
    }
    return "QA" if $code =~ /^Qatar$/;
    return $code =~ /^WW$/i ? 'US' : $code;

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

my %mappings = (
    "album" => {
        product_type => RPS::File::Sale::TYPE_ALBUM,
        format_type  => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    "audio stream" => {
        product_type => RPS::File::Sale::TYPE_TRACK,
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    "ringtone" => {
        product_type => RPS::File::Sale::TYPE_TRACK,
        format_type  => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    "royalty collection" => {
        product_type => RPS::File::Sale::TYPE_TRACK,
        format_type  => RPS::File::Sale::FORMAT_PERFORMANCE,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    "track" => {
        product_type => RPS::File::Sale::TYPE_TRACK,
        format_type  => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    "video stream" => {
        product_type => RPS::File::Sale::TYPE_TRACK,
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    "video" => {
        product_type => RPS::File::Sale::TYPE_TRACK,
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
);

sub price {
    my $self = shift;

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

    $price =~ s/[\$,]//g;
    $price *= -1 if $price =~ s/[)(]//g;

    return $price;
}

sub productType  {
    my $self = shift;

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

    if ( $self->_version == 2 ) {
        # v2 can contain physical sales
        return RPS::File::Sale::TYPE_CD if $productType =~ /^Physical \(CD\)$/i;
        return RPS::File::Sale::TYPE_LP if $productType =~ /^Physical \(Vinyl\)$/i;
    }

    # an extra rule for cases when a productType value is empty (RSD-4500)
    return RPS::File::Sale::TYPE_TRACK if !$productType && $self->serviceID == 10028;    # DSP_KKBOX

    return $mappings{lc $productType}->{product_type} if $mappings{lc $productType}->{product_type};

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

sub formatType   {
    my $self = shift;

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

    # an extra rule for cases when a productType value is empty (RSD-4500)
    return RPS::File::Sale::FORMAT_STREAM if !$formatType && $self->serviceID == 10028;    # DSP_KKBOX

    return $mappings{lc $formatType}->{format_type} if $mappings{lc $formatType}->{format_type};

    $self->fail("Could not parse format type from '$formatType'");
}
sub mediaType    {
    my $self = shift;

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

    if ( $self->_version == 2 ) {
        # v2 can contain physical sales
        return RPS::DB::Item::MediaType::kMediaTypeAudio if $mediaType =~ /^Physical \((?:Vinyl|CD|)\)$/i;
    }

    # an extra rule for cases when a productType value is empty (RSD-4500)
    return RPS::DB::Item::MediaType::kMediaTypeAudio if !$mediaType && $self->serviceID == 10028;    # DSP_KKBOX

    return $mappings{lc $mediaType}->{media_type} if $mappings{lc $mediaType}->{media_type};

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

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 $sdate = $self->_getByFieldName('dateBegin') || "";
    my ($startDate, $endDate);
    my ($m, $y) = ($sdate =~ /^(\w{3})[ -](\d{2,4})$/); # e.g. Jun-19
    if ($m && $y){
        $y = "20".$y if length($y) < 4;
        $startDate = sprintf( "%04d-%02d-01", $y, $months{$m} );
        $endDate   = sprintf( "%04d-%02d-%02d", $y, $months{$m}, Days_in_Month( $y, $months{$m} ) );
    }
    elsif ($sdate =~ /^(\d{4})-(\d{2})-(\d{2})$/) {
        $startDate = sprintf( "%04d-%02d-01", $1, $2 );
        $endDate   = sprintf( "%04d-%02d-%02d", $1, $2, Days_in_Month( $1, $2 ) );
    }
    elsif ($sdate =~ /^(\d\d)[ -](\w{3})$/) { # e.g. 19-Jun
        $startDate = sprintf( "20%02d-%02d-01", $1, $months{$2} );
        $endDate   = sprintf( "20%02d-%02d-%02d", $1, $months{$2}, Days_in_Month( "20".$1, $months{$2} ) );
    }

    else {
        $self->fail("Wrong start date: $sdate");
    }

    return ( $startDate, $endDate );
}

sub serviceID {
    my $self = shift;

    my $service = lc( $self->_getByFieldName('serviceID') || '' );
    return Client::Service::DSP_EMPIRE if $service =~ /^unknown service \(\d\)$/i;

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

    unless ( $self->_getByFieldName('productType') ) {
        $self->fail("Unable to determine service id from '$serviceID'.");
    }

    return $self->handleError( "Unable to determine service id from: '$service'", RPS::DB::Item::SaleImportError::kErrorService );
}

sub units {
    my $self = shift;

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

    if ( $price > 0 ) {
        $units = $units ? abs($units) : 1;
    } elsif ( $price < 0 ) {
       $units = $units ? -1 * abs($units) : -1;
    }

    return $units;
}

# physical
sub totalRevenue {
    my $self = shift;

    my $totalRevenue = $self->_getByFieldName('totalRevenue') || 0;
    $totalRevenue =~ s/[\$,]//g;
    $totalRevenue *= -1 if $totalRevenue =~ s/[)(]//g;

    return $totalRevenue * 1;
}

sub _netUnits      { $_[0]->_getByFieldName('_netUnits') || 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 {
    my $self  = shift;

    return 0 if !$self->_netUnits && !$self->totalRevenue;
    return 1 if ($self->units || $self->price || $self->trackName);
    return 0;
}

# mapFace
sub _mapFaceServiceID   { 'serviceID' }
sub _mapFaceCountryCode {}
sub _mapFaceProductType {}
sub _mapFaceFormatType  {}
sub _mapFaceMediaType   {}

1;
