package RPS::Import::GoogleMusic::v2;

use strict;

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

#public methods

sub _fieldMap {
    {
        # header
        countryCode => 'B',
        dateBegin   => 'C',
        dateEnd     => 'D',

        # detail
        type       => 'D',    # required in order to use _productTypes
        upc        => 'G',
        isrc       => 'H',
        artistName => 'I',
        trackName  => 'J',
        albumName  => 'K',

        units   => 'E',       # Quantity_Purchased
        returns => 'F',       # Quantity_Returned

        currencyCode => 'S',

        labelName => 'M',
        price     => 'R',
    }

}

sub _productTypes {
    {
        'a' => {
            productType => RPS::File::Sale::TYPE_ALBUM,
            formatType  => RPS::File::Sale::FORMAT_DOWNLOAD,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        't' => {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_DOWNLOAD,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
    };
}

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

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

    my $totalUnits = $units - ( abs $returns );
    return $totalUnits;
}

sub saleDates {
    my $self = shift;
    return ( $self->{_startDate}, $self->{_endDate} ) if ( $self->{_startDate} );    # from header; see _preProcess
}

sub countryCode {
    my $self = shift;
    return $self->{_countryCode} if ( $self->{_countryCode} );                       # from header; see _preProcess
}

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

    Log->info("Starting _preProcess");
    $self->SUPER::_preProcess(%args);

    my $distFee;

    my $getDateFlag;                                                                 # set if we find a date header
    my $getCountryFlag;                                                              # set if we find a country header

    foreach my $line ( @{ $args{lines} } ) {

        $self->{line} = $line;

        # Get the date from the header
        #
        if ( !$getDateFlag && $self->_getByFieldName('dateBegin') =~ /start_date/i ) {
            $getDateFlag = 1;
        } elsif ( !$self->{_startDate} && $getDateFlag ) {
            my $dt = $self->_getByFieldName('dateBegin');

            if ( $dt =~ /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/ )    # DD/MM/YYYY or MM/DD/YYYY
            {
                # Assume the date is US (MM/DD/YYYY), but we'll accomodate UK if needed
                #
                my $startDate = sprintf( "%04d-%02d-%02d", $3, $1, $2 );

                my $_endDate = $self->_getByFieldName('dateEnd');
                my ( $m, $d, $y ) = split( "/", $_endDate );
                my $endDate = sprintf( "%04d-%02d-%02d", $y, $m, $d );

                ( $startDate, $endDate ) = $self->_getDates( date_begin => $startDate, date_end => $endDate );

                $self->{_startDate} = $startDate;
                $self->{_endDate}   = $endDate;
            } elsif ( $dt =~ /^(\d{1,2})\/(\d{1,2})\/(\d{2})$/ )    # DD/MM/YY or MM/DD/YY
            {
                # Assume the date is US (MM/DD/YY), but we'll accomodate UK if needed
                #
                my $startDate = sprintf( "%04d-%02d-%02d", $3 + 2000, $1, $2 );

                my $_endDate = $self->_getByFieldName('dateEnd');
                my ( $m, $d, $y ) = split( "/", $_endDate );
                my $endDate = sprintf( "%04d-%02d-%02d", $y + 2000, $m, $d );

                ( $startDate, $endDate ) = $self->_getDates( date_begin => $startDate, date_end => $endDate );

                $self->{_startDate} = $startDate;
                $self->{_endDate}   = $endDate;
            } elsif ( $dt =~ /^(\d{4})-(\d{1,2})-(\d{1,2})$/ )    # YYYY-MM-DD
            {
                # Assume the date is US (MM/DD/YYYY), but we'll accomodate UK if needed
                #
                my $startDate = sprintf( "%04d-%02d-%02d", $1, $2, $3 );

                my $_endDate = $self->_getByFieldName('dateEnd');
                my ( $y, $m, $d ) = split( "-", $_endDate );
                my $endDate = sprintf( "%04d-%02d-%02d", $y, $m, $d );

                ( $startDate, $endDate ) = $self->_getDates( date_begin => $startDate, date_end => $endDate );

                $self->{_startDate} = $startDate;
                $self->{_endDate}   = $endDate;
            } else {
                print STDERR "_preProcess: WARNING: Unable to decode date '$dt'\n";
                $self->errstr("Unable to decode date '$dt' in header");
                return undef;
            }
        }

        # Get the country from the header
        #
        if ( !$getCountryFlag && $self->_getByFieldName('countryCode') =~ /reporting_region/i ) {
            $getCountryFlag = 1;
        } elsif ( !$self->{_countryCode} && $getCountryFlag ) {
            my $countryName = $self->_getByFieldName('countryCode');
            my $o           = Common::Country->Get($countryName);
            if ($o) {
                $self->{_countryCode} = $o->alpha2();
            } else {
                $self->errstr("Unknown country '$countryName' in header");
                return undef;
            }

        }

    }
}

# _getDates: helper method to process US or UK formatted dates.
#
# The end date is checked to see if it's a US or UK-formatted date, with
# the assumption that the day will be be greater than 12 (most likely
# between 28-31). The begin date determines the reporting period, which
# will span one month regardless of the end date specified in the file.
#
sub _getDates {
    my $self = shift;
    my %args = @_;

    my $_dateBegin = $args{date_begin};    # YYYY-MM-DD or YYYY-DD-MM
    my $_dateEnd   = $args{date_end};      # YYYY-MM-DD or YYYY-DD-MM

    my $dateBegin = $_dateBegin;

    my ( $beginYear, $beginMonth, $beginDay ) = split( "-", $_dateBegin );
    my ( $endYear,   $endMonth,   $endDay )   = split( "-", $_dateEnd );

    if ( $endMonth > 12 ) {
        $dateBegin = join( "-", $beginYear, $beginDay, $beginMonth );    # swap the month/day fields
    }

    return $self->SUPER::_getDates( date_begin => $dateBegin );
}

sub _isValidSaleRecord {
    my $self = shift;

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

    # skip lines with units but no revenue
    return unless ( $price != 0 && $self->units() );

    # use the default validation
    return unless ( $self->SUPER::_isValidSaleRecord );
}

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