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

package RPS::Import::Sony::v14;

use strict;

use Date::Calc qw(Days_in_Month);

use lib '/app/tools/common/lib';
use Common::Assert;
use Common::UTF8;
use Common::Country;
use Common::Log;

use lib '/app/tools/rps/lib';
use base 'RPS::Import::Importer';

sub _fieldMap {
    {
        dateBegin  => 'A',
        dateEnd    => 'A',
        artistName => 'C',
        upc        => 'B',
        albumName  => 'D',
        isrc       => 'B',
        trackName  => 'D',
        units      => 'I',    # Digital Net Qty
    };
}

sub _unverifiedFieldMap {
    {
        configurationType  => 'E',
        distributionManner => 'H',
        commission         => 'K',    # Commission %
        digitalNetValue    => 'J',    # Digital Net Value

        # The following are shifted on the NZ tab
        #
        unitsNZ           => 'J',    # Digital Net Qty
        digitalNetValueNZ => 'K',    # Digital Net Value
        commissionNZ      => 'L',    # Commission %
    };
}

sub _headerIdentifier { ( 'upc' => 'Catalog' ) }

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

sub currencyCode { 'AUD' }

sub saleDates {
    my $self  = shift;
    my $begin = $self->_getByFieldName('dateBegin');
    my $end   = $self->_getByFieldName('dateEnd');
    if ( $begin =~ /(\d{4})(\d{1,2})/ ) {
        $begin = sprintf( "%04d-%02d-%02d", $1, $2, 1 );
    } else {
        $self->fail("Unexpected date begin format: $begin");
    }
    if ( $end =~ /(\d{4})(\d{1,2})/ ) {
        $end = sprintf( "%04d-%02d-%02d", $1, $2, Days_in_Month( $1, $2 ) );
    } else {
        $self->fail("Unexpected date end format: $end");
    }

    return ( $begin, $end ) if ($begin);
}

sub productType {
    my $self   = shift;
    my $config = $self->_getByFieldName('configurationType');

    if (   $config =~ /^digital\s+(audio|video) track$/i
        || $config =~ /^mastertone$/i
        || $config =~ /^digital download (single|video) track$/i
        || $config =~ /^ringback tone$/i ) {
        return RPS::File::Sale::TYPE_TRACK;
    } else {
        return RPS::File::Sale::TYPE_ALBUM;
    }

    $self->fail("Unable to determine product type from config($config)");
}

my %formatMediaMap = (
    'digital audio longplay' => {
        'n' => {
            format => RPS::File::Sale::FORMAT_STREAM,
            media  => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'y' => {
            format => RPS::File::Sale::FORMAT_DOWNLOAD,
            media  => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
    },

    # there are intentionally two spaces between digital and audio in the next line
    'digital  audio longplay' => {
        'n' => {
            format => RPS::File::Sale::FORMAT_STREAM,
            media  => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'y' => {
            format => RPS::File::Sale::FORMAT_DOWNLOAD,
            media  => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
    },
    'digital audio track' => {
        'n' => {
            format => RPS::File::Sale::FORMAT_STREAM,
            media  => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'y' => {
            format => RPS::File::Sale::FORMAT_DOWNLOAD,
            media  => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
    },
    'digital video track' => {
        'n' => {
            format => RPS::File::Sale::FORMAT_STREAM,
            media  => RPS::DB::Item::MediaType::kMediaTypeVideo,
        },
    },
    'digital video longform' => {
        'n' => {
            format => RPS::File::Sale::FORMAT_STREAM,
            media  => RPS::DB::Item::MediaType::kMediaTypeVideo,
        },
        'y' => {
            format => RPS::File::Sale::FORMAT_DOWNLOAD,
            media  => RPS::DB::Item::MediaType::kMediaTypeVideo,
        },
    },
    'digital combo longform' => {
        'y' => {
            format => RPS::File::Sale::FORMAT_DOWNLOAD,
            media  => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
    },
    'mastertone' => {
        'n' => {
            format => RPS::File::Sale::FORMAT_STREAM,
            media  => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'y' => {
            format => RPS::File::Sale::FORMAT_RINGTONE,
            media  => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
    },
    'digital audio extended play' => {
        'y' => {
            format => RPS::File::Sale::FORMAT_DOWNLOAD,
            media  => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
    },
    'digital maxi single' => {
        'y' => {
            format => RPS::File::Sale::FORMAT_DOWNLOAD,
            media  => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
    },
    'digital combo' => {
        'y' => {
            format => RPS::File::Sale::FORMAT_DOWNLOAD,
            media  => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
    },
    'digital download longplay' => {
        'y' => {
            format => RPS::File::Sale::FORMAT_DOWNLOAD,
            media  => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'n' => {
            format => RPS::File::Sale::FORMAT_STREAM,
            media  => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
    },
    'digital audio bundle' => {
        'y' => {
            format => RPS::File::Sale::FORMAT_DOWNLOAD,
            media  => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
    },
    'digital download single track' => {
        'y' => {
            format => RPS::File::Sale::FORMAT_DOWNLOAD,
            media  => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'n' => {
            format => RPS::File::Sale::FORMAT_STREAM,
            media  => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
    },
    'digital download maxi single' => {
        'y' => {
            format => RPS::File::Sale::FORMAT_DOWNLOAD,
            media  => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
    },
    'digital download combo' => {
        'y' => {
            format => RPS::File::Sale::FORMAT_DOWNLOAD,
            media  => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
    },
    'ringback tone' => {
        'n' => {
            format => RPS::File::Sale::FORMAT_RINGTONE,
            media  => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
    },
    'digital download video track' => {
        'y' => {
            format => RPS::File::Sale::FORMAT_DOWNLOAD,
            media  => RPS::DB::Item::MediaType::kMediaTypeVideo,
        },
        'n' => {
            format => RPS::File::Sale::FORMAT_STREAM,
            media  => RPS::DB::Item::MediaType::kMediaTypeVideo,
        },
    },
);

sub _getFormatMedia {
    my $self   = shift;
    my $config = shift;
    my $dist   = shift;
    foreach my $_config ( keys %formatMediaMap ) {
        next if ( $config !~ /^$_config$/i );

        foreach my $_dist ( keys %{ $formatMediaMap{$_config} } ) {
            next if ( $dist !~ /^$_dist$/i );
            return ( $formatMediaMap{$_config}{$_dist}->{format}, $formatMediaMap{$_config}{$_dist}->{media} );
            last;
        }
    }
}

sub formatType {
    my $self   = shift;
    my $config = $self->_getByFieldName('configurationType');
    my $dist   = $self->_getByFieldName('distributionManner');

    my ( $formatType, $mediaType ) = $self->_getFormatMedia( $config, $dist );

    $self->fail("Unable to determine format type from config($config) distributionManner($dist)") if ( !$formatType );

    return $formatType;
}

sub mediaType {
    my $self   = shift;
    my $config = $self->_getByFieldName('configurationType');
    my $dist   = $self->_getByFieldName('distributionManner');

    my ( $formatType, $mediaType ) = $self->_getFormatMedia( $config, $dist );

    $self->fail("Unable to determine media type from config($config) distributionManner($dist)") if ( !$mediaType );

    return $mediaType;
}

sub albumName {
    my $self      = shift;
    my $albumName = $self->_getByFieldName('albumName');
    return $albumName if ( $self->productType eq RPS::File::Sale::TYPE_ALBUM );
}

sub upc {
    my $self = shift;
    my $upc  = $self->_getByFieldName('upc');
    return $upc if ( $self->productType eq RPS::File::Sale::TYPE_ALBUM );
}

sub trackName {
    my $self      = shift;
    my $trackName = $self->_getByFieldName('trackName');
    return $trackName if ( $self->productType eq RPS::File::Sale::TYPE_TRACK );
}

sub isrc {
    my $self = shift;
    my $isrc = $self->_getByFieldName('isrc');
    return $isrc if ( $self->productType eq RPS::File::Sale::TYPE_TRACK );
}

sub price {
    my $self            = shift;
    my $commission      = $self->_getByFieldName('commission');
    my $digitalNetValue = $self->_getByFieldName('digitalNetValue');

    if ( $self->{_countryCode} =~ /^nz$/i ) {
        $commission      = $self->_getByFieldName('commissionNZ');
        $digitalNetValue = $self->_getByFieldName('digitalNetValueNZ');
    }

    return $digitalNetValue * ( 1 - $commission );
}

sub units {
    my $self = shift;
    my $units;
    my $price;

    if ( $self->{_countryCode} =~ /^nz$/i ) {
        $units = $self->_getByFieldName('unitsNZ') || return;
        $price = $self->_getByFieldName('digitalNetValueNZ');
    } else {
        $units = $self->_getByFieldName('units') || return;
        $price = $self->_getByFieldName('digitalNetValue');
    }

    # The 'sign' of the units is driven by the price.
    # If the price is negative, we'll store negative units,
    # regardless of whether the units were positive or negative
    # in the sale file.  Accordingly, the price is always
    # positive.  This ensures that returns are recorded correctly.
    #
    if ( defined($price) ) {
        return $price < 0 ? abs($units) * -1 : $units;
    } else {
        return $units;
    }
}

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

# _processSheet is used to process a tab from the spreadsheet.
# Here, we're extracting the sale date and label information
# from the cells called out in the template.
#
sub _processSheet {
    my $self     = shift;
    my $sheet    = shift;
    my $sheetnum = shift;

    if ( $self->{sheetname} =~ /^digital sales (\w+)\s*$/i ) {
        $self->{_countryCode} = $1;

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

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