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.
###
