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

package RPS::Import::Alliance::v1;

use strict;

use Date::Calc qw(Days_in_Month);

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

use lib '/app/tools/rps/lib';

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

# Note: the verified _fieldMap is the same for versions 1 and 2
#
sub _fieldMap {
    my $self      = shift;
    my $version   = $self->_version;
    my %field_map = (
        1 => {

            # detail section of each sheet
            #
            labelName       => 'B',
            artistName      => 'L',
            clientProductID => 'J',
            wholesalePrice  => 'O',
            upc             => 'K',
            albumName       => 'M',
            countryCode     => 'V',
            dateBegin       => 'T',

            # Top section only (returns)
            #
            returns        => 'N',
            returnsRevenue => 'R',

            # Bottom section only (sales)
            #
            sales        => 'N',
            salesRevenue => 'P',
        },
        2 => {

            # detail section of each sheet
            #
            labelName       => 'B',
            artistName      => 'L',
            clientProductID => 'J',
            wholesalePrice  => 'O',
            upc             => 'K',
            albumName       => 'M',
            countryCode     => 'V',
            dateBegin       => 'T',

            # Top section only (returns)
            #
            returns        => 'N',
            returnsRevenue => 'R',

            # Bottom section only (sales)
            #
            sales        => 'N',
            salesRevenue => 'P',
        },
        3 => {

            # detail section of each sheet
            #
            labelName       => 'B',
            artistName      => 'P',
            clientProductID => 'N',
            wholesalePrice  => 'R',
            upc             => 'O',
            albumName       => 'P',
            countryCode     => 'AC',
            dateBegin       => 'W',

            # Top section only (returns)
            #
            returns        => 'Q',
            returnsRevenue => 'U',

            # Bottom section only (sales)
            #
            sales        => 'Q',
            salesRevenue => 'S',
        },
    );
    return $field_map{$version};
}

use constant kReturnsSection => 1;
use constant kSalesSection   => 2;

sub _unverifiedFieldMap {
    my $self      = shift;
    my $version   = $self->_version;
    my %field_map = (
        1 => {

            # Bottom section only (sales)
            #
            distFee => 'Q',
        },
        2 => {

            # Bottom section only (sales)
            #
            distFee => 'S',
        },
        3 => {

            # Bottom section only (sales)
            #
            distFee => 'T',
        },
    );
    return $field_map{$version};
}

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

sub currencyCode { 'USD'; }

sub channel { RPS::File::Sale::CHANNEL_RETAIL; }

sub priceLevel { RPS::File::Sale::PLEVEL_FULL; }

sub physical { 1 }

sub clientProductID {
    my $self = shift;
    my $name = $self->_getByFieldName('clientProductID');
    if ( $name =~ /(\w+)\.(\w+)$/ ) {
        return $1;    # strip off trailing suffix
    }
    return $name;
}

sub countryCode {
    my $self  = shift;
    my $cname = $self->_getByFieldName('countryCode');

    my $o = Common::Country->Get($cname);

    return ( defined $o ) ? $o->alpha2() : $cname;
}

sub saleDates {
    my $self = shift;

    my $dt = $self->_getByFieldName('dateBegin');
    my $sdate;
    my $edate;

    # Make sure that dates encompass the entire month
    #
    if ( $dt =~ /(\d{4})-(\d{1,2})-(\d{1,2})/ )    # YYYY-MM-DD
    {
        $sdate = sprintf( "%04d-%02d-%02d", $1, $2, 1 );
        $edate = sprintf( "%04d-%02d-%02d", $1, $2, Days_in_Month( $1, $2 ) );
    }
    return ( $sdate, $edate );
}

sub artistName {
    my $self = shift;
    my $name = $self->_getByFieldName('artistName');
    if ( $self->version == 3 ) {
        my ( $artist, $album ) = split( "/", $name );
        $name = $artist;
        $name =~ s/\s*$//;
    }
    return $name;
}

sub albumName {
    my $self = shift;
    my $name = $self->_getByFieldName('albumName');
    if ( $self->version == 3 ) {
        my ( $artist, $album ) = split( "/", $name );
        $name = $album;
        $name =~ s/^\s*//;
    }
    return $name;
}

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

    if ( $config =~ /\.2$/i ) {
        return RPS::File::Sale::TYPE_CD;
    } elsif ( $config =~ /\.1$/i ) {
        return RPS::File::Sale::TYPE_LP;
    }
    $self->fail("Unable to determine config from product($config)");
}

sub sales {
    my $self = shift;
    if ( $self->{_section} == kSalesSection ) {
        my $grossRevenue = $self->_getByFieldName('salesRevenue') || 0;
        my $distFee      = $self->_getByFieldName('distFee')      || 0;
        my $netRev       = $grossRevenue - $distFee;

        # handle returns in the sales section
        #
        return ( $netRev > 0 ) ? abs( $self->_getByFieldName('sales') || 0 ) : 0;
    }
    return 0;
}

sub salesRevenue {
    my $self = shift;
    if ( $self->{_section} == kSalesSection ) {
        my $grossRevenue = $self->_getByFieldName('salesRevenue');
        my $distFee      = $self->_getByFieldName('distFee');
        my $netRev       = $grossRevenue - $distFee;

        # handle returns in the sales section
        #
        return ( $netRev > 0 ) ? $netRev : 0;
    }
    return 0;
}

sub returns {
    my $self = shift;
    if ( $self->{_section} == kReturnsSection ) {

        # a return is assumed to be a return...
        #
        return abs( $self->_getByFieldName('returns') || 0 );
    } else {

        # ... however a sale may also be a return
        #
        my $grossRevenue = $self->_getByFieldName('salesRevenue') || 0;
        my $distFee      = $self->_getByFieldName('distFee')      || 0;
        my $netRev       = $grossRevenue - $distFee;
        my $sales        = $self->_getByFieldName('sales') || 0;

        return ( $netRev < 0 ) ? abs($sales) : 0;
    }
}

sub returnsRevenue {
    my $self = shift;
    if ( $self->{_section} == kReturnsSection ) {

        # a return is assumed to be a return...
        #
        return abs( $self->_getByFieldName('returnsRevenue') );
    } else {

        # ... however a sale may also be a return
        #
        my $grossRevenue = $self->_getByFieldName('salesRevenue');
        my $distFee      = $self->_getByFieldName('distFee');
        my $netRev       = $grossRevenue - $distFee;

        return ( $netRev < 0 ) ? abs($netRev) : 0;
    }

}

sub totalRevenue {
    my $self = shift;
    return $self->salesRevenue - $self->returnsRevenue;
}

sub _isValidSaleRecord {
    my $self = shift;

    # The line is valid if it has sales or returns, and has an album title
    #
    return ( ( $self->sales != 0 || $self->returns != 0 ) && $self->albumName );
}

sub _processLine {
    my $self  = shift;
    my $label = $self->_getByFieldName('labelName');
    $self->{_section} = kSalesSection if ( $label =~ /Return(?:s)? Total/i );    # toggle next section
    return $self->SUPER::_processLine(@_);
}

sub _containsMonth {
    my $self = shift;
    my $name = shift;
    return 1 if ( $name =~ /^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)[a-z]* \d{4}/i );
}

# _processSheet is used to process a tab from the spreadsheet.  We only process
# tabs with month-year information in them.
#
sub _processSheet {
    my $self     = shift;
    my $sheet    = shift;
    my $sheetnum = shift;

    my %args = @_;

    # Reset sheet variables
    #
    $self->{_section} = kReturnsSection;    # first section on each sheet

    if ( $self->_containsMonth( $self->{sheetname} ) ) {
        return $self->SUPER::_processSheet( $sheet, $sheetnum );
    }
}

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