#---------------------------------------------------------------
# ____                   _ _         ____  _
#|  _ \ ___  _   _  __ _| | |_ _   _/ ___|| |__   __ _ _ __ ___
#| |_) / _ \| | | |/ _` | | __| | | \___ \| '_ \ / _` | '__/ _ \
#|  _ < (_) | |_| | (_| | | |_| |_| |___) | | | | (_| | | |  __/
#|_| \_\___/ \__, |\__,_|_|\__|\__, |____/|_| |_|\__,_|_|  \___|
#            |___/             |___/
#
# 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.
###
