package RPS::Import::Thumbplay::v1;

use strict;

use lib '/app/tools/rps/lib';
use RPS::DB::Item::Client;

use lib '/app/tools/common/lib';
use Common::Country;
use Common::Consts;
use Common::Assert;
use Common::Log;
use Data::Dumper;

use lib '/app/tools/data_classes/lib';

use lib '/app/tools/rps/lib';
use RPS::Import::SaleRec;
use RPS::DB::Item::MediaType;
use RPS::File::Sale;

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

sub _fieldMap {
    {

    #-----------------------------------------------------------------
    # Note: the sales file has a blank first column, so in terms of
    # setting up the _fieldMap, we list the column numbers minus one
    # (e.g., the column numbers are zeroed at column B).
    #
    # The actual column information is added as a comment to make
    # it easier to identify the source columns. -ES
    #-----------------------------------------------------------------
        # Summary-related columns
        salesType             => 0, # B - Sales Type
        salesProduct          => 1, # C - Product
        salesUnits            => 2, # D - Units
        salesRevenue          => 9, # K - Sales Revenue
        salesStreamingRevenue => 8, # J (Merged column)

        # Detail-related columns
        dateBegin     => 8,   # J - Period Start Date
        dateEnd       => 9,   # K - Period End Date
        productType   => 5,   # G - Product
        formatType    => 1,   # C - Sales Channel
        artistName    => 6,   # H - Artist
        isrc          => 2,   # D - External Meta Data
        upc           => 4,   # E - UPC
        trackName     => 7,   # I - Title
        units         => 10,  # K - Units
    }
}

#--------------------------------------------------------------------
# productSummaryMap - maps product types found in the summary section
# to the product type in the detail section.
# Note: the following products are assumed to be tracks.
#--------------------------------------------------------------------
my %productSummaryMap = (
   'full track (tier ii)'  => 'ms2 download',
   'streaming'             => 'ms2 stream',
);

#---------------------------------------------------------------
# salesChannelMap - Maps the sales channel to an RPS format type
#---------------------------------------------------------------
my %salesChannelMap = (
   'ms2 download' => RPS::File::Sale::FORMAT_DOWNLOAD,
   'ms2 stream'   => RPS::File::Sale::FORMAT_STREAM,
);

#------------------------------------------------------------------------
# revenueMap - Maps the product type in the summary section to a sales
# channel in the detail section.
#
# For example for the product 'full track (tier ii)' in the summary
# section, we'd map the product type to 'ms2 download' (via the
# productSummaryMap, above), and store the associated revenue as:
#
# revenueMap{ 'ms2 download' }{ 'track' } => {
#    revenue => $revenue,
#    units => $units,
#    unit_price => $revenue/$units
# }
#------------------------------------------------------------------------
my %revenueMap;

sub _importLines
{
    my $self        = shift;
    my %args        = @_;
    my $fileObj     = $args{file};
    my $version     = $args{file}->VersionNum();
    my $fileName    = $args{file}->OrigFileName();
    my $serviceID   = $args{file}->ServiceID;
    my $sheet_count = 0;

    assert(defined $args{sheets});
    assert(defined $version);

    my $offsets     = $self->_fieldMap;
    my $sheet_names = $args{sheet_names};
    my $sheets      = $args{sheets};
    my $linenum     = 1;


    for (my $sheetIndex = 0; $sheetIndex < scalar @{$args{sheets}}; $sheetIndex++)
    {
        my $sheet = $sheets->[$sheetIndex];

        #--------------------------------------------------------------------
        # All data is assumed to be on the first sheet.
        #
        # We'll look for the summary section first.  Once it is found, we'll
        # set 'foundSummaryHeader' and process the summary data until we
        # encounter the detail section.  At that point, we'll set the
        # 'foundDetailHeader' flag and the subsequent sales data will be read
        # in.  We'll set the price information for each sale based on the
        # unit price information derived from the summary section.
        #--------------------------------------------------------------------
        next if( $sheetIndex > 0 );

        my $foundSummaryHeader = 0;
        my $foundDetailHeader  = 0;

        for( my $lineIndex = 0; $lineIndex < scalar @$sheet; $lineIndex++ )
        {
            $linenum = $lineIndex + 1;
            my $line = $sheet->[$lineIndex];

            if (! $foundSummaryHeader)
            {
                if ('Sales Type' eq $line->[$offsets->{format_type}])
                {
                    $foundSummaryHeader = 1;
                }
                next;
            }

            if ( $foundSummaryHeader )
            {

                if ( !$foundDetailHeader )
                {
                    #-------------------------
                    # Process the summary data
                    #-------------------------

                    #==================================================================
                    # NOTE: The revenue column for Subscription/(Streaming) is slightly
                    # different than for Subscription/(anything_but_streaming) or
                    # A La Carte/(anything).  This is due to the merged cell for the
                    # 'Proportionate Share' data with Subscription/Streaming.
                    #==================================================================
                    my $salesType             = $line->[$offsets->{salesType}];
                    my $salesProduct          = $line->[$offsets->{salesProduct}];
                    my $salesUnits            = $line->[$offsets->{salesUnits}];

                    my $salesRevenue          = $line->[$offsets->{salesRevenue}];
                    my $salesStreamingRevenue = $line->[$offsets->{salesStreamingRevenue}];

                    if ('Row number' eq $line->[$offsets->{format_type}])
                    {
                        $foundDetailHeader = 1;
                        next;  # keep looking for detail section...
                    }
                    elsif ( $salesType && ($salesType ne 'Sales Type') && $salesProduct && $salesUnits )
                    {
                        #---------------------------------------------------------
                        # Store the units/revenue data for the given sales_type &
                        # product combination. 
                        #
                        # Per the template, the initial version of the importer
                        # will only accept 'Full Track (Tier II)' and 'Streaming'
                        # as valid sales types, and those are only valid for track
                        # sales.
                        #---------------------------------------------------------
                        my $mappedProduct = $productSummaryMap{ lc $salesProduct };

                        if ( $mappedProduct )
                        {
                            my $_revenue   = $salesRevenue;
                            $_revenue      = $salesStreamingRevenue if ( $salesProduct =~ m/^streaming$/i );
                            my $_unitPrice = $_revenue / $salesUnits;

                            $revenueMap{ $mappedProduct }{ track } = {
                                units      => $salesUnits,
                                revenue    => $_revenue,
                                unit_price => $_unitPrice
                            };
                        }
                        else
                        {
                            print STDERR "Unknown sales product '$salesProduct' detected\n"; # XXX
                            $self->errstr("Line $linenum: unknown sales product");
                            return undef;
                        }
                    }

                }
                else
                {
                    #------------------------
                    # Process the detail data
                    #------------------------

                    my( $dateBegin, $dateEnd) = $self->_getDates(
                        date_begin => $line->[$offsets->{dateBegin}],
                        date_end   => $line->[$offsets->{dateEnd}]
                        );

                    my $artist       = $line->[$offsets->{artistName}];
                    my $units        = $line->[$offsets->{units}];
                    my $formatType   = $line->[$offsets->{formatType}];
                    my $_productType = $line->[$offsets->{productType}];

                    my $productFormat = $salesChannelMap{ lc $formatType };
                    if( !$productFormat )
                    {
                        print STDERR "ERROR: line $linenum: Unable to map sales channel '$formatType'\n";
                        $self->errstr("Line $linenum: unknown sales channel");
                        return undef;
                    }

                    my $unitPrice;
                    my $upc;
                    my $isrc;
                    my $albumTitle;
                    my $trackTitle;
                    my $productType;
                    my $_title = $line->[$offsets->{trackName}];

                    if ( lc $_productType eq 'track' )
                    {
                       $trackTitle = $_title;
                       $isrc = $line->[$offsets->{isrc}];
                       $productType = RPS::File::Sale::TYPE_TRACK;

                       if ( exists $revenueMap{$formatType}{track} )
                       {
                           $unitPrice = $revenueMap{$formatType}{track}->{unit_price};
                       }
                       else
                       {
                           print STDERR "ERROR: line $linenum: Unable to determine unit price for track format($formatType)\n";
                           $self->errstr("Line $linenum: unable to determine unit price");
                           return undef;
                       }
                    }
                    elsif( lc $_productType eq 'album' )
                    {
                       $albumTitle = $_title;
                       $upc = $line->[$offsets->{upc}];
                       $productType = RPS::File::Sale::TYPE_ALBUM;
                       if ( exists $revenueMap{$formatType}{album} )
                       {
                           $unitPrice = $revenueMap{$formatType}{album}->{unit_price};
                       }
                       else
                       {
                           print STDERR "ERROR: line $linenum: Unable to determine net price for album format($formatType)\n";
                           $self->errstr("Line $linenum: unable to determine unit price");
                           return undef;
                       }
                    }
                    else
                    {
                        print STDERR "ERROR: line $linenum: Unknown product type '$_productType'\n";
                        $self->errstr("Line $linenum: unknown product type");
                        return undef;
                    }

                    my $mediaType = RPS::DB::Item::MediaType::kMediaTypeAudio;


                    if ( ($units || $artist) && $unitPrice && ('' ne $albumTitle || '' ne $trackTitle) )
                    {

                        my $sale = RPS::Import::SaleRec->new();
                        $sale->mediaType($mediaType);
                        $sale->productType($productType);
                        $sale->formatType($productFormat);
                        $sale->dateBegin($dateBegin);
                        $sale->dateEnd($dateEnd);
                        $sale->trackName($trackTitle) if ( $trackTitle );
                        $sale->albumName($albumTitle) if ( $albumTitle );
                        $sale->artistName($artist);
                        $sale->upc($upc)   if ( $upc );
                        $sale->isrc($isrc) if ( $isrc );
                        $sale->units($units);
                        $sale->price($unitPrice);
                        $sale->countryCode('US');
                        $sale->currencyCode('USD');
                        $sale->lineNum($linenum);

                        $self->_insertSale(sale => $sale);
                    }
                }
            }


        }
    }

    return $linenum;
}

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