package RPS::Import::ThirtyTigers::v4;

use strict;
use warnings;

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

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

sub physical { 2 }

sub _fieldMapExtended {
    {
        digital => {
            option1 => {    # US Digital
                labelName   => 'J',
                serviceID   => 'T',
                countryCode => 'S',
                dateBegin   => 'L',
                dateEnd     => 'L',
                productType => 'U',
                formatType  => 'U',
                upc         => 'Q',
                albumName   => 'N',
                isrc        => 'R',
                trackName   => 'P',
                units       => 'V',
                price       => 'W',
                mediaType   => 'U',
            },
            option2 => {    # Non-US Digital
                labelName   => 'Y',
                serviceID   => 'AI',
                countryCode => 'AH',
                dateBegin   => 'AA',
                dateEnd     => 'AA',
                productType => 'AJ',
                formatType  => 'AJ',
                upc         => 'AF',
                albumName   => 'AC',
                isrc        => 'AG',
                trackName   => 'AE',
                units       => 'AK',
                price       => 'AL',
                mediaType   => 'AJ',
            },
        },
        physical => {    # Physical
            option1 => {
                labelName      => 'AN',
                countryCode    => 'AT',
                dateBegin      => 'AP',
                dateEnd        => 'AP',
                artistName     => 'AQ',
                upc            => 'AU',
                albumName      => 'AR',
                sales          => 'AV',
                salesRevenue   => 'AW',
                returns        => 'AX',
                returnsRevenue => 'AY',
                totalRevenue   => 'BA',
            },
        },
    };
}

sub _unverifiedFieldMapExtended {
    {
        digital => {
            option1 => {
                _title       => 'M',
                _trackArtist => 'O',
            },
            option2 => {
                _title       => 'AB',
                _trackArtist => 'AD',
            },
        },
        physical => {
            option1 => {
                _netUnits => 'AZ',
            },
        },
    };
}

sub _headerIdentifierExtended {
    {
        digital => {
            option1 => {
                upc => 'UPC',
            },
            option2 => {
                upc => 'UPC',
            },
        },
        physical => {
            option1 => {
                upc => 'UPC',
            },
        }
    };
}

my %map = (
    'ad-supported audio streams' => {
        product_type => RPS::File::Sale::TYPE_TRACK,
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'ad-supported video streams' => {
        product_type => RPS::File::Sale::TYPE_TRACK,
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'cloud match units' => {
        product_type => RPS::File::Sale::TYPE_TRACK,
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'download albums' => {
        product_type => RPS::File::Sale::TYPE_ALBUM,
        format_type  => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'download tracks' => {
        product_type => RPS::File::Sale::TYPE_TRACK,
        format_type  => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'mid-tier subscription audio streams' => {
        product_type => RPS::File::Sale::TYPE_TRACK,
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'non-interactive radio' => {
        product_type => RPS::File::Sale::TYPE_TRACK,
        format_type  => RPS::File::Sale::FORMAT_PERFORMANCE,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'subscription audio streams' => {
        product_type => RPS::File::Sale::TYPE_TRACK,
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'subscription video streams' => {
        product_type => RPS::File::Sale::TYPE_TRACK,
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'fraudulent streams' => {
        product_type => RPS::File::Sale::TYPE_TRACK,
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'tethered downloads' => {
        product_type => RPS::File::Sale::TYPE_TRACK,
        format_type  => RPS::File::Sale::FORMAT_TETHERED,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'streaming bonus' => {
        product_type => RPS::File::Sale::TYPE_ALBUM,
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
);


sub _processLine {
    my $self = shift;

    # processing of all available data_types and their options consistently
    my $hFieldMap = $self->_fieldMapExtended();
    foreach my $type ( sort keys %$hFieldMap ) {
        foreach my $option ( sort keys %{ $hFieldMap->{$type} } ) {
            # redefine fieldMap for the particular line
            $self->_setTypesAndFieldMaps($type, $option);
            $self->SUPER::_processLine(@_);
        }
    }

    return 1;
}

sub _processSheet {
    my $self = shift;

    if ( $self->sheetnum > 1 ) {
        $self->fail("This importer does not allow to process more than one sheet.");
    }

    $self->SUPER::_processSheet(@_);
}

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

sub saleDates {
    my $self = shift;

    my $dateBegin = $self->_getByFieldName('dateBegin') || '';
    if ( $dateBegin =~ /^(\d{4})(\d{2})$/ ) {
        return $self->_getDates( date_begin => sprintf("%04d-%02d-%02d", $1, $2, 1) )
    }

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

sub serviceID {
    my $self = shift;

    if ( $self->dataType =~ /^physical$/ && $self->dataTypeOption =~ /^option1$/ ) {
        return Client::Service::DSP_THIRTY_TIGERS;
    }

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

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

sub countryCode {
    my $self = shift;

    my $country  = $self->_getByFieldName('countryCode') || '';
    my $oCountry = Common::Country->Get($country);
    return $oCountry->alpha2 if $oCountry;

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

sub productType {
    my $self = shift;

    if ( $self->dataType =~ /^physical$/ && $self->dataTypeOption =~ /^option1$/ ) {
        return RPS::File::Sale::TYPE_CD;
    }

    my $type = lc( $self->_getByFieldName('productType') || '' );
    return $map{$type}{product_type} if exists $map{$type};

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

sub formatType {
    my $self = shift;

    return if $self->dataType =~ /^physical$/;

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

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

sub mediaType {
    my $self = shift;

    if ( $self->dataType =~ /^physical$/ && $self->dataTypeOption =~ /^option1$/ ) {
        return RPS::DB::Item::MediaType::kMediaTypeAudio;
    }

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

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

sub artistName {
    my $self = shift;

    if ( $self->dataType =~ /^physical$/ && $self->dataTypeOption =~ /^option1$/ ) {
        return $self->_getByFieldName('artistName');
    }

    my $title  = $self->_getByFieldName('_title') || '';
    my $artist = $self->_getByFieldName('_trackArtist') || '';
    if ( $self->productType eq RPS::File::Sale::TYPE_ALBUM ) {
        return $title;
    } elsif ( $self->productType eq RPS::File::Sale::TYPE_TRACK ) {
        return $artist || $title;
    }

    return;
}

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

    return $units;
}

# physical
sub netUnits       { $_[0]->_getByFieldName('_netUnits')    || 0 }
sub totalRevenue   { $_[0]->_getByFieldName('totalRevenue') || 0 }
sub sales          { abs( $_[0]->_getByFieldName('sales')   || 0 ) }
sub returns        { abs( $_[0]->_getByFieldName('returns') || 0 ) }
sub salesRevenue   { $_[0]->_getByFieldName('salesRevenue')   > 0 ? $_[0]->_getByFieldName('salesRevenue')       : 0 }
sub returnsRevenue { $_[0]->_getByFieldName('returnsRevenue') < 0 ? abs $_[0]->_getByFieldName('returnsRevenue') : 0 }

sub _isValidSaleRecord {
    return $_[0]->_getByFieldName('trackName') || $_[0]->_getByFieldName('albumName');
}


1;
