package RPS::Import::BacklashSolutions::v1;

use strict;
use warnings;

use lib '/app/tools/rps/lib';
use RPS::Import::ServiceMap;

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

sub physical { 2 }


## Please note that during the importer implementation the Physical tab had no records
## so we did not have a chance to check it.

sub _fieldMapExtended {
    {
        digital => {
            option1 => {
                labelName       => 'A',
                serviceID       => 'J',
                countryCode     => 'K',
                productType     => 'E',
                clientProductID => 'B',
                artistName      => 'C',
                upc             => 'F',
                albumName       => 'D',
                isrc            => 'G',
                trackName       => 'D',
                units           => 'R',
                price           => 'W',
                mediaType       => 'E',
            },
            option2 => {    # with an extra column
                labelName       => 'A',
                serviceID       => 'J',
                countryCode     => 'K',
                productType     => 'E',
                clientProductID => 'B',
                artistName      => 'C',
                upc             => 'F',
                albumName       => 'D',
                isrc            => 'G',
                trackName       => 'D',
                units           => 'R',
                price           => 'X',
                mediaType       => 'E',
            },
        },
        physical => {
            option1 => {
                labelName       => 'A',
                countryCode     => 'I',
                productType     => 'E',
                clientProductID => 'B',
                artistName      => 'C',
                upc             => 'G',
                albumName       => 'D',
                totalRevenue    => 'S',
            },
        }
    };
}

sub _unverifiedFieldMapExtended {
    {
        digital => {
            option1 => {
                _deliveryType     => 'L',
                _deliveryFormat   => 'M',
                _headerIdentifier => 'U',
            },
            option2 => {
                _deliveryType     => 'L',
                _deliveryFormat   => 'M',
                _headerIdentifier => 'U',
            }
        },
        physical => {
            option1 => {
                _netUnits       => 'M',
            }
        }
    }
}

sub _headerIdentifierExtended {
    {
        digital => {
            option1 => { _headerIdentifier => 'Net Income' },
            option2 => { _headerIdentifier => 'Net Sales' },
        },
        physical => {
            option1 => { _headerIdentifier => 'UPC' },
        }
    };
}

sub currencyCode { 'USD' }

sub serviceID {
    my $self = shift;

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

    return $self->_getDates( date_begin => $self->{_date_begin}, date_end => $self->{_date_end} );
}

sub countryCode {
    my $self = shift;

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

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

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

sub productType {
    my $self = shift;

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

    # digital
    return RPS::File::Sale::TYPE_ALBUM if $type =~ /^Album|Single$/i;
    return RPS::File::Sale::TYPE_TRACK if $type =~ /^Track|Video$/i;

    $self->handleError( "Unknown product type: $type", RPS::DB::Item::SaleImportError::kErrorProductType );
}

sub formatType {
    my $self = shift;

    my $deliveryType   = $self->_getByFieldName('_deliveryType')   || '';
    my $deliveryFormat = $self->_getByFieldName('_deliveryFormat') || '';

    if ( $deliveryType =~ /^Stream$/i ) {
        return $deliveryFormat !~ /NonInteractiveStream/i
            ? RPS::File::Sale::FORMAT_STREAM
            : RPS::File::Sale::FORMAT_PERFORMANCE;
    }

    return RPS::File::Sale::FORMAT_DOWNLOAD if $deliveryType =~ /^Download$/;
    return RPS::File::Sale::FORMAT_STREAM if $deliveryType =~ /^Subscription$/;

    $self->handleError( "Unknown format type: $$deliveryType and $deliveryFormat", RPS::DB::Item::SaleImportError::kErrorFormatType );
}

sub mediaType {
    my $self = shift;

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

    # digital
    return RPS::DB::Item::MediaType::kMediaTypeAudio if $type =~ /^Album|Single|Track$/i;
    return RPS::DB::Item::MediaType::kMediaTypeVideo if $type =~ /^Video$/i;

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

sub albumName {
    my $self = shift;

    my $albumName = $self->_getByFieldName('albumName') || '';
    # physical

    # digital
    if ( $self->productType() eq RPS::File::Sale::TYPE_ALBUM ) {
        return $albumName;
    }

    return;
}

sub trackName {
    my $self = shift;

    my $trackName = $self->_getByFieldName('trackName') || '';
    # physical

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

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

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

    if ( $self->sheetname() =~ /^Statement Summary$/i ) {

        # Distributor should be in cell A2 - Zojak Worldwide
        # Period should be in cell A5 - 'Period: 3/1/2023 - 3/31/2023'
        my ($distributorFound, $periodFound);
        for ( 0..50 ) {
            next unless defined $sheet->[$_][0];
            if ( $sheet->[$_][0] =~ /^Zojak Worldwide$/i  ) {
                $distributorFound = 1;
            } elsif ( $sheet->[$_][0] =~ /Period: (\d{1,2})\/(\d{1,2})\/(\d{4}) \- (\d{1,2})\/(\d{1,2})\/(\d{4})/ ) {
                $self->{_date_begin} = sprintf "%04d-%02d-%02d", $3, $1, $2;
                $self->{_date_end}   = sprintf "%04d-%02d-%02d", $6, $4, $5;
                $periodFound = 1;
            }
        }
        $self->fail("Distributor name is not 'Zojak Worldwide'.") unless $distributorFound;
        $self->fail("Unbale to determine sale period,") unless $self->{_date_begin} && $self->{_date_end};
    }

    if ( $self->sheetname() =~ /^Physical Sales$/i ) {
        # check the first cell for a value in the first 10 lines after the header
        my $values = '';
        for ( 1..10 ) {
            $values .= $sheet->[$_][0] || '';
            $values =~ s/^\s+|\s+$//g;
        }
        if ( $values && $values !~ /^Totals$/i ) {
            $self->fail("The Physical Sales tab contains data. Please check the data and provide rules for its analysis.");
        }
    }

    $self->SUPER::_processSheet( $sheet, $sheetnum );
}

sub _isValidSaleRecord {
    my $self = shift;

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


# mapFace
sub _mapFaceServiceID   { 'serviceID' }
sub _mapFaceCountryCode { 'countryCode' }
sub _mapFaceProductType { 'productType' }
sub _mapFaceFormatType  { '_deliveryType', '_deliveryFormat' }
sub _mapFaceMediaType   { 'mediaType' }


1;
