#---------------------------------------------------------------
# ____                   _ _         ____  _
#|  _ \ ___  _   _  __ _| | |_ _   _/ ___|| |__   __ _ _ __ ___
#| |_) / _ \| | | |/ _` | | __| | | \___ \| '_ \ / _` | '__/ _ \
#|  _ < (_) | |_| | (_| | | |_| |_| |___) | | | | (_| | | |  __/
#|_| \_\___/ \__, |\__,_|_|\__|\__, |____/|_| |_|\__,_|_|  \___|
#            |___/             |___/
#
# Copyright (C) 2013 RoyaltyShare, Inc.   All Rights Reserved
#---------------------------------------------------------------

package RPS::Import::Caroline::v2;

use strict;

use Date::Calc qw(Days_in_Month Decode_Month);

use lib '/app/tools/common/lib';
use Common::Assert;

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

use base 'RPS::Import::MapFaceBase';
use base 'RPS::Import::Importer';

sub _fieldMap {
    my $self    = shift;
    my $version = $self->_version;

    my %field_map = (
        2 => {
            type       => 'J',    # requires _productTypes hash
            artistName => 'E',
            upc        => 'F',
            albumName  => 'G',
            isrc       => 'H',
            trackName  => 'I',
            units      => 'L',
            price      => 'K',
        },
        6 => {
            type       => 'K',    # requires _productTypes hash
            artistName => 'F',
            upc        => 'G',
            albumName  => 'H',
            isrc       => 'I',
            trackName  => 'J',
            units      => 'M',
            price      => 'L',
        },
        14 => {
            dateBegin  => 'A',
            type       => 'I',    # requires _productTypes hash
            artistName => 'D',
            upc        => 'E',
            albumName  => 'F',
            isrc       => 'G',
            trackName  => 'H',
            units      => 'K',
            price      => 'J',
        },
        19 => {
            dateBegin  => 'B',
            type       => 'J',    # requires _productTypes hash
            artistName => 'E',
            upc        => 'F',
            albumName  => 'G',
            isrc       => 'H',
            trackName  => 'I',
            units      => 'L',
            price      => 'K',
        },
        20 => {
            dateBegin  => 'B',
            type       => 'H',    # requires _productTypes hash
            artistName => 'E',
            upc        => 'F',
            albumName  => 'G',
            isrc       => 'I',
            trackName  => 'J',
            units      => 'L',
            price      => 'K',
        },
        31 => {
            dateBegin  => 'A',
            type       => 'I',    # requires _productTypes hash
            artistName => 'D',
            upc        => 'E',
            albumName  => 'F',
            isrc       => 'G',
            trackName  => 'H',
            units      => 'K',
            price      => 'J',
        },
        35 => {
            dateBegin  => 'A',
            type       => 'I',    # requires _productTypes hash
            artistName => 'D',
            upc        => 'E',
            albumName  => 'F',
            isrc       => 'G',
            trackName  => 'H',
            units      => 'K',
            price      => 'J',
        },
    );
    return $field_map{$version};
}

sub _unverifiedFieldMap {
    my $self    = shift;
    my $version = $self->_version;

    my %field_map = (
        2 => {
            year  => 'A',
            month => 'B',
        },
        6 => {
            year  => 'B',
            month => 'C',
        },
        14 => {},
        19 => {},
        20 => {},
        31 => {},
        35 => {},
    );
    return $field_map{$version};
}

sub _headerIdentifier { ( upc => qr/CPRS new UPC code|UPC/ ) }

# Note: keys must be lowercase
#
sub _productTypes {
    {
        'audio album perm. kiosk' => {
            productType => RPS::File::Sale::TYPE_ALBUM,
            formatType  => RPS::File::Sale::FORMAT_DOWNLOAD,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'audio cloud services' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'audio cloud services - subscr' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'audio stream true up' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'audio subscription true up' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'audio track perm. kiosk' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_DOWNLOAD,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'audio track stream portable' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'audio track stream portable - subscr' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'audio track stream webcast' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'audio track stream webcast - subscr' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'audio track stream webcast portable - su' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'audio track stream webcast non-royalty' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'audio track stream webcast portable' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'dig mob aud track perm download' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_DOWNLOAD,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'dig mob aud track perm mast (real) tones' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'dig mob aud track perm callrgs/rgbacks' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_RINGTONE,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'dig mob aud track play/stream (mob ota)' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_DOWNLOAD,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'dig mob vid single perm download' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_DOWNLOAD,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeVideo,
        },
        'digital allocations streams (audio)' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'digital aud track stream  -subscr ltdcat' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'digital mob aud track perm  download' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_DOWNLOAD,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'digital mob vid single perm download' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_DOWNLOAD,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeVideo,
        },
        'digital mobile audio album permanent' => {
            productType => RPS::File::Sale::TYPE_ALBUM,
            formatType  => RPS::File::Sale::FORMAT_DOWNLOAD,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'digital online aud album permanent' => {
            productType => RPS::File::Sale::TYPE_ALBUM,
            formatType  => RPS::File::Sale::FORMAT_DOWNLOAD,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'digital online aud bund stream' => {
            productType => RPS::File::Sale::TYPE_ALBUM,
            formatType  => RPS::File::Sale::FORMAT_DOWNLOAD,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'digital online aud track permanent' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_DOWNLOAD,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'digital online aud track stream' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_DOWNLOAD,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'digital online aud track stream - subscr' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'digital online vid track permanent' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_DOWNLOAD,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeVideo,
        },
        'digital online vid track stream' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeVideo,
        },
        'ringback - no copyright' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'user generated content stream' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'user generated content stream - subscr' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'user generated content stream track' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'user generated content stream vid subscr' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeVideo,
        },
        'video cloud services' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeVideo,
        },
        'video stream video portable' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeVideo,
        },
        'video stream video portable - subscr' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeVideo,
        },
        'video stream webcasting' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeVideo,
        },
    };
}

sub productType {
    my $self      = shift;
    my $trackName = $self->_getByFieldName('trackName');
    my $isrc      = $self->_getByFieldName('isrc');

    if ( $isrc eq '#' && $trackName =~ /^not assigned$/i )    # outlier
    {
        return RPS::File::Sale::TYPE_ALBUM;                   # override _productTypes hash
    }

    my $productType = $self->SUPER::productType();

    if ($productType) {
        return $productType;
    } else {
        my $type = $self->_getByFieldName('type');
        return $self->handleError( "Unable to determine product type from '$type'", RPS::DB::Item::SaleImportError::kErrorProductType );
    }
}

sub formatType {
    my $self = shift;

    my $type = $self->_getByFieldName('type');
    if ( $type =~ /mobile images/i ) {
        return $self->handleError( "Unsupported format_type '$type'", RPS::DB::Item::SaleImportError::kErrorNonqualifying );
    }

    if ( my $formatType = $self->SUPER::formatType() ) {
        return $formatType;
    } else {
        return $self->handleError( "Unable to determine format type from '$type'", RPS::DB::Item::SaleImportError::kErrorFormatType );
    }
}

sub trackName {
    my $self      = shift;
    my $trackName = $self->_getByFieldName('trackName');
    my $isrc      = $self->_getByFieldName('isrc');
    return ( $isrc eq '#' && $trackName =~ /^not assigned$/i ) ? undef : $trackName;
}

sub isrc {
    my $self      = shift;
    my $trackName = $self->_getByFieldName('trackName');
    my $isrc      = $self->_getByFieldName('isrc');
    return ( $isrc eq '#' && $trackName =~ /^not assigned$/i ) ? undef : $isrc;
}

sub mediaType {
    my $self = shift;

    my $mediaType = $self->SUPER::mediaType();

    if ($mediaType) {
        return $mediaType;
    } else {
        my $type = $self->_getByFieldName('type');
        return $self->handleError( "Unable to determine media type from '$type'", RPS::DB::Item::SaleImportError::kErrorMediaType );
    }
}

sub saleDates {
    my $self = shift;
    my $dateBegin;
    my $dateEnd;

    if ( exists $self->_fieldMap->{'dateBegin'} ) {
        my $dt = $self->_getByFieldName('dateBegin');
        return $self->_getDates( date_begin => $dt );
    } else {
        my $year  = $self->_getByFieldName('year');
        my $month = $self->_getByFieldName('month');

        my %months = (
            'JAN' => '01',
            'FEB' => '02',
            'MAR' => '03',
            'APR' => '04',
            'MAY' => '05',
            'JUN' => '06',
            'JUL' => '07',
            'AUG' => '08',
            'SEP' => '09',
            'OCT' => '10',
            'NOV' => '11',
            'DEC' => '12',
        );

        # we were originally getting 3 letter months (JAN) and the file switched to full month
        # names (January), so I added the following line to convert it
        $month = uc( substr( $month, 0, 3 ) );

        $dateBegin = sprintf( "%04d-%02d-%02d", $year, $months{$month}, 1 );
        $dateEnd = sprintf( "%04d-%02d-%02d", $year, $months{$month}, Days_in_Month( $year, $months{ uc($month) } ) );
    }
    return ( $dateBegin, $dateEnd );

}

sub countryCode {
    my $self = shift;
    return $self->{_countryCode};
}

sub currencyCode {
    my $self = shift;
    return $self->{_currencyCode};
}

sub price {
    my $self = shift;

    my $price = $self->_getByFieldName('price') || 0;
    return sprintf "%.8f", $price;
}

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

    # Follow the sign of the revenue...
    #
    if ( $p > 0 ) {
        return ( $u < 0 ) ? abs($u) : $u;
    } elsif ( $p < 0 ) {
        return ( $u < 0 ) ? $u : ( $u * -1 );
    }
    return $u;
}

sub unitPrice { abs( shift->SUPER::unitPrice ) }

sub _isValidSaleRecord {
    my $self = shift;

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

    return 0 if ( !$type );    # skip if summary line (no product type)

    # Skip footer section
    #
    if ( exists $self->_unverifiedFieldMap->{'month'} && exists $self->_unverifiedFieldMap->{'year'} ) {
        return 0 if ( $self->_getByFieldName('month') eq '' && $self->_getByFieldName('year') eq '' );
    } else {
        return 0 if ( $self->_getByFieldName('dateBegin') eq '' );
    }

    if ( $self->albumName || $self->upc || $self->trackName || $self->isrc ) {
        return 1;
    } else {

        # Ignore lines in the footer area
        #
        $self->fail("Missing product identifier") if ( $type !~ /Dist Fees/i && $type !~ /Total/i );
    }

    return $self->SUPER::_isValidSaleRecord();
}

sub _preProcess {
    my $self = shift;
    my %args = @_;
    my $sheet_names = $args{sheet_names};

    $self->SUPER::_preProcess(%args);

    my $fileName = $args{file}->OrigFileName();

    if ( $fileName =~ /_US(_).*\./i ) {
        $self->{_countryCode}  = 'US';
        $self->{_currencyCode} = 'USD';
    } elsif ( $fileName =~ /(_|\s)?(?:CA|CN|CANADA).*?\./i ) {
        $self->{_countryCode}  = 'CA';
        $self->{_currencyCode} = 'CAD';
    } else {
        return $self->handleError( "Unable to determine country code from " . $fileName,
            RPS::DB::Item::SaleImportError::kErrorNonqualifying );

    }

    # Error out if we see physical sales
    #
    my $i = 0;
    foreach my $sheet ( @{ $args{sheets} } ) {
        my $sheetName = $sheet_names->[$i++];

        if ( $sheetName =~ /physical/i ) {
            $self->fail("Detected physical worksheet while expecting digital only");
        }
    }

}

## MapFace Stuff

sub _mapFaceServiceID {
    return;
}

sub _mapFaceCountryCode {
    return;
}

sub _mapFaceProductType {
    return ('type');
}

sub _mapFaceFormatType {
    return ('type');
}

sub _mapFaceMediaType {
    return ('type');
}

sub _mapFaceCompatibleVersions {
    return ( 2, 6, 14, 19, 20, 31, 35 );
}

###
1;    # Play nicely.
###
