package RPS::Import::Universal::v55;

use strict;
use warnings;

use lib '/app/tools/rps/lib';
use RPS::File::Sale;
use RPS::Import::ServiceMap;
use RPS::DB::Item::MediaType;
use Date::Calc qw(Days_in_Month Decode_Month);

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

sub physical { 2 }

sub _fieldMapExtended {
    {
        mixed => {
            option1 => {
                dateBegin    => 'A',
                dateEnd      => 'A',
                countryCode  => 'O',
                productType  => 'I',
                upc          => 'P',
                albumName    => 'G',
                serviceID    => 'R',
                artistName   => 'B',
                isrc         => 'P',
                trackName    => 'G',
                units        => 'V',
                priceLevel   => 'U',
                currencyCode => 'AF',
                price        => 'AF',
                mediaType    => 'I',
                totalRevenue => 'AF',
                channel      => 'U',
            },
        },
    };
}

sub _unverifiedFieldMapExtended {
    {
        mixed => {
            option1 => {
            salesChannel    => 'U',
            netUnits        => 'V',
            netRevenue      => 'AF',
            saleDescription => 'T'
            },
        }
    };
}

sub currencyCode {
    my $self = shift;

    return $self->{_currencyCode};    # See _processHeader
}

sub _headerIdentifierExtended {
    {
        mixed => {
            option1 => { dateBegin => 'Processing Period' }
        },
    };
}
sub _processHeader {
    my $self = shift;
    my $c    = $self->_getByFieldName('netRevenue');

    return if ( !defined $self->{_headerFound} );

    if ( $c =~ /Net Royalty Amount \((\w{2,3})\)/i ) {
        $self->{_currencyCode} = $1;
    } else {
        $self->fail("Unable to get currency code from $c");
    }
}

my %formatMap = (
    '3RDPA  3RD PARTY EXPLOITATION'  => 'error',
    'PERMD  DIGITAL ALLOCATIONS'     => RPS::File::Sale::FORMAT_DOWNLOAD,
    'PERMD  PERMANENT DOWNLOAD'      => RPS::File::Sale::FORMAT_DOWNLOAD,
    'TIMED  TIMED OUT DOWNLOAD'      => RPS::File::Sale::FORMAT_DOWNLOAD,
    'STREA  DIGITAL ALLOCATIONS STR' => RPS::File::Sale::FORMAT_STREAM,
    'STREA  STREAMING'               => RPS::File::Sale::FORMAT_STREAM,
    'SUBSC  STREAMING/SUBSCRIPTION'  => RPS::File::Sale::FORMAT_STREAM,
    'MOBMT  MOBILE MASTER TONES'     => RPS::File::Sale::FORMAT_TETHERED,
    'MOBSA  MOBILE SERVICE ACTIVATI' => RPS::File::Sale::FORMAT_TETHERED,
    'RINGB  RING-BACK TONES'         => RPS::File::Sale::FORMAT_TETHERED,
    'SYNCH  SYNCH/FLAT FEE'          => 'error',
    'TVCLI  TVCLIP VIDEO'            => RPS::File::Sale::FORMAT_PERFORMANCE,
    'MOBPE  MOBILE PERMANENT DOWNL'  => RPS::File::Sale::FORMAT_RINGTONE
);

sub serviceID {
    my $self = shift;

    return Client::Service::DSP_UNIVERSAL unless $self->isDigitalProduct( $self->productType );

    my $serviceName = $self->_getByFieldName('serviceID') || "";
    my $serviceID   = $self->getServiceID($serviceName)
      || $RPS::Import::ServiceMap::SERVICE_ALIASES{ lc $serviceName };

    return $serviceID if ($serviceID);
    return Client::Service::DSP_UNIVERSAL unless $serviceName;
    return Client::Service::DSP_UNIVERSAL if $serviceName =~ /^digital sales$/i;

    $self->fail("Unknown service '$serviceName'\n");

    return Client::Service::DSP_UNIVERSAL;
}

sub countryCode   {
    my $self = shift;

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

    $name = "Czech Republic" if ( $name =~ /^CZECH$/i );
    $name = "Bosnia and Herzegovina" if ( $name =~ /^BOSNIA HERZEGOVINA$/i );
    $name = "Trinidad and Tobago" if ( $name =~ /^TRINIDAD & TOBAGO$/i );

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

sub saleDates {
    my $self = shift;

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

    if ( $date=~ /^(\d{4})(\d{2})$/ ) {
        $startDate = sprintf( "%04d-%02d-01", $1, $2 );
        $endDate = sprintf( "%04d-%02d-%02d", $1, $2, Days_in_Month( $1, $2 ) );
    }

    return ( $startDate, $endDate );
}

sub productType {
    my $self = shift;

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

    if ($configuration =~ /^PERMD  PERMANENT DOWNLOAD$/i) {
        if ( $code =~ /^D1|D8$/i ) {
            return RPS::File::Sale::TYPE_ALBUM;
        }
    }
    if ( $code =~ /^(D1|D5|D8)$/i ) {
        return RPS::File::Sale::TYPE_CD;
    } elsif ( $code =~ /^(L6|S6|S5|L5)$/i ) {
        return RPS::File::Sale::TYPE_LP;
    } elsif ( $code =~ /^(P1|R5|K3|Q3|P7)$/i ) {
        return RPS::File::Sale::TYPE_DVD;
    } elsif ( $code =~ /^(N8|P8)$/i ) {
        return RPS::File::Sale::TYPE_DVD_CD_SET;
    } elsif ( $code =~ /^(M1|M2|M7)$/i ) {
        return RPS::File::Sale::TYPE_CASS;
    } elsif ( $code =~ /^V1$/i ) {
        return RPS::File::Sale::TYPE_VHS;
    } elsif ( $code =~ /^D4$/i ) {
        return RPS::File::Sale::TYPE_CD_SIN;
    } elsif ( $code =~ /^B1|B4$/i ) {
        return RPS::File::Sale::TYPE_ALBUM;
    } elsif ( $code =~ /^B2|ID|IV$/i ) {
        return RPS::File::Sale::TYPE_TRACK;
    } else {
        $self->fail("Unknown product type from $code");
        return undef;
    }

    return $self->handleError(
        "Product type not set: $code",
        RPS::DB::Item::SaleImportError::kErrorNonqualifying
    );
}

sub formatType {
    my $self = shift;

    my $configuration = uc( $self->_getByFieldName('saleDescription') || '' );

    if ( exists $formatMap{$configuration} && $formatMap{$configuration} ne 'error') {
        return $formatMap{$configuration};
    }

    my $errorMsg = "Couldn't determine product format";
    if ($formatMap{$configuration} eq 'error') {
        $errorMsg = "Wrong product format";
    }

    return $self->handleError(
        $errorMsg . " $configuration: ",
        RPS::DB::Item::SaleImportError::kErrorFormatType
    );
}

sub upc {
    my $self = shift;

    my $isDigitalProduct = $self->isDigitalProduct( $self->productType );
    return !$isDigitalProduct || $self->productType eq RPS::File::Sale::TYPE_ALBUM
        ? $self->_getByFieldName('upc')
        : undef;
}

sub isrc {
    my $self = shift;

    return $self->productType eq RPS::File::Sale::TYPE_TRACK ? $self->_getByFieldName('isrc') : undef;
}

sub albumName {
    my $self = shift;

    return ($self->productType eq RPS::File::Sale::TYPE_ALBUM || $self->productType eq RPS::File::Sale::TYPE_CD)
        ? $self->_getByFieldName('albumName')
        : undef;
}

sub trackName {
    my $self = shift;

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

sub channel {
    my $self = shift;

    my $isDigitalProduct = $self->isDigitalProduct( $self->productType );
    my $ch = $self->_getByFieldName('channel') || '';
    if (!$isDigitalProduct) {
        if ( $ch =~ /^(11|21|31)$/ ) {
            return RPS::File::Sale::CHANNEL_RETAIL;
        }
        elsif ( $ch =~ /^12$/ ) {
            return RPS::File::Sale::CHANNEL_CLUB;
        }
        elsif ( $ch =~ /^15$/ ) {
            return RPS::File::Sale::CHANNEL_MAILORDER;
        }
        elsif ( $ch =~ /^DA|DC$/i ) {
            return RPS::File::Sale::CHANNEL_DIRECT;
        }
    }

    $self->fail("Unsupported sales channel for physical product type: '$ch'.");
}

sub priceLevel {
    my $self = shift;

    my $isDigitalProduct = $self->isDigitalProduct( $self->productType );
    my $pl = $self->_getByFieldName('priceLevel') || '';
    if (!$isDigitalProduct) {
        return RPS::File::Sale::PLEVEL_FULL if ($pl =~ /^11|21|31$/);
        return RPS::File::Sale::PLEVEL_UNKNOWN if ($pl =~ /^12|15|DA|DC$/i);
    }

    $self->fail("Unsupported price level for physical product type: '$pl'.");
}
sub mediaType {
    my $self = shift;

    my $type = $self->_getByFieldName('mediaType') || '';
    return RPS::DB::Item::MediaType::kMediaTypeAudio if ($type =~ /^D1|L6|S6|N8|D8|D5|M1|M2|S5|L5|D4|B1|B2|B4|ID$/i);
    return RPS::DB::Item::MediaType::kMediaTypeVideo if ($type =~ /^P1|R5|K3|P8|Q3|V1|P7|IV$/i);

    return $self->handleError(
        "Media type not set: '$type'",
        RPS::DB::Item::SaleImportError::kErrorNonqualifying
    );
}


sub price     { abs( shift->_getByFieldName('price') || 0 ) }
sub units {
    my $self = shift;

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

    return $price < 0 ? abs($units) * -1 : $units;
}
sub unitPrice { abs shift->SUPER::unitPrice }

sub netUnits       { sprintf "%.0f", ( shift->_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 {
    my $self = shift;

    return $self->netUnits && defined $self->totalRevenue && $self->_getByFieldName('albumName');
}

1;
