#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;
use Getopt::Std;

use lib '/app/tools/common/lib';
use Common::Amazon::Mail;
use Common::Client;
use Common::DB::Item::Client;
use Common::Log;
use Common::RSApp;
use Common::RSDB;

use lib '/app/tools/raptor/lib';
use Raptor::DB::Item::Period;
use Raptor::DB::Item::Sale;

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

use constant REPORT_BASE_DIR => '/app/shared/sale_report';

my %opt;
getopts( 'c:p:', \%opt );

my $clientID     = $opt{c};
my $periodID     = $opt{p};

unless ( $clientID && $periodID ) {
    die "clientID '-c' and periodID '-p' required";
}

unless ( $clientID =~ /^\d+$/ && $clientID > 0 ) {
    die "clientID '$clientID' must be a number greater than zero";
}

unless ( $periodID =~ /^\d+$/ && $periodID > 0 ) {
    die "periodID '$periodID' must be a number greater than zero";
}

my $app = Common::RSApp->new(clientID => $clientID);

my $report = genReport( $clientID, $periodID );

Common::Log::Print("Report created: $report");

if ($report && Common::RSApp::IsProductionServer) {
    emailReport( $clientID, $periodID, $report );
} elsif ($report && !Common::RSApp::IsProductionServer) {
    Common::Log::Print("Report generated but not emailed.");
} else {
    die "Report not generated";
}

sub genReport {
    my $clientID = shift;
    my $periodID = shift;

    my $client = Common::DB::Item::Client->Lookup(client_id => $clientID);
    my $clientNameClean = $client->client_name_clean;

    my $directory = REPORT_BASE_DIR . "/" . $clientNameClean;
    if ( !-d $directory && !mkdir($directory) ) {
        Common::Log::Print("can't create dir: $directory\n");
        return undef;
    }

    my $reportName = $clientNameClean . "_period_" . $periodID . "_billable_revenue.csv";
    my $filePath = $directory . "/" . $reportName;

    unless ( open FILE, ">$filePath" ) {
        Common::Log::Print("can't create file $filePath\n");
        return undef;
    }

    my @headers = ('Service', 'File ID', 'File Name', 'Type', 'Digital Revenue', 'Physical Revenue', 'Total Revenue');
    print FILE join(",", @headers), "\n";

    our %CLIENT_DB = Common::RSDB::StaticList::clientDB;

    my $dbName = $CLIENT_DB{$clientID}{db_name};
    my $server = $CLIENT_DB{$clientID}{server};
    my $userName = $CLIENT_DB{$clientID}{username};
    my $password = $CLIENT_DB{$clientID}{password};

    my $currencySymbol = Common::Client::Current()->Locale()->currencyFormat()->symbol();

    my $services = Client::Service::GetAllServiceNames( client_id => $clientID );
    my $files = Raptor::DB::Item::File->GetByPeriodID($periodID);

    my $digitalTotal;
    my $physicalTotal;
    my $totalTotal;

    while ( my $file = $files->next() ) {
        my $serviceID   = $file->service_id;
        my $serviceName = $services->{$serviceID};
        my $fileID      = $file->file_id;
        my $fileObj     = RPS::File::File->new( file_id => $fileID );
        my $fileName    = $file->orig_file_name;

        my $digitalRevenue = 0;
        my $physicalRevenue = 0;
        my $totalRevenue = 0;
        my $fileType;

        if ( $file->input_conversion_rate ) {
            $totalRevenue = $fileObj->AdjustedRevenue;
        } else {
            $totalRevenue = $file->revenue;
        }

        if ( $file->type_id eq File::File::FILETYPE_LICENSE_INCOME ) {

            # Treat license income as physical revenue
            $physicalRevenue = $totalRevenue;
            $fileType = "Physical";
            $serviceName = "License Income";
        } elsif ( $file->physical == 1 ) {

            # physical sales
            $physicalRevenue = $totalRevenue;
            $fileType = "Physical";
        } elsif ( $file->physical == 2 ) {

            # digital and/or physical
            my $sales = Raptor::DB::Item::Sale->GetByFileID( $file->file_id );
            while ( my $sale = $sales->next() ) {
                my $distFee = $fileObj->GetDistFeePct( $sale->format_type );

                if ($distFee) {
                    $distFee = ( 100 - $distFee ) * .01;
                } else {
                    $distFee = 1;
                }

                if (   $sale->product_type eq RPS::File::Sale::TYPE_TRACK
                    || $sale->product_type eq RPS::File::Sale::TYPE_ALBUM ) {
                    # digital sales
                    $digitalRevenue += ( $sale->price * $sale->units * $sale->conversion_rate * $distFee );
                } else {
                    # physical sales
                    $physicalRevenue += ( $sale->total_revenue * $sale->conversion_rate * $distFee );
                }
            }
            $fileType = "Mixed";
        } else {

            # digital sales
            $digitalRevenue = $totalRevenue;
            $fileType = "Digital";
        }

        # round the revenue totals
        $digitalRevenue  = sprintf( "%.2f", $digitalRevenue );
        $physicalRevenue = sprintf( "%.2f", $physicalRevenue );
        $totalRevenue    = sprintf( "%.2f", $totalRevenue );

        # add them to the grand totals
        $digitalTotal += $digitalRevenue;
        $physicalTotal += $physicalRevenue;
        $totalTotal += $totalRevenue;

        my @fileData = (
            $serviceName,
            $fileID,
            $fileName,
            $fileType,
            $currencySymbol . $digitalRevenue,
            $currencySymbol . $physicalRevenue,
            $currencySymbol . $totalRevenue
        );

        print FILE join(",", @fileData), "\n";
    }

    # now add a line with the revenue totals
    print FILE "\n";
    my @totals = (
        '',
        '',
        '',
        'Total:',
        $currencySymbol . $digitalTotal,
        $currencySymbol . $physicalTotal,
        $currencySymbol . $totalTotal
    );
    print FILE join(",", @totals), "\n";

    close FILE;

    return $filePath;
}

sub emailReport {
    my $clientID = shift;
    my $periodID = shift;
    my $report   = shift;

    my $client = Common::DB::Item::Client->Lookup(client_id => $clientID);
    my $clientName = $client->client_name;
    my $clientDomain = $client->web_alias ? $client->web_alias : $client->client_name_clean;

    my $emailTo   = 'RoyaltyshareInvoices@theorchard.com';
    my $cc        = 'cbreindel@theorchard.com, oscar@royaltyshare.com, billy@royaltyshare.com';

    my $period = Raptor::DB::Item::Period->Lookup(period_id => $periodID);
    my $periodName = $period->name;

    if (!$periodName) {
        my ( $s_year, $s_month, $s_day ) = split( '-', $period->start_date );
        $s_month = substr( Date::Calc::Month_to_Text($s_month), 0, 3 );
        my $startDate = $s_month . " " . $s_day . ", " . $s_year;

        my ( $e_year, $e_month, $e_day ) = split( '-', $period->end_date );
        $e_month = substr( Date::Calc::Month_to_Text($e_month), 0, 3 );
        my $endDate = $e_month . " " . $e_day . ", " . $e_year;

        $periodName = $startDate . " - " . $endDate;
    }

    my $subject = "Closed Period Revenue Report $periodName - $clientName";
    my $body    = "Attached is the closed period revenue report for $periodName (Period ID = $periodID) for $clientName:\n\n"
      . "https://$clientDomain.royaltyshare.com/app/tracker?period=$periodID\n\n"
      . "Enjoy!\n\nCheryl\n\n";

    my $mail = Common::Amazon::Mail->new;
    $mail->to( $emailTo );
    $mail->cc( $cc );
    $mail->subject($subject);
    $mail->body($body);
    $mail->sendit( [$report] );

    Common::Log::Print("Report emailed to $emailTo, $cc");
}
