package RPS::Import::OrchardPub;

use strict;

use Math::BigFloat;
use lib '/app/tools/common/lib';
use Common::Util qw(normalize_upc normalize_isrc);

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

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

my %field_map = (
    3 => {
        date      => 0,
        service   => 1,
        vendor_id => 2,
        upc       => 3,
        catno     => 4,
        label     => 5,
        artist    => 6,
        album     => 7,
        track     => 8,
        isrc      => 9,
        disc_no   => 10,
        track_no  => 11,
        units     => 12,
        format    => 15,
        gross     => 16,
        split_fee => 17,
        ring_fee  => 19,
        pub_fee   => 20,
        oms_fee   => 21,
    },
    7 => {
        date      => 2,
        service   => 3,
        country   => 4,
        vendor_id => 5,
        upc       => 6,
        catno     => 7,
        label     => 8,
        artist    => 9,
        album     => 10,
        track     => 11,
        isrc      => 12,
        disc_no   => 13,
        track_no  => 14,
        units     => 15,
        format    => 18,
        gross     => 17,
        split_fee => 20,
        ring_fee  => 22,
        pub_fee   => 23,
        oms_fee   => 24,
    },
    8 => {
        artist => 0,
        album  => 1,
        catno  => 2,
    },
    9 => {
        date      => 0,
        service   => 2,
        country   => 3,
        vendor_id => 4,
        upc       => 4,
        catno     => 6,
        label     => 7,
        artist    => 8,
        album     => 9,
        track     => 10,
        isrc      => 11,
        disc_no   => 12,
        track_no  => 13,
        units     => 14,
        format    => 17,
        gross     => 20,
        split_fee => 19,
        ring_fee  => 21,
        pub_fee   => 22,
        oms_fee   => 23,
    },
    13 => {
        date      => 1,
        service   => 2,
        country   => 3,
        upc       => 5,
        vendor_id => 4,
        catno     => 6,
        label     => 7,
        artist    => 8,
        album     => 9,
        track     => 10,
        isrc      => 11,
        disc_no   => 12,
        track_no  => 13,
        units     => 14,
        format    => 17,
        gross     => 20,
        split_fee => 19,
        ring_fee  => 21,
        pub_fee   => 22,
        oms_fee   => 23,
    },
);

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

    my $sheets = $args{sheets};
    return undef unless ($sheets);

    my $sheet_names = $args{sheet_names};
    my $sheet_count = 0;
    my $version     = $self->_version;
    my $offsets     = $field_map{$version};

    my %errors  = ();
    my $linenum = 1;

    foreach my $lines (@$sheets) {

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

            my $currencyCode = $line->[ $offsets->{'currency_code'} ] if ( exists $offsets->{currency_code} );

            my $countryName = $line->[ $offsets->{'country'} ] if ( exists $offsets->{country} );

            if ( $countryName && $countryName =~ m/territory/i ) {
                $linenum++;
                next;
            }

            my ( $serviceID, $countryCode );
            my $serviceName = $line->[ $offsets->{'service'} ];
            if ( '' eq $countryName && '' eq $serviceName ) {
                $linenum++;
                next;
            }

            ( $serviceID, $countryCode ) = $self->_parseServiceCountry( $line->[ $offsets->{'service'} ], \%errors ) if ( $version == 3 );
            ( $serviceID, $countryCode ) =
              $self->_parseServiceCountry( $line->[ $offsets->{'service'} ] . ":::" . $line->[ $offsets->{'country'} ], \%errors )
              if ( $version != 3 && $line->[ $offsets->{service} ] ne "" );

            unless ( $serviceID && $countryCode ) {
                print STDERR "Missing service and/or country: "
                  . $line->[ $offsets->{service} ] . " s:"
                  . $serviceID . " c:"
                  . $countryCode
                  . " line:"
                  . $linenum . "\n";
                $self->errstr( "Missing service and/or country: "
                      . $line->[ $offsets->{service} ] . " s:"
                      . $serviceID . " c:"
                      . $countryCode
                      . " line:"
                      . $linenum );
                return undef;
            }

            my $vendor_id = $line->[ $offsets->{'vendor_id'} ];

            my $upc = normalize_upc( $line->[ $offsets->{'upc'} ] ) || '';
            if ( ( $version == 13 || $version == 14 || $version == 15 ) && !$upc ) {
                $upc = $vendor_id || '';
            }

            my $catno     = $line->[ $offsets->{'catno'} ];
            my $label     = $line->[ $offsets->{'label'} ];
            my $artist    = $line->[ $offsets->{'artist'} ];
            my $album     = $line->[ $offsets->{'album'} ];
            my $track     = $line->[ $offsets->{'track'} ];
            my $isrc      = normalize_isrc( $line->[ $offsets->{'isrc'} ] ) || '';
            my $disc_no   = $line->[ $offsets->{'disc_no'} ];                        ## unused
            my $track_num = $line->[ $offsets->{'track_no'} ];

            my $units = $self->numeric( $line->[ $offsets->{'units'} ] );
            $units =~ s/\.0+$//g;                                                    # remove any trailing decimal zeroes

            my $format = $line->[ $offsets->{'format'} ];
            my $type;

            my $gross = $line->[ $offsets->{'gross'} ];

            # If the template doesn't have the split/ring/pub/oms fields, then
            # default them to zero.
            #
            my $split_fee = ( defined $offsets->{'split_fee'} ) ? $line->[ $offsets->{'split_fee'} ] : 0;
            my $ring_fee  = ( defined $offsets->{'ring_fee'} )  ? $line->[ $offsets->{'ring_fee'} ]  : 0;
            my $pub_fee   = ( defined $offsets->{'pub_fee'} )   ? $line->[ $offsets->{'pub_fee'} ]   : 0;
            my $oms_fee   = ( defined $offsets->{'oms_fee'} )   ? $line->[ $offsets->{'oms_fee'} ]   : 0;

            $gross =~ s/\$//g;
            $gross =~ s/,//g;
            $split_fee =~ s/\$//g;
            $ring_fee =~ s/\$//g;
            $pub_fee =~ s/\$//g;
            $oms_fee =~ s/\$//g;

            $units *= -1 if ( $units < 0 );
            my $price;
            $ring_fee *= -1 if ( $ring_fee < 0 );
            $pub_fee  *= -1 if ( $pub_fee < 0 );
            $oms_fee  *= -1 if ( $oms_fee < 0 );
            if ( $gross < 0 ) {
                $gross *= -1;
                if ( 0 != $units ) {
                    $price = Math::BigFloat->new( $version < 9 ? $gross * $split_fee - $ring_fee - $pub_fee - $oms_fee : $gross );
                    $price /= $units;
                    $units *= -1 if ( $units > 0 );
                } else {
                    $price = 0;
                }
            } else {
                if ( 0 != $units ) {
                    $price =
                      Math::BigFloat->new( $version < 9
                        ? $gross * $split_fee - $ring_fee - $pub_fee - $oms_fee
                        : ( $gross - $ring_fee - $pub_fee - $oms_fee ) );
                    $price /= $units;
                } else {
                    $price = 0;
                }

                # if the calculated price is negative, make this a return
                #
                if ( $price < 0 ) {
                    $units *= -1 if ( $units > 0 );
                    $price *= -1;
                }
            }

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

            if ( $format eq "DT" ) {
                $format = RPS::File::Sale::FORMAT_DOWNLOAD;
                $type   = RPS::File::Sale::TYPE_TRACK;
            } elsif ( $format eq "UA" ) {
                $format = RPS::File::Sale::FORMAT_DOWNLOADUPGRADE;
                $type   = RPS::File::Sale::TYPE_ALBUM;
            } elsif ( $format eq "TD" ) {
                $format = RPS::File::Sale::FORMAT_TETHERED;
                $type   = RPS::File::Sale::TYPE_TRACK;
            } elsif ( $format eq "DV" ) {
                $format    = RPS::File::Sale::FORMAT_DOWNLOAD;
                $type      = RPS::File::Sale::TYPE_ALBUM;
                $mediaType = RPS::DB::Item::MediaType::kMediaTypeVideo;
            } elsif ( $format eq "DA" ) {
                $format = RPS::File::Sale::FORMAT_DOWNLOAD;
                $type   = RPS::File::Sale::TYPE_ALBUM;
            } elsif ( $format eq "DR" ) {
                $format = RPS::File::Sale::FORMAT_RINGTONE;
                $type   = RPS::File::Sale::TYPE_TRACK;
            } elsif ( $format eq "RB" ) {
                $format = RPS::File::Sale::FORMAT_RINGTONE;    # Was Ringback; See Case 34
                $type   = RPS::File::Sale::TYPE_TRACK;
            } elsif ( $format eq "S" ) {
                $format = RPS::File::Sale::FORMAT_STREAM;
                $type   = RPS::File::Sale::TYPE_TRACK;
            } elsif ( $format eq "UT" ) {
                $format = RPS::File::Sale::FORMAT_DOWNLOADUPGRADE;
                $type   = RPS::File::Sale::TYPE_TRACK;
            } elsif ( $format eq "AS" ) {
                $format = RPS::File::Sale::FORMAT_STREAM;
                $type   = RPS::File::Sale::TYPE_TRACK;
            } elsif ( $format eq "NR" ) {
                $format = RPS::File::Sale::FORMAT_STREAM;
                $type   = RPS::File::Sale::TYPE_TRACK;
            } elsif ( $format eq "TA" ) {
                $format = RPS::File::Sale::FORMAT_TETHERED;
                $type   = RPS::File::Sale::TYPE_ALBUM;
            } elsif ( $format eq "AV" ) {
                $format    = RPS::File::Sale::FORMAT_STREAM;              # was FORMAT_VIDEOSTREAM (FB1324)
                $type      = RPS::File::Sale::TYPE_TRACK;
                $mediaType = RPS::DB::Item::MediaType::kMediaTypeVideo;
            } elsif ( $format eq "VR" ) {
                $format    = RPS::File::Sale::FORMAT_TETHERED;
                $type      = RPS::File::Sale::TYPE_ALBUM;
                $mediaType = RPS::DB::Item::MediaType::kMediaTypeVideo;
            } elsif ( $format eq "CL" ) {
                $format = RPS::File::Sale::FORMAT_STREAM;
                $type   = RPS::File::Sale::TYPE_TRACK;
            } elsif ( $format eq "NS" ) {
                $format = RPS::File::Sale::FORMAT_STREAM;
                $type   = RPS::File::Sale::TYPE_TRACK;
            } elsif ( $format eq "SF" ) {
                $format = RPS::File::Sale::FORMAT_STREAM;
                $type   = RPS::File::Sale::TYPE_TRACK;
            } elsif ( $format eq "FP" ) {
                $format    = RPS::File::Sale::FORMAT_STREAM;
                $type      = RPS::File::Sale::TYPE_TRACK;
                $mediaType = RPS::DB::Item::MediaType::kMediaTypeAudio;
            } elsif ( $format ne "" ) {
                $self->errstr("unknown format '$format' in line $linenum");
                return undef;
            }

            # RSD-11462
            if ( $serviceID == Client::Service::DSP_SOUNDEXCHANGE ) {
                $format = RPS::File::Sale::FORMAT_NON_EPHEMERAL;
            }

            if ( $units && $serviceID && ( $type eq RPS::File::Sale::TYPE_TRACK && ( $track || $isrc ) )
                || ( $type eq RPS::File::Sale::TYPE_ALBUM && ( $album || $upc ) ) ) {
                my ( $dateBegin, $dateEnd ) = $self->_getDates( $line->[ $offsets->{'date'} ] );

                unless ( $dateBegin && $dateEnd ) {
                    $self->errstr("couldn't get dates (line: $linenum)");
                    print STDERR "date: '$line->[$offsets->{'date'}]'\n";
                    return undef;
                }
                my $sale = RPS::Import::SaleRec->new();

                $sale->serviceID($serviceID);
                $sale->productType($type);
                $sale->mediaType($mediaType);
                $sale->formatType($format);
                $sale->dateBegin($dateBegin);
                $sale->dateEnd($dateEnd);
                $sale->serviceProductID($vendor_id);
                $sale->clientProductID($catno);
                $sale->upc($upc);
                $sale->isrc($isrc) if ( $type eq RPS::File::Sale::TYPE_TRACK );
                $sale->artistName($artist);
                $sale->albumName($album);
                $sale->labelName($label);
                $sale->trackName($track) if ( $type eq RPS::File::Sale::TYPE_TRACK );
                $sale->trackNum($track_num);
                $sale->units($units);
                $sale->price($price);
                $sale->lineNum($linenum);
                $sale->countryCode($countryCode);
                $sale->currencyCode($currencyCode) if ($currencyCode);

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

            #else { print STDERR "skip ($linenum) u: $units s: $serviceID t: $type ($track or $isrc) ($album or $upc)\n"; }

            $linenum++;
        }
        $sheet_count++;
    }
    return $linenum;
}

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