#!/usr/bin/perl
use strict;


use Data::Dumper;
use Getopt::Std;
use POSIX qw(ceil);
use POSIX ":sys_wait_h";
use Sys::Hostname;
use Carp;


use lib '/app/tools/common/lib';
use Common::DB::Item;
use Common::Assert;
use Common::TextProgressBar;
use Common::Timer;
use Common::DB::Item::Service;

#use lib '/app/tools/data_classes/lib';
#use File::Sale;
use lib '/app/tools/raptor/lib';
#use Raptor::Sale::Sale;
use Raptor::DB::Item::Sale;
use Raptor::DB::Item::File;

use lib '/app/tools/rps/lib';
use RPS::DB::Item::ArtistRoyaltyAlbum;
use RPS::DB::Item::ArtistRoyaltyRun;
use RPS::DB::Item::ArtistRoyaltyStatement;
use RPS::DB::Item::FinanceAccount;
use RPS::DB::Item::FinanceTransaction;
use RPS::DB::Item::ArtistRoyaltyAlbumBalanceAccount;
use RPS::RoyaltyRun::Status;

my $gVerbosityLevel = 1;



# Parse the command-line options.
#
my %options;
_parseCommandLine(\%options);


# Instantiate the application singleton object.
#
my $appSingleton = Common::RSApp->new(clientID => $options{clientID});


my $runs = RPS::DB::Item::ArtistRoyaltyRun->GetAll();
while (my $run = $runs->next())
{
    next unless (RPS::RoyaltyRun::Status::kCommitted == $run->status);

    _fixRun($run);
}


sub _fixRun
{
    my ($run) = @_;

    _report("\n---- Converting run " . $run->artist_royalty_run_id);

    my $statements = RPS::DB::Item::ArtistRoyaltyStatement::GetByArtistRoyaltyRunID($run->artist_royalty_run_id);
    while (my $statement = $statements->next())
    {
        _fixStatement($statement);
    }
}


sub _fixStatement
{
    my ($statement) = @_;
    _report("  statement: " . $statement->artist_royalty_statement_id);

    # We don't need to adjust the uncross albums - just the crossed ones.
    # And, really, we just need to make sure positive balances were carried forward
    # when necessary.
    #
    my @crossed;
    my @uncrossed;

    my $artistPayeeID = $statement->payee_id;

    my $balanceForwardFlag = ($statement->cross_collateralized_subtotal < 0);

    my $albums = RPS::DB::Item::ArtistRoyaltyAlbum->GetByArtistRoyaltyStatementID($statement->artist_royalty_statement_id);
    while (my $album = $albums->next())
    {
        my $albumID = $album->album_id;
        if ($album->is_cross_collateralized() && $balanceForwardFlag)
        {
            # Presumably negative balances were already created?
            #
            if ($album->total > 0)
            {
                _report("   adjusting album_item: " . $album->artist_royalty_album_id . " amount to carry forward: " . $album->total);


                my $accountID;
                my $accountMap = RPS::DB::Item::ArtistRoyaltyAlbumBalanceAccount->Lookup
                (
                    album_id => $albumID,
                    artist_payee_id => $artistPayeeID,
                );

                if ($accountMap)
                {
                    $accountID = $accountMap->account_id;
                }
                else
                {
                    my $account = RPS::DB::Item::FinanceAccount->Create
                    (
                        description => "holdover account for album $albumID artist payee $artistPayeeID",
                        type_code => RPS::DB::Item::FinanceAccount::kAccountTypeHoldover,
                    );
                    $account->save();
                    $accountID = $account->finance_account_id;
                    _report("      created new holdover account, id $accountID");

                    $accountMap = RPS::DB::Item::ArtistRoyaltyAlbumBalanceAccount->Create
                    (
                        album_id => $albumID,
                        artist_payee_id => $artistPayeeID,
                        account_id => $accountID,
                    );
                    $accountMap->save();
                }

                my $statementID = $statement->artist_royalty_statement_id;
                my $transaction = RPS::DB::Item::FinanceTransaction->Create
                (
                    finance_account_id => $accountID,
                    amount => $album->total,
                    type_code => RPS::DB::Item::FinanceTransaction::kTypeTransaction,
                    memo => "artist statement $statementID",
                );
                $transaction->save();
            }
        }
    }


    # Adjust
}


sub _usage
{
    print "\nusage: $0 -c client_id [-V]\n";
    print "\n";
    print "Arguments:\n";
    print "\t-c <client_id>\t\tThe client_id of the client to process\n";
    print "\t-V <N>\t\t\tVerbosity level - 0 means no output\n";
}


sub _report
{
    my ($string, $verbosity) = @_;
    $verbosity = 1 unless defined $verbosity;

    if ($gVerbosityLevel >= $verbosity)
    {
        print $string . "\n";
    }
}


# Pass dates in 'yyyy-mm-dd' format.
#
sub _parseCommandLine
{
    my ($settings) = @_;

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

    if (! $opt{c})
    {
        _usage();
        exit(1);
    }
    $settings->{clientID} = $opt{c};

    if (defined $opt{V})
    {
        $gVerbosityLevel = $opt{V};
    }
}
