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

package RPS::Import::Bandcamp::v2;

use strict;

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

use RPS::Import::Bandcamp::BandcampBase;
use base 'RPS::Import::Bandcamp::BandcampBase';

sub _fieldMap {
    my $self      = shift;
    my $version   = $self->_version;
    my %field_map = (
        2 => {
            countryCode      => 'AC',
            dateBegin        => 'A',
            productType      => 'C',
            formatType       => 'U',
            artistName       => 'E',
            serviceProductID => 'X',
            upc              => 'Y',
            albumName        => 'D',
            isrc             => 'Z',
            trackName        => 'D',
            units            => 'H',
            currencyCode     => 'F',
            price            => 'T',
        },
        6 => {
            countryCode      => 'AI',
            dateBegin        => 'A',
            productType      => 'C',
            formatType       => 'AA',
            artistName       => 'E',
            serviceProductID => 'AD',
            upc              => 'AE',
            albumName        => 'D',
            isrc             => 'AF',
            trackName        => 'D',
            units            => 'H',
            currencyCode     => 'F',
            price            => 'Z',
        },
        7 => {
            countryCode      => 'AG',
            dateBegin        => 'A',
            productType      => 'C',
            formatType       => 'Y',
            artistName       => 'E',
            serviceProductID => 'AB',
            upc              => 'AC',
            albumName        => 'D',
            isrc             => 'AD',
            trackName        => 'D',
            units            => 'H',
            currencyCode     => 'F',
            price            => 'X',
        },
        10 => {
            countryCode      => 'AI',
            dateBegin        => 'A',
            productType      => 'C',
            formatType       => 'AA',
            artistName       => 'E',
            serviceProductID => 'AD',
            upc              => 'AE',
            albumName        => 'D',
            isrc             => 'AF',
            trackName        => 'D',
            units            => 'H',
            currencyCode     => 'F',
            price            => 'Z',
        },
        12 => {
            countryCode      => 'AU',
            dateBegin        => 'A',
            productType      => 'C',
            formatType       => 'AA',
            artistName       => 'E',
            serviceProductID => 'AD',
            upc              => 'AE',
            albumName        => 'D',
            isrc             => 'AF',
            trackName        => 'D',
            units            => 'H',
            currencyCode     => 'F',
            price            => 'Z',
        },
        13 => {
            countryCode      => 'AH',
            dateBegin        => 'A',
            productType      => 'C',
            formatType       => 'Y',
            artistName       => 'E',
            serviceProductID => 'AC',
            upc              => 'AD',
            albumName        => 'D',
            isrc             => 'AE',
            trackName        => 'D',
            units            => 'H',
            currencyCode     => 'F',
            price            => 'X',
        },
        14 => {
            countryCode      => 'AI',
            dateBegin        => 'A',
            productType      => 'C',
            formatType       => 'Z',
            artistName       => 'E',
            serviceProductID => 'AD',
            upc              => 'AE',
            albumName        => 'D',
            isrc             => 'AF',
            trackName        => 'D',
            units            => 'H',
            currencyCode     => 'F',
            price            => 'Y',
        },
        16 => {
            countryCode      => 'AL',
            dateBegin        => 'A',
            productType      => 'C',
            formatType       => 'AC',
            artistName       => 'E',
            serviceProductID => 'AF',
            upc              => 'AG',
            albumName        => 'D',
            isrc             => 'AH',
            trackName        => 'D',
            units            => 'H',
            currencyCode     => 'F',
            price            => 'AB',
        },
        17 => {
            countryCode      => 'AI',
            dateBegin        => 'A',
            productType      => 'C',
            formatType       => 'Z',
            artistName       => 'E',
            serviceProductID => 'AC',
            upc              => 'AD',
            albumName        => 'D',
            isrc             => 'AE',
            trackName        => 'D',
            units            => 'H',
            currencyCode     => 'F',
            price            => 'Y',
        },
        18 => {
            countryCode      => 'AV',
            dateBegin        => 'A',
            productType      => 'C',
            formatType       => 'Z',
            artistName       => 'E',
            serviceProductID => 'AD',
            upc              => 'AE',
            albumName        => 'D',
            isrc             => 'AF',
            trackName        => 'D',
            units            => 'H',
            currencyCode     => 'F',
            price            => 'Y',
        },
        21 => {
            countryCode      => 'AI',
            dateBegin        => 'A',
            productType      => 'C',
            formatType       => 'Z',
            artistName       => 'E',
            serviceProductID => 'AC',
            upc              => 'AD',
            albumName        => 'D',
            isrc             => 'AE',
            trackName        => 'D',
            units            => 'H',
            currencyCode     => 'F',
            price            => 'Y',
        },
        22 => {
            countryCode      => 'AT',
            dateBegin        => 'A',
            productType      => 'C',
            formatType       => 'Y',
            artistName       => 'E',
            upc              => 'AC',
            albumName        => 'D',
            isrc             => 'AD',
            trackName        => 'D',
            units            => 'H',
            currencyCode     => 'F',
            price            => 'X',
        },
    );
    return $field_map{$version};
}

sub _headerIdentifier { ( upc => 'upc' ) }
sub mediaType { RPS::DB::Item::MediaType::kMediaTypeAudio }

sub productType {
    my $self = shift;
    my $type = $self->_getByFieldName('productType') || return;

    if ( $type =~ /^track$/i ) {
        return RPS::File::Sale::TYPE_TRACK;
    } elsif ( $type =~ /^album$/i || $type =~ /^bundle$/i ) {
        return RPS::File::Sale::TYPE_ALBUM;
    } elsif ( $type =~ /^(refund|reversal)$/i ) {
        my $isrc = $self->_getByFieldName('isrc');
        if ( $isrc && '' ne $isrc ) {
            return RPS::File::Sale::TYPE_TRACK;
        } else {
            return RPS::File::Sale::TYPE_ALBUM;
        }
    }

    $self->fail("Could not parse product type from '$type'");
}

sub formatType {
    my $self   = shift;
    my $format = $self->_getByFieldName('formatType');
    if ( $format =~ /^digital (download|bundle)$/i ) {
        return RPS::File::Sale::FORMAT_DOWNLOAD;
    }

    $self->fail("Could not parse format type from '$format'");
}

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

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

sub isrc {
    my $self = shift;

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

    if ($isrc) {
        return Common::Util::normalize_isrc($isrc);
    }
}

sub upc {
    my $self = shift;

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

    if ($upc) {
        return Common::Util::normalize_upc($upc);
    }
}

sub _getDateBegin {
    my $self = shift;
    my $date = $self->_getByFieldName('dateBegin');

    # 04/01/2016 19:54
    if ( $date =~ /(\d{1,2})\/\d{1,2}\/(\d{4})/ ) {
        $date = sprintf( "%04d-%02d-01", $2, $1 );
    }

    # 12/1/14 10:46am
    elsif ( $date =~ /(\d{1,2})\/\d{1,2}\/(\d{2})/ ) {
        my $month = $1;
        if ( $month < 10 ) {
            $month = "0" . $month;
        }
        my $year = "20" . $2;
        $date = $year . "-" . $month . "-01";
    }

    return $date

}

sub units {
    my $self  = shift;
    my $units = int($self->_getByFieldName('units')) || return;
    my $price = $self->_getByFieldName('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.
    #
    # Note: if the productType is 'refund', we'll treat the units as a refund.
    #
    my $type = $self->_getByFieldName('productType');
    if ( defined($price) ) {
        return ( $price < 0 || $type =~ /^refund$/i ) ? abs($units) * -1 : $units;
    } else {
        return ( $type =~ /^refund$/i ) ? abs($units) * -1 : $units;
    }
}

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

sub _isValidSaleRecord {
    my $self        = shift;
    my $units       = $self->_getByFieldName('units');
    my $price       = $self->_getByFieldName('price');
    my $productType = $self->_getByFieldName('productType');

    # Skip any line with 'payout' as the product type
    return undef if ( $productType && $productType =~ /^payout$/i );

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

sub _processSheet {
    my ($self, $sheet, $sheetnum) = @_;
    
    if ( $self->_version && $self->_version == 21 ) {
        # We only process the 'Digital' for version 21
        return unless $self->{sheetname} =~ /^Digital$/i;
    }
    
    return $self->RPS::Import::Importer::_processSheet( $sheet, $sheetnum );
}

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