package RPS::Import::AWAL::v35;

use strict;
use warnings;

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

sub physical { 2 }

sub _fieldMapExtended {
    {
        mixed => {
            option1 => {
                serviceID       => 'F',
                countryCode     => 'G',
                dateBegin       => 'E',
                dateEnd         => 'E',
                productType     => 'U',
                formatType      => 'U',
                clientProductID => 'J',
                artistName      => 'L',
                upc             => 'H',
                albumName       => 'M',
                isrc            => 'R',
                trackNum        => 'T',
                trackName       => 'Q',
                units           => 'Y',
                currencyCode    => 'X',
                grossRevenue    => 'AA',
                totalRevenue    => 'AB',
                price           => 'AB',
                mediaType       => 'U',
            },
        }
    }
}

sub _unverifiedFieldMapExtended {
    {
        mixed => {
            option1 => {
                _netUnits       => 'Y',
                _rel_man_upc    => 'I',
            },
        }
    };
}

sub _headerIdentifierExtended {
    {
        mixed => {
            option1 => {
                formatType => 'Transaction Transaction Type',
            },
        }
    };
}

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

my $ORCHARD_PUB2_FORMAT_MAP = RPS::Import::OrchardPub2::get_format_map();


sub serviceID {
    my $self = shift;

    if ( !$self->isDigitalProduct( $self->productType ) ) {
        return Client::Service::DSP_AWAL;
    }

    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 dateBegin {
    my $self = shift;

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

    # YYYY-MM-DD
    if ( my ($y, $m, $d) = $date =~ /^(\d{4})[-](\d{2})[-](\d{2})$/ ) {
        return sprintf "%04d-%02d-%02d", $y, $m, $d;
    }

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

sub dateEnd {
    my $self = shift;

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

    # YYYY-MM-DD
    if ( my ($y, $m, $d) = $date =~ /^(\d{4})[-](\d{2})[-](\d{2})$/ ) {
        return sprintf "%04d-%02d-%02d", $y, $m, $d;
    }

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

sub countryCode {
    my $self = shift;

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

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

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

sub productType {
    my $self = shift;

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

    # physical
    if ( $type =~ /^(?:PS|RE|TP|TR)$/i ) {
        return RPS::File::Sale::TYPE_CD;
    }

    # digital
    if ( $type =~ /^(?:DA|DV|EQ|TA|UA|VR)$/i ) {
        return RPS::File::Sale::TYPE_ALBUM;
    } elsif ( $type =~ /^(?:AC|AO|AP|AS|AV|CL|DB|DJ|DR|DT|ER|FA|FS|MA|MD|MT|MV|NR|NS|NT|OC|OG|PA|PP|RB|RR|RW|S|SA|SC|SF|SV|TD|TV|UN|UP|UQ|UT|VA|XA|XC|XG|XM|YA|YC|YG|YM|YP|CC|EH|PV|RC|RL|SL|TP|TR|VS|WA|WS|NQ|FP|KS|KA|PX|CT|PT|ST|TY)$/i ) {
        return RPS::File::Sale::TYPE_TRACK;
    } elsif ( $type =~ /^(?:SB)$/i ) {
        return $trackName =~ /^(?:Full Album|^$)$/ ? RPS::File::Sale::TYPE_ALBUM : RPS::File::Sale::TYPE_TRACK;
    } elsif ( $type =~ /^\(all\)$/i ) {
        return RPS::File::Sale::TYPE_TRACK;
    }

    $self->fail("Unknown product_type from: '$type'");
}

sub formatType {
    my $self = shift;

    if ( $self->serviceID == Client::Service::DSP_SOUNDEXCHANGE ) {
        return RPS::File::Sale::FORMAT_NON_EPHEMERAL;
    }

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

    if ( $type =~ /^(?:DT|DA|DV)$/i ) {
        return RPS::File::Sale::FORMAT_DOWNLOAD;
    } elsif ( $type =~ /^(?:AC|AO|AP|AS|AV|CL|DB|DJ|EQ|ER|FA|FS|MA|MD|MT|MV|NS|OC|OG|PA|PP|RR|RW|S|SA|SB|SC|SF|SV|TV|UN|UP|UQ|VA|XA|XC|XG|XM|YA|YC|YG|YM|YP|VS|WA|WS|NQ|FP|KS|KA|PX|CT|PT|ST|TY)$/i ) {
        return RPS::File::Sale::FORMAT_STREAM;
    } elsif ( $type =~ /^(?:TD|TA|VR)$/i ) {
        return RPS::File::Sale::FORMAT_TETHERED;
    } elsif ( $type =~ /^(?:UA|UT)$/i ) {
        return RPS::File::Sale::FORMAT_DOWNLOADUPGRADE;
    } elsif ( $type =~ /^(?:NR|NT|RL|SL|CC)$/i ) {
        return RPS::File::Sale::FORMAT_PERFORMANCE;
    } elsif ( $type =~ /^(?:DR|RB)$/i ) {
        return RPS::File::Sale::FORMAT_RINGTONE;
    } elsif ( $type =~ /^(?:EH|PV)$/i ) {
        return RPS::File::Sale::FORMAT_EPHEMERAL;
    } elsif ( $type =~ /^RC$/i ) {
        return RPS::File::Sale::FORMAT_NON_EPHEMERAL;
    }

    # fallback to OrchardPub2 mapping
    if ( exists $ORCHARD_PUB2_FORMAT_MAP->{uc $type} ) {
        my $orchard_pub2_mapping = $ORCHARD_PUB2_FORMAT_MAP->{uc $type};
        return $orchard_pub2_mapping->{format_type} if $orchard_pub2_mapping->{format_type};
    }

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

sub mediaType {
    my $self = shift;

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


    if ( $type =~ /^(?:AP|AS|CL|DA|DB|DJ|DR|DT|EQ|ER|FA|FS|MA|MD|MT|NR|NS|NT|OC|OG|PA|PP|PS|RB|RE|RR|RW|S|SA|SB|SC|TA|TD|TV|UA|UN|UP|UQ|UT|XA|XC|XM|YA|YM|\(all\)|CC|EH|PV|RC|RL|SL|TP|TR|WA|WS|NQ|FP|KS|KA|PX|CT|PT|ST|TY)$/i ) {
        return RPS::DB::Item::MediaType::kMediaTypeAudio;
    } elsif ( $type =~ /^(?:AC|AO|AV|DV|MV|SF|SV|VA|VR|XG|YC|YG|YP|VS)$/i ) {
        return RPS::DB::Item::MediaType::kMediaTypeVideo;
    }

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

sub upc {
    my $self = shift;

    my $upc = $self->_getByFieldName('upc') || '';
    my $relManUPC = $self->_getByFieldName('_rel_man_upc') || '';

    # physical
    if ( !$self->isDigitalProduct( $self->productType() ) ) {
        return $relManUPC || $upc;
    }

    # digital
    return $upc;
}

sub wholesalePrice {
    my $self = shift;

    my $totalRevenue = $self->totalRevenue();
    my $units = $self->units();

    return $units ? $totalRevenue / $units : 0;
}

sub grossRevenue {
    my $self = shift;

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

    return $grossRevenue;
}

sub trackNum {
    my $self = shift;

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

    return $trackNum;
}

# digital
sub price     { 
    my $self = shift;

    my $price = $self->_getByFieldName('price') || 0;
    $price =~ s/,//g;
    return abs( $price );
}

sub unitPrice { abs shift->SUPER::unitPrice }

sub units     {
    my $self = shift;

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

    $units =~ s/,//g;

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

    return $units;
}

# physical
sub netUnits       { $_[0]->units() }
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;
    $revenue =~ s/,//g;

    return $revenue;
}

sub _isValidSaleRecord {
    my $self = shift;

    # see RSD-12242
    return 1 if ($self->price || $self->totalRevenue)
        || ($self->units || $self->netUnits);

    return 0;
}

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


1;
