package RPS::Import::GoogleMusic::v4;

use strict;

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

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

        # detail
        upc         =>  'D',
        isrc        =>  'E',
        artistName  =>  'A',
        trackName   =>  'B',
        albumName   =>  'C',
        labelName   =>  'I',
    }

}

sub _unverifiedFieldMap {
    {
        webPlays    => 'J',
        devicePlays => 'K',
        downloads   => 'L',
    }
}

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

sub productType{ RPS::File::Sale::TYPE_TRACK }

sub formatType{ RPS::File::Sale::FORMAT_STREAM }

sub mediaType{ RPS::DB::Item::MediaType::kMediaTypeAudio }

sub currencyCode{ 'USD' }

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

    return $webPlays + $downloads + $devicePlays;
}

sub unitPrice {
    my $self = shift;
    return $self->{_unitPrice};  # see _preProcess
}

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 $getDateFlag;    # set if we find a date header
    my $getCountryFlag; # set if we find a country header
    my $getRevenueFlag; # set if we find a revenue header

    my $foundDetails;   # set once we find the header for the details section

    my $revenue;
    my $units;

    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;
            }

        }

        # Get the total revenue from the header
        #
        if( !$getRevenueFlag && $self->_getByFieldName('price') =~ /^money_due_partner$/i )
        {
            $getRevenueFlag = 1;
        }
        elsif( $getRevenueFlag && ! defined $revenue )
        {
            $revenue = $self->_getByFieldName('price');
            $revenue =~ s/^\$//;
            $revenue =~ s/\,//g;

            $revenue =~ s/[^\d\.]//g;

            # While we're in the header, grab the currency code if we have a fieldmap
            # entry defined, otherwise default to 'USD' (see currencyCode method).
            #
            my $map = $self->_fieldMap();
            if( exists( $map->{'currencyCode'} ) )
            {
                my $ccode = $self->_getByFieldName('currencyCode');
                $self->{_currencyCode} = $ccode;
            }
        }

        # Count the total units if we're in the 'details' section
        #
        my $webPlays    = $self->_getByFieldName('webPlays');
        if( !$foundDetails && $webPlays =~ /^web_plays$/i )
        {
            $foundDetails = 1;
        }
        elsif( $foundDetails )
        {
            $units += $self->units;
        }

    }

    my $up = $revenue / $units;

    $self->{_unitPrice} = $revenue / $units;
}

# _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 );
}

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