package RPS::Import::PIAS::Combined::v1;

use strict;
use warnings;

use lib '/app/tools/rps/lib';
use RPS::File::Sale;
use RPS::Import::ServiceMap;
use RPS::DB::Item::MediaType;

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

sub physical { 2 }

sub _fieldMapExtended {
    {
        mixed => {
            option1 => {
                serviceID    => 'G',
                countryCode  => 'F',
                dateBegin    => 'C10',
                dateEnd      => 'C10',
                productType  => 'H',
                formatType   => 'I',
                artistName   => 'B',
                upc          => 'E',
                albumName    => 'C',
                isrc         => 'D',
                trackName    => 'C',
                units        => 'Q',
                priceLevel   => 'I',
                currencyCode => 'C9',
                retailPrice  => 'L',
                totalRevenue => 'R',
                price        => 'R',
                mediaType    => 'H',
            },
        },
    };
}

sub _unverifiedFieldMapExtended {
    {
        mixed => {
            option1 => {
                _netUnits => 'Q',
            },
        },
    };
}

sub _headerIdentifierExtended {
    {
        mixed => {
            option1 => {
                isrc => 'ISRC',
            },
        },
    };
}

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

sub currencyCode {
    my $self = shift;

    # if we have a cached currency code, use it!
    if ( $self->{_currencyCode} ) {
        return $self->{_currencyCode};
    }

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

    if ( $code =~ /(\w{3})/ ) {
        $self->{_currencyCode} = $1;
    }

    unless ( $self->{_currencyCode} ) {
        $self->fail( "Unable to determine currency code from: '$code'." );
    }

    return $self->{_currencyCode};
}

sub serviceID {
    my $self = shift;

    my $service = lc( $self->_getByFieldName('serviceID') || '' );

    return Client::Service::DSP_NOKIA if $service =~ /^nokia\s/i;
    return Client::Service::DSP_CULTURA if $service =~ /^cultura[ .]/i;
    return Client::Service::DSP_LECLERC if $service =~ /espace (?:culturel|temps)/i;
    return Client::Service::DSP_LECLERC if $service =~ /leclerc/i;
    return Client::Service::DSP_LECLERC if $service =~ /^ec limoges \/ limoges dis$/i;
    return Client::Service::DSP_CONCERTO if $service =~ /^concerto b.v./i;
    return Client::Service::DSP_PIAS if $service =~ /^(?:uk exporter|label stock out|artist sales|\[pias\] d2c)$/i;
    return Client::Service::DSP_PIAS if $service =~ /^fnac vanden borre -pias cd 50027-$/i;
    return Client::Service::DSP_NETFLIX if $service =~ /^trailer: les affam/i;
    return Client::Service::DSP_BOL if $service =~ /\(bol\.com\)/i;
    return Client::Service::DSP_MEDIA_MARKT if $service =~ /^media markt\s/i;
    return Client::Service::DSP_KROESE_COMPACT_DISCS if $service =~ /kroese/i;
    return Client::Service::DSP_UNKNOWN if $service =~ /non uk consignment stock/i;

    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 = $self->_getByFieldName('countryCode') || '';
    my $oCountry = Common::Country->Get($name);
    if ( my $country = $oCountry->alpha2 ) {
        return $country;
    }

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

sub saleDates {
    my $self = shift;

    # if we have cached dates
    if ( $self->{_dateBegin} && $self->{_dateEnd} ) {
        return $self->{_dateBegin}, $self->{_dateEnd};
    }

    # DD/MM/YYYY to DD/MM/YYYY
    my $period = $self->_getByFieldName('dateBegin') || '';

    if ( $period =~ /^(\d{2})[\-\/](\d{2})[\-\/](\d{4})\s+\w+\s+(\d{2})[\-\/](\d{2})[\-\/](\d{4})$/ ) {
        $self->{_dateBegin} = sprintf "%04d-%02d-%02d", $3, $2, $1;
        $self->{_dateEnd}   = sprintf "%04d-%02d-%02d", $6, $5, $4;
    }

    unless ( $self->{_dateBegin} && $self->{_dateEnd} ) {
        $self->fail( "Unable to determine dates from: '$period'." );
    }

    return $self->_getDates( date_begin => $self->{_dateBegin}, date_end => $self->{_dateEnd} );
}

sub productType {
    my $self = shift;

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

    if ( $type =~ /^CD\s?(?:DIGIPACK|EP)?$/i ) {               # physical
        return RPS::File::Sale::TYPE_CD;
    } elsif ( $type =~ /^2?CD(?: LTD 2)?$/i ) {
        return RPS::File::Sale::TYPE_DBL_CD;
    } elsif ( $type =~ /^1?2(?:LTD|LP)?$/i ) {
        return RPS::File::Sale::TYPE_LP;
    } elsif ( $type =~ /^(?:2nd LP Format|LP LTD ED\.)$/i ) {
        return RPS::File::Sale::TYPE_LP;
    } elsif ( $type =~ /^12" EP$/i ) {
        return RPS::File::Sale::TYPE_LP5;
    } elsif ( $type =~ /^7$/i ) {
        return RPS::File::Sale::TYPE_LP5;
    } elsif ( $type =~ /^2?LP(?: \+ Download)?$/i ) {
        return RPS::File::Sale::TYPE_LP;
    } elsif ( $type =~ /^Digital\s(?:Album|EP)$/i ) {    # digital
        return RPS::File::Sale::TYPE_ALBUM;
    } elsif ( $type =~ /^(?:Digital\s)?(?:Track|Single|VIDEO SHORT FORM|Video)$/i ) {
        return RPS::File::Sale::TYPE_TRACK;
    }

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

sub formatType {
    my $self = shift;

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

    if ( $type =~ /^(?: A\sla\scarte\sdownload\sProduct | INVOICE | FULL\sPRICE)$/xi ) {
        return RPS::File::Sale::FORMAT_DOWNLOAD;
    } elsif ( $type =~ /^(?:
        Breakage | Cloud\sStreaming | Streaming | Official\sAd\-funded\sStreaming\sProduct |
        Radio\sstreaming\sproduct | Discount\ssubsc'\sstreaming\sproduct |
        Subsc'\s(?: Stream\sProd\s\(A\)|UGC\sproduct ) | Subscr'\s(?: Stream\sprod\(teth\)|Streaming\sproduct ) |
    )$/xi ) {
        return RPS::File::Sale::FORMAT_STREAM;
    } elsif ( $type =~ /^ Subscription\sDL\sProduct $/xi ) {
        return RPS::File::Sale::FORMAT_TETHERED;
    }

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

}

sub albumName {
    my $self = shift;

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

    return;
}

sub trackName {
    my $self = shift;

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

    return ;
}

sub isrc {
    my $self = shift;

    my $isrc = $self->_getByFieldName('isrc') || '';
    $isrc =~ s/-//g;

    return $isrc;
}

sub priceLevel {
    my $self = shift;

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

    if ( $level =~ /^ CREDIT\sNOTE | INVOICE $/xi ) {
        return RPS::File::Sale::PLEVEL_UNKNOWN;
    } elsif ( $level =~ /^ FULL\sPRICE $/xi ) {
        return RPS::File::Sale::PLEVEL_FULL;
    }

     $self->fail( "Unable to determine price_level from: '$level'." );
}

sub mediaType {
    my $self = shift;

    my $type = $self->_getByFieldName("mediaType") || '';
    if ( $type =~ /^(?:DIGITAL\sVIDEO\sSHORT\sFORM|Video)$/xi ) {
        return RPS::DB::Item::MediaType::kMediaTypeVideo;
    } elsif ( $type =~ /^(?: 2?CD\s?(?: DIGIPACK|EP|LTD\s2 )? | 2?LP | Digital\s(?: Album|EP|Single|Track )? )$/xi ) {
        return RPS::DB::Item::MediaType::kMediaTypeAudio;
    } elsif ( $type =~ /^(?:12|7)(LTD)?$/i ) {
        return RPS::DB::Item::MediaType::kMediaTypeAudio;
    } elsif ( $type =~ /^12" EP$/i ) {
        return RPS::DB::Item::MediaType::kMediaTypeAudio;
    } elsif ( $type =~ /^(?:2nd LP Format|LP LTD ED\.|LP \+ Download)$/i ) {
        return RPS::DB::Item::MediaType::kMediaTypeAudio;
    }

    $self->fail("Unable to determine media_type from '$type'");

}

sub price     { abs( shift->_getByFieldName('price') || 0 ) }
sub unitPrice { abs shift->SUPER::unitPrice }

sub units {
    my $units = $_[0]->_getByFieldName('units') || 0;
    my $price = $_[0]->_getByFieldName('price') || 0;

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

    return $units;
}

sub netUnits {
    my $self = shift;
    my $netUnits = $self->_getByFieldName('_netUnits') || 0;

    if ( $self->totalRevenue > 0 ) {
         $netUnits = abs($netUnits);
    }
    elsif ( $self->totalRevenue < 0 ) {
        $netUnits = abs($netUnits) * -1;
    }
    return $netUnits;
}

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 totalRevenue {
    my $self = shift;
    my $revenue = $self->_getByFieldName('totalRevenue') || 0;
    return $revenue;
}

sub _isValidSaleRecord {
    return ( $_[0]->units || $_[0]->netUnits || $_[0]->totalRevenue || $_[0]->price );
}

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

1;
