package RPS::Import::Caroline::v38;

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 Add_Delta_YMD);

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

sub physical { 2 }

sub _fieldMapExtended {
    {
        physical => {
            option1 => {    # 'Physical Sales'
                labelName    => 'B',
                countryCode  => 'J',
                dateBegin    => 'A8', # Cell A8 OR B9 of "Statement - Send Version" Tab',
                productType  => 'N',
                artistName   => 'C',
                upc          => 'F',
                albumName    => 'G',
                totalRevenue => 'U',
            },
        },
        digital => {
            option1 => {    # 'Digital Sales'
                labelName   => 'B',
                serviceID   => 'L',
                dateBegin   => 'A8', # Cell A8 OR B9 of "Statement - Send Version" Tab',
                productType => 'I',
                formatType  => 'P',
                artistName  => 'C',
                upc         => 'F',
                albumName   => 'G',
                isrc        => 'I',
                trackName   => 'J',
                units       => 'U',
                price       => 'S',
                mediaType   => 'P',
            },
            option2 => {    # 'Domestic Licensing'
                labelName   => 'B',
                serviceID   => 'K',
                dateBegin   => 'A8', # Cell A8 OR B9 of "Statement - Send Version" Tab',
                productType => 'H',
                formatType  => 'M',
                artistName  => 'C',
                upc         => 'F',
                albumName   => 'G',
                isrc        => 'H',
                trackName   => 'I',
                mediaType   => 'M',
            },
        },
    }
}

sub _unverifiedFieldMapExtended {
    {
        physical => {
            option1 => {    # 'Physical Sales'
                _netUnits => 'X',
                _segment  => 'A',
            },
        },
        digital => {
            option1 => {    # 'Digital Sales'
                _segment => 'A',
            },
            option2 => {    # 'Domestic Licensing'
                _segment => 'A',
                _price_income  => 'P',
                _price_expense => 'Q',
            },
        },
    }
}

sub _headerIdentifierExtended {
    {
        physical => {
            option1 => {    # 'Physical Sales'
                productType => 'Product Type Description',
            },
        },
        digital => {
            option1 => {    # 'Digital Sales'
                formatType => 'Product Type Description',
            },
            option2 => {    # 'Domestic Licensing'
                isrc => 'ISRC',
            },
        },
    }
}

my %physicalSalesMaping = (
    'cd album' => {
        product_type => RPS::File::Sale::TYPE_CD,
    },
    'cd album plus dvd video' => {
        product_type => RPS::File::Sale::TYPE_DVD_CD_SET,
    },
    'cd ep' => {
        product_type => RPS::File::Sale::TYPE_CD,
    },
    'cd plus cd bonus' => {
        product_type => RPS::File::Sale::TYPE_CD,
    },
    'cd plus dvd bonus' => {
        product_type => RPS::File::Sale::TYPE_DVD_CD_SET,
    },
    'dvd video album ntsc' => {
        product_type => RPS::File::Sale::TYPE_DVD,
    },
    'mc album' => {
        product_type => RPS::File::Sale::TYPE_CASS,
    },
    'vinyl album 10" 33 rpm' => {
        product_type => RPS::File::Sale::TYPE_LP,
    },
    'vinyl album 12" 33 rpm' => {
        product_type => RPS::File::Sale::TYPE_LP,
    },
    'vinyl album 12" 45 rpm' => {
        product_type => RPS::File::Sale::TYPE_LP,
    },
    'vinyl single 12" 33 rpm' => {
        product_type => RPS::File::Sale::TYPE_LP5,
    },
    'vinyl single 7" 45 rpm' => {
        product_type => RPS::File::Sale::TYPE_LP5,
    },
    'vinyl single 12" 45 rpm' => {
        product_type => RPS::File::Sale::TYPE_LP5,
    },
    'vinyl single 7" 33 rpm' => {
        product_type => RPS::File::Sale::TYPE_LP5,
    },
);

my %digitalSalesMapping = (
    'audio cloud services - subscr' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'audio stream true up' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'audio subscription true up' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'audio track perm. kiosk' => {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'audio track stream portable' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'audio track stream portable - subscr' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'audio track stream webcast' => {
        format_type => RPS::File::Sale::FORMAT_PERFORMANCE,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'audio track stream webcast - subscr' => {
        format_type => RPS::File::Sale::FORMAT_PERFORMANCE,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'audio track stream webcast non-royalty' => {
        format_type => RPS::File::Sale::FORMAT_PERFORMANCE,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'audio track stream webcast portable' => {
        format_type => RPS::File::Sale::FORMAT_PERFORMANCE,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'audio track stream webcast portable - su' => {
        format_type => RPS::File::Sale::FORMAT_PERFORMANCE,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'digital allocations streams (audio)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'digital allocations streams (video)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'digital aud track stream -subscr ltdcat' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'digital online aud album permanent' => {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'digital online aud track permanent' => {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'digital online aud track stream' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'digital online aud track stream - subscr' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'digital online vid track stream' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'digital online vid track stream - subscr' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'fitness business use / gym use' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'fitness in app use' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'fitness on device / hardware use' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'longform video - permanent' => {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'telco breakage - audio subscr' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'user generated content stream - subscr' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'user generated content stream track' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'user generated content stream vid subscr' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'user generated content stream video' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'video cloud services - subscr' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'video stream video portable - subscr' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'video stream webcasting' => {
        format_type => RPS::File::Sale::FORMAT_PERFORMANCE,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'video stream webcasting - subscr' => {
        format_type => RPS::File::Sale::FORMAT_PERFORMANCE,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'digital allocations downloads' => {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'dig mob aud track perm mast (real) tones' => {
        format_type => RPS::File::Sale::FORMAT_RINGTONE,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'video stream sponsorship' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'digital online vid track permanent' => {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'dig mob aud track perm callrgs/rgbacks' => {
        format_type => RPS::File::Sale::FORMAT_RINGTONE,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'video stream video portable' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'ffp user generated content stream' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'ffp short form videos' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'ffp on demand stream' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'true up - audio stream' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'breakage - audio subscr' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'breakage audio stream' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'true up - video stream' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'true up - video subscr' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
);

my %domesticLicensingMapping = (
    'business establishment services' => {
        format_type => RPS::File::Sale::FORMAT_PERFORMANCE,
    },
    'cable radio & subscription services' => {
        format_type => RPS::File::Sale::FORMAT_PERFORMANCE,
    },
    'cabsat ephemeral' => {
        format_type => RPS::File::Sale::FORMAT_EPHEMERAL,
    },
    'royalties' => {
        format_type => undef,    # error out
    },
    'satellite radio' => {
        format_type => RPS::File::Sale::FORMAT_PERFORMANCE,
    },
    'sdars ephemeral' => {
        format_type => RPS::File::Sale::FORMAT_EPHEMERAL,
    },
    'television promo spot' => {
        format_type => undef,    # error out
    },
    'preexisting services' => {
        format_type => RPS::File::Sale::FORMAT_PERFORMANCE,
    },
    'video' => {
        format_type => RPS::File::Sale::FORMAT_PERFORMANCE,
    },
    'audio track stream webcast' => {
        format_type => RPS::File::Sale::FORMAT_PERFORMANCE,
    }
);

my %sheetRules = (
    'physical sales' => {
        labelName => sub { return $_[1] },
        serviceID => Client::Service::DSP_CAROLINE,
        saleDates => sub {
            if ( $_[0]->{_dateBegin} && $_[0]->{_dateEnd} ) {
                return ( $_[0]->{_dateBegin}, $_[0]->{_dateEnd} );
            }
            return undef;
        },
        countryCode => sub {
            return 'US' unless $_[1];
            my $oCountry = Common::Country->Get($_[1]);
            return $oCountry ? $oCountry->alpha2() : 'US';
        },
        productType => sub {
            if ( exists $physicalSalesMaping{ lc $_[1] }{product_type} ) {
                return $physicalSalesMaping{ lc $_[1] }{product_type};
            }
            return undef;
        },
        artistName => sub { return $_[1] },
        upc => sub { return $_[1] },
        albumName => sub { return $_[1] },
        channel => RPS::File::Sale::CHANNEL_RETAIL,
        priceLevel => RPS::File::Sale::PLEVEL_UNKNOWN,
        currencyCode  => 'USD',
        mediaType => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'digital sales' => {
        labelName => sub { return $_[1] },
        serviceID => sub {
            return Client::Service::DSP_CAROLINE if $_[1] =~ /All Other Licensees/i;
            my $serviceID = $_[0]->getServiceID( lc $_[1]  ) || $RPS::Import::ServiceMap::SERVICE_ALIASES{ lc $_[1] };
            return $serviceID ? $serviceID : undef;
        },
        saleDates => sub {
            if ( $_[0]->{_dateBegin} && $_[0]->{_dateEnd} ) {
                return ( $_[0]->{_dateBegin}, $_[0]->{_dateEnd} );
            }
            return undef;
        },
        countryCode => 'US',
        productType => sub {
            return $_[1] =~ /^#$/
                ? RPS::File::Sale::TYPE_ALBUM
                : RPS::File::Sale::TYPE_TRACK;
        },
        formatType => sub {
            return exists $digitalSalesMapping{ lc $_[1] }
                ? $digitalSalesMapping{ lc $_[1] }{format_type}
                : undef;
        },
        artistName => sub { return $_[1] },
        upc => sub { return $_[1] },
        albumName => sub { return $_[1] },
        isrc => sub { return $_[1] },
        trackName => sub { return $_[1] },
        currencyCode  => 'USD',
        mediaType =>  sub {
            return exists $digitalSalesMapping{ lc $_[1] }
                ? $digitalSalesMapping{ lc $_[1] }{media_type}
                : undef;
        },
    },
    'domestic licensing' => {
        labelName => sub { return $_[1] },
        serviceID => sub {
            return Client::Service::DSP_CAROLINE if $_[1] =~ /All Other Licensees/i;
            my $serviceID = $_[0]->getServiceID( lc $_[1]  ) || $RPS::Import::ServiceMap::SERVICE_ALIASES{ lc $_[1] };
            return $serviceID ? $serviceID : undef;
        },
        saleDates => sub {
            if ( $_[0]->{_dateBegin} && $_[0]->{_dateEnd} ) {
                return ( $_[0]->{_dateBegin}, $_[0]->{_dateEnd} );
            }
            return undef;
        },
        countryCode => 'US',
        productType => sub {
            return $_[1]
                ? RPS::File::Sale::TYPE_TRACK
                : RPS::File::Sale::TYPE_ALBUM;
        },
        formatType => sub {
            return exists $domesticLicensingMapping{ lc $_[1] }
                ? $domesticLicensingMapping{ lc $_[1] }{format_type}
                : undef;
        },
        artistName => sub { return $_[1] },
        upc => sub { return $_[1] },
        albumName => sub { return $_[1] },
        isrc => sub { return $_[1] },
        trackName => sub { return $_[1] },
        currencyCode  => 'USD',
        mediaType => sub {
            return $_[1] =~ /^'?Video$/i
                ? RPS::DB::Item::MediaType::kMediaTypeVideo
                : RPS::DB::Item::MediaType::kMediaTypeAudio;
        },
    },
);



sub saleDates {
    my $self = shift;

    my @result = $self->_ruleException();
    return @result
        ? @result
        : $self->fail("Unable to determine sale period for sheetname: " . $self->sheetname);
}

sub labelName {
    my $self = shift;

    my $labelName = $self->_getByFieldName('labelName') || '';
    my $result = $self->_ruleException($labelName);

    return defined $result
        ? $result
        : $self->fail("Unable to determine labelName from: '$labelName'");
}

sub serviceID {
    my $self = shift;

    my $serviceID = $self->_getByFieldName('serviceID') || '';
    my $result = $self->_ruleException($serviceID);

    return $result
        ? $result
        : $self->fail("Unable to determine serviceID from: '$serviceID'");
}

sub countryCode {
    my $self = shift;

    my $countryCode = $self->_getByFieldName('countryCode') || '';
    my $result = $self->_ruleException($countryCode);
    return $result if defined $result;

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

sub productType {
    my $self = shift;

    my $productType = $self->_getByFieldName('productType') || '';
    my $result = $self->_ruleException($productType);
    return $result if defined $result;

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

sub formatType {
    my $self = shift;

    my $formatType = $self->_getByFieldName('formatType') || '';
    my $result = $self->_ruleException( lc $formatType );
    return $result if defined $result;

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

sub artistName {
    my $self = shift;

    my $artistName = $self->_getByFieldName('artistName') || '';
    my $result = $self->_ruleException($artistName);

    return $result;
}

sub upc {
    my $self = shift;

    my $upc = $self->_getByFieldName('upc') || '';
    my $result = $self->_ruleException($upc);

    return $result if defined $result;;
}

sub albumName {
    my $self = shift;

    my $albumName = $self->_getByFieldName('albumName') || '';
    my $result = $self->_ruleException($albumName);

    return $result if defined $result;
}

sub isrc {
    my $self = shift;

    my $isrc = $self->_getByFieldName('isrc') || '';
    my $result = $self->_ruleException($isrc);

    return $result if defined $result;;
}

sub trackName {
    my $self = shift;

    my $trackName = $self->_getByFieldName('trackName') || '';
    my $result = $self->_ruleException($trackName);

    return $result if defined $result;
}

sub mediaType {
    my $self = shift;

    my $mediaType = $self->_getByFieldName('mediaType') || '';
    my $result = $self->_ruleException($mediaType);
    return $result if defined $result;

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

sub channel {
    my $self = shift;

    my $result = $self->_ruleException();
    return $result if defined $result;

    $self->fail("Unable to determine channel");
}

sub priceLevel {
    my $self = shift;

    my $result = $self->_ruleException();
    return $result if defined $result;

    $self->fail("Unable to determine priceLevel");
}

sub currencyCode {
    my $self = shift;

    my $currencyCode = $self->_getByFieldName('currencyCode') || '';
    my $result = $self->_ruleException($currencyCode);
    return $result if defined $result;

    $self->fail("Unable to determine currencyCode from '$currencyCode'");
}

# digital
sub price {
    my $self = shift;

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

    if ( $self->_sheetName eq 'domestic licensing' ) {
        my $price_income = abs( $self->_getByFieldName('_price_income') || 0 );
        my $price_expense = abs( $self->_getByFieldName('_price_expense') || 0 );
        if ( $price_income && $price_expense ) {
            $self->fail("Both Income and Expense values cannot be provided for the same record.");
        }

        $price = $price_income - $price_expense;
    }

    my $result = $self->_ruleException($price);
    return $result if defined $result;

    return sprintf "%0.8f", $price;
}
sub unitPrice { abs shift->SUPER::unitPrice }
sub units {
    my $self = shift;

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

    if ( $self->_sheetName eq 'domestic licensing' ) {
        my $price_income = abs( $self->_getByFieldName('_price_income') || 0 );
        my $price_expense = abs( $self->_getByFieldName('_price_expense') || 0 );
        $price = $price_income - $price_expense;
        $units = 0;
    }

    my $result = $self->_ruleException($units, $price);
    return $result if defined $result;

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

    return $units;
}

# physical
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   { $_[0]->_getByFieldName('totalRevenue') || 0 }

sub netUnits {
    my $self = shift;

    my $netUnits = $self->_getByFieldName('_netUnits') || 0;
    return $netUnits;
}

# internal functions
sub _ruleException {
    my ( $self, @args ) = @_;

    my $sheet = $self->_sheetName;
    my ($method) = ( caller(1) )[3] =~ /.*::(.+)$/;
    return unless exists $sheetRules{$sheet} && exists $sheetRules{$sheet}{$method};

    my $rule = $sheetRules{$sheet}{$method};
    return ref $rule eq 'CODE' ? &$rule( $self, @args ) : $rule;
}

sub _sheetName {
    my $self = shift;

    my $name = $self->sheetname() || '';
    $name =~ s/^\s+|\s+$//g;
    $name =~ s/[^0-9a-zA-Z\s]//g;
    $name =~ s/\s+/ /g;

    return lc $name;
}

sub _processHeader {
    my ($self, %args) = @_;

    if ( $self->{_dateBegin} && $self->{_dateEnd} ) {
        return $self->{_dateBegin}, $self->{_dateEnd};
    }

    ($self->{_dateBegin}, $self->{_dateEnd}) = $self->_getPeriod();

    return 1;
}

my @tabsToSkip = (
    'A&R', 'Dig FiRR', 'GCH - AIF AIN', 'Manufacturing', 'Marketing',
    'Other Handling Fees', 'Phy FiRR', 'RDW - AIJ', 'RDW - Dig Copyright Royalties',
    'RDW - Foreign License Royalties', 'RDW - PMJ',
    'Reserves', 'SOP', 'SR - Perpetual Inventory', 'SR - Refurbishment', 'SR - Scrap',
    'SR - SKU Charges', 'U19', 'UME', 'UME MFG', 'UML', 'SX Direct Passthrough', 'FRT',
    'OH UME', 'MKT Support', 'SR-SOP US001', 'PT phys'
);

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

    # Get date period from columns A8 or B9 of the 'Statement - Send Version' tab
    if ( $self->{sheetname} =~ /^Statement - Send Version$/i ) {
        foreach my $aLine ( @$sheet[0..50] ) {    # read 50 first lines
            foreach  my $col ( 0..1 ) {           # for col. A and col. B
                next unless ref $aLine eq 'ARRAY';
                my $date = $aLine->[$col] || '';
                last if $self->_getPeriod($date);
            }
        }
    }

    # Skip these tabs
    if ( grep { lc($self->{sheetname}) eq lc($_) } @tabsToSkip ) {
        Common::Log::Print("-- Skipping tab: '$self->{sheetname}'");
        return 0;
    }

    # Checking the sheet header for correctness
    my $headerFound = $self->SUPER::_processSheet( $sheet, $sheetnum );
    if ( !$headerFound && $self->sheetname =~ /^Foreign Licensing$/i ) {
        $self->fail( "Malformed header of the '$self->{sheetname}' sheet" );
    }

    return $headerFound;
}

sub _getPeriod {
    my $self = shift;
    my $period = shift || '';

    if ( $self->{_dateBegin} && $self->{_dateEnd} ) {
        return $self->{_dateBegin}, $self->{_dateEnd};
    }

    my %months = (
        jan => 1, feb => 2, mar => 3, apr => 4, may => 5, jun => 6,
        jul => 7, aug => 8, sep => 9, oct => 10, nov => 11, dec => 12
    );

    # 'FOR 1 MONTH ENDING MAY 31, 2022' ===> 05/01/2022 - 05/31/2022
    my ($p, $em, $ed, $ey) = $period =~ /FOR (\d+) MONTHS? ENDING (\w+) (\d{1,2}), (\d{4})/i;
    return unless $p--;

    $em = $months{ lc(substr($em, 0, 3)) };

    $self->{_dateEnd} = sprintf("%04d-%02d-%02d", $ey, $em, Days_in_Month($ey, $em));
    my ($by, $bm, $bd) = Add_Delta_YMD($ey, $em, 1, 0, -$p, 0);
    $self->{_dateBegin} = sprintf("%04d-%02d-%02d", $by, $bm, 1);

    return ($self->{_dateBegin}, $self->{_dateEnd});
}

sub _isValidSaleRecord {
    my $self = shift;

    my $totalRevenue = $self->_getByFieldName('totalRevenue') || '';
    my $segment = $self->_getByFieldName('_segment') || '';

    if ( $self->_sheetName eq 'physical sales' ) {
        return if $totalRevenue =~ /(?:Physical Sales Detail|Overall Result)/i;
        return if $segment =~ /Overall Result/i;
        return if !$self->artistName && !$self->albumName;
    } elsif ( $self->_sheetName eq 'digital sales' ) {
        my $price = $self->_getByFieldName('price') || 0;
        return if $price =~ /(?:Digital Sales Detail|Overall Result)/i;
        return if $segment =~ /Overall Result/i;
        return if !$self->artistName && !$self->albumName && !$self->trackName;
    } elsif (  $self->_sheetName eq 'domestic licensing' ) {
        my $price_income = $self->_getByFieldName('_price_income') || 0;
        return if $price_income =~ /(?:Domestic Licensing Income)/i;
        return if $segment =~ /Overall Result/i;
    }

    return 1;
}


1;
