package RPS::Import::Sony::v48;

use strict;
use warnings;

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

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

sub physical { 0 }

sub _fieldMapExtended {
    {
        digital => {
            option1 => {
                serviceID       => 'M',
                dateBegin       => 'P',
                dateEnd         => 'Q',
                productType     => 'J',
                formatType      => 'L',
                clientProductID => 'I',
                artistName      => 'E',
                albumName       => 'F',
                isrc            => 'H',
                trackName       => 'G',
                units           => 'N',
                price           => 'O',
                mediaType       => 'J',
            },
            option2 => {    # an alternative header for the Digital Sales-Mobile&NonStream tab
                serviceID       => 'L',
                dateBegin       => 'O',
                dateEnd         => 'P',
                productType     => 'I',
                formatType      => 'K',
                clientProductID => 'H',
                artistName      => 'D',
                albumName       => 'E',
                isrc            => 'G',
                trackName       => 'F',
                units           => 'M',
                price           => 'N',
                mediaType       => 'I',
            },
            option3 => {  # an alternative tabl for tabs: Digital Sales-Downloads and Digital Sales - Streams
                labelName       => 'D',    # If header is 'Label Name', undef if column is 'Sap Profit Center Nm product' (RSD-12173)
                serviceID       => 'M',
                dateBegin       => 'N',
                dateEnd         => 'O',
                productType     => 'J',
                formatType      => 'L',
                clientProductID => 'H',
                artistName      => 'E',
                albumName       => 'F',
                isrc            => 'I',
                trackName       => 'G',
                units           => 'Q',
                price           => 'P',
                mediaType       => 'J',
            },
        }
    };
}

sub _unverifiedFieldMapExtended { {} }

sub _headerIdentifierExtended {
    {
        digital => {
            option1 => {
                dateBegin => 'Start Dt',
            },
            option2 => {
                dateBegin => 'Start Dt',
            },
            option3 => {
                dateBegin => 'Start Dt',
            },
        }
    };
}

my %mapProductMedia = (
    'audio album' => {
        product_type => RPS::File::Sale::TYPE_ALBUM,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'audio track' => {
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'mastertone' => {
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'video track' => {
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'auto tool video' => {
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'ugc (audio)' => {
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'ugc (video)' => {
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'user gen video (audio source)' => {
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'user gen video (video source)' => {
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'premium ugc video' => {
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    }
);

my %mapFormat = (
    'online permanent download' => {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
    },
    'mobile permanent download' => {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
    },
    'locker - streaming' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
    },
    'lockers' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
    },
    'mobile stream (ad supported)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
    },
    'mobile stream (non-ad supported)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
    },
    'mobile tethered (non-ad supported)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
    },
    'online stream (ad supported)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
    },
    'online stream (non-ad supported)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
    },
    'online tethered (non-ad supported)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
    },
    'mobile ephemeral' => {
        format_type => RPS::File::Sale::FORMAT_EPHEMERAL,
    },
    'online ephemeral' => {
        format_type => RPS::File::Sale::FORMAT_EPHEMERAL,
    },
    'multi-platform stream (non-ad supported)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
    },
    'multi-platform stream (ad supported)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
    },
    'locker' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
    },
    'metadata earnings' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
    },
    'ephemeral' => {
        format_type => RPS::File::Sale::FORMAT_EPHEMERAL,
    }
);

my %allowedSheets = (
    'digital sales - streams'            => 1,
    'digital sales-mobile&nonstream'     => 1,
    'digital sales-mobile&amp;nonstream' => 1,
    'digital sales-downloads'            => 1,
);

sub _getServiceID {
    my ($self, $service) = @_;

    return Client::Service::DSP_AMAZON        if $service =~ /^amazon/i;
    return Client::Service::DSP_GOOGLE        if $service =~ /^google/i;
    return Client::Service::DSP_SPOTIFY       if $service =~ /^spotify/i;
    return Client::Service::DSP_YOUTUBE       if $service =~ /^Vevo - YouTube Streams$/i;
    return Client::Service::DSP_VEVO          if $service =~ /^vevo/i;
    return Client::Service::DSP_YOUTUBE       if $service =~ /^youtube/i;
    return Client::Service::DSP_APPLE_MUSIC   if $service =~ /^apple services latam llc/i;
    return Client::Service::DSP_APPLE_MUSIC   if $service =~ /^apple distribution international/i;
}

sub countryCode  { 'CA' }
sub currencyCode { 'CAD' }

sub labelName {
    my $self = shift;

    if ( $self->sheetname =~ /^Digital Sales\s*\-\s*(?:Downloads|Streams)$/i ) {
        my $headerLineNum = $self->{_header_line_num} || return;
        my $headerValue = $self->cell( 'D' . $headerLineNum );
        return $self->_getByFieldName('labelName') if $headerValue =~ /Label Name/i;
    }

    return;
}

sub _processHeader {
    my $self = shift;

    if ( $self->_isHeader() && $self->sheetname =~ /^Digital Sales\s*\-\s*(?:Downloads|Streams)$/i ) {
        $self->{_header_line_num} = $self->linenum;
    }

    return;
}

sub serviceID {
    my $self = shift;

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

    return $self->handleError( "Unknown service: '$service'", RPS::DB::Item::SaleImportError::kErrorService );
}

sub saleDates {
    my $self = shift;

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

    # mm/dd/yyyy
    if ( $startDate =~ /(\d{2})\/(\d{2})\/(\d{4})/ ) {
        $startDate = sprintf "%04d-%02d-%02d", $3, $1, $2;
    }
    if ( $endDate =~ /(\d{2})\/(\d{2})\/(\d{4})/ ) {
        $endDate = sprintf "%04d-%02d-%02d", $3, $1, $2;
    }

    $startDate = Spreadsheet::ParseExcel::Utility::ExcelFmt( "yyyy-mm-dd", $startDate ) if $startDate =~ /^\d{5}$/;
    $endDate   = Spreadsheet::ParseExcel::Utility::ExcelFmt( "yyyy-mm-dd", $endDate )   if $endDate   =~ /^\d{5}$/;

    return $startDate, $endDate if $startDate && $endDate;

    $self->fail("Unable to determine period of a sale");
}

sub productType {
    my $self = shift;

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

    if ( exists $mapProductMedia{$type} ) {
        return $mapProductMedia{$type}{product_type};
    }

    return $self->handleError( "Unable to determine product_type from: '$type'.", RPS::DB::Item::SaleImportError::kErrorNonqualifying );
}

sub formatType {
    my $self = shift;

    my $format_type = lc( $self->_getByFieldName('formatType') || '' );
    my $product_type = lc( $self->_getByFieldName('productType') || '' );

    return  RPS::File::Sale::FORMAT_RINGTONE if ($product_type eq 'mastertone');

    if ( exists $mapFormat{$format_type} ) {
        return $mapFormat{$format_type}{format_type};
    }

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

sub mediaType {
    my $self = shift;

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

    if ( exists $mapProductMedia{$type} ) {
        return $mapProductMedia{$type}{media_type};
    }

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

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

sub _isValidSaleRecord {
    my $self = shift;

    return 1 if ( $self->price || $self->units );
    return;
}

sub _processSheet {
    my ( $self, $sheet, $sheetnum ) = @_;

    delete $self->{_header_line_num};

    if ( !exists $allowedSheets{ lc $self->sheetname } ) {
        $self->fail( "Encountered unrecognized sheet '" . $self->{sheetname} . "'" );
    } else {
        my $headerFound = $self->SUPER::_processSheet( $sheet, $sheetnum );

        if ( !$headerFound ) {
            $self->fail( "Unable to find header for '$self->{sheetname}' sheet" );
        }

        return $headerFound;
    }

    return 0;
}

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


1;
