#---------------------------------------------------------------
# ____                   _ _         ____  _
#|  _ \ ___  _   _  __ _| | |_ _   _/ ___|| |__   __ _ _ __ ___
#| |_) / _ \| | | |/ _` | | __| | | \___ \| '_ \ / _` | '__/ _ \
#|  _ < (_) | |_| | (_| | | |_| |_| |___) | | | | (_| | | |  __/
#|_| \_\___/ \__, |\__,_|_|\__|\__, |____/|_| |_|\__,_|_|  \___|
#            |___/             |___/
#
# Copyright (C) 2012 RoyaltyShare, Inc.   All Rights Reserved
#---------------------------------------------------------------

package RPS::LabelRoyalty::Fast::Final::DB::LabelRoyaltyStatement;

use strict;
use Data::Dumper;
use File::Path;
use IO::File;

use lib '/app/tools/common/lib';
use lib '/app/tools/rps/lib';
use lib '/app/tools/raptor/lib';
use Common::RSApp;
use Common::RSMath;
use Common::Assert;
use Common::Log;

use DB_File;

use RPS::LabelRoyalty::Fast::Mapped::Data;
use RPS::LabelRoyalty::Fast::Static::LabelPayeeAccounts;

use base 'RPS::LabelRoyalty::Fast::Final::DB';

use constant kLabelRoyaltyStatementID => 0;
use constant kLabelRoyaltyRunID       => 1;
use constant kPayeeID                 => 2;
use constant kPreviousBalance         => 3;
use constant kBalance                 => 4;
use constant kMinPayment              => 5;
use constant kTransactionSubtotal     => 6;
use constant kTotal                   => 7;
use constant kAmountDue               => 8;
use constant kPayorID                 => 9;
use constant kOnHold                  => 10;
use constant kError                   => 11;

my @gFields = (
    'label_royalty_statement_id', 'label_royalty_run_id', 'payee_id', 'previous_balance', 'balance', 'min_payment', 'transaction_subtotal',
    'total', 'amount_due', 'payor_id', 'on_hold', 'error',
);
sub Fields { return \@gFields; }

sub FileName { 'label_royalty_statement' }

my $labelPayeeAccounts;

# We're going to use some globals to manage this class.
# This method initializes those.
#
# If this was intended to live in the web app, I'd probably store these inside the App singleton.
# But for now I will just put this in the package's global scope.
#

sub Init {
    my ( $class, $outputDirectory, $dataPath ) = @_;
    assert( $dataPath, "MISSING dataPath" );

    $labelPayeeAccounts = RPS::LabelRoyalty::Fast::Static::LabelPayeeAccounts->GetLabelPayeeAccounts($dataPath);

    # Call the inherited method first.
    #
    $class->SUPER::Init($outputDirectory);

    # !!! Leaving this stubbed out, because I am fairly sure I will need to initialize some stuff eventually...
}

sub new {
    my ( $class, $data, $runID, $payorID, $payeeToSalesMapCount ) = @_;

    # Basically, we'll bless the 'BlankItem' array reference into this class
    # Then we can invoke methods on it.
    #
    my $item = $class->BlankItem();
    $class->_IncrementID();

    $item->[kLabelRoyaltyStatementID] = $class->_CurrentID();
    $item->[kLabelRoyaltyRunID]       = $runID;
    $item->[kPayeeID]                 = $data->[RPS::LabelRoyalty::Fast::Mapped::Data::kPayeeID] =~ s/^\s+|\s+$//gr;
    $item->[kPayorID]                 = $payorID;
    $item->[kMinPayment]              = $data->[RPS::LabelRoyalty::Fast::Mapped::Data::kPayeeMinPayment];
    $item->[kPreviousBalance]         = $data->[RPS::LabelRoyalty::Fast::Mapped::Data::kPayeeBalance];
    $item->[kOnHold]                  = $data->[RPS::LabelRoyalty::Fast::Mapped::Data::kPayeeOnHold];

    # We need to determine if statement for this payee should be skipped.
    # So, we are checking total sales/transaction records associated with this payee
    # if at least 1 record exists we shouldn't skip the statement
    # Also, if balance is set for this payee - it shouldn't be skipped as well.
    my $sales_count = $payeeToSalesMapCount->{$item->[kPayeeID]};

    Common::Log::Debug("*** Skipping statement with no activity. Payee: $item->[kPayeeID] ***") if ($sales_count < 2 && !$item->[kPreviousBalance]);

    return bless $item, $class if ( $sales_count > 1 || $item->[kPreviousBalance]);

    return undef;
}

sub process {
    my ( $self, $data ) = @_;

    # Test whether we're still looking at data for 'this' object.
    #
    if ( $self->[kPayeeID] != $data->[RPS::LabelRoyalty::Fast::Mapped::Data::kPayeeID] ) {
        Log->info("RPS::LabelRoyalty::Fast::Final::DB::LabelRoyaltyStatement::process - returning UNDEF");
        return undef;
    }

    # !!! How am I going to address the transactions?
    # !!! I ought to follow the same model we used for ArtistRoyalties, which means putting that data
    # !!! into the Mapped::Data stream, using a distinct 'type' code that sorts _before_ the sales.
    # !!! Then handle the transactions here or in the Statement object.

    Log->info("RPS::LabelRoyalty::Fast::Final::DB::LabelRoyaltyStatement::process - returning 1");
    return 1;
}

sub _output {
    my ( $self, $fd ) = @_;

    # !!! For now, leave this blank.  I just want to get the ball rolling.

    # Calculate the final totals.
    # - previous_balance
    # - balance
    # - min_payment - May be set earlier, as an immutable property of the transactions?   Or from a cache of account data.
    # - transaction_subtotal
    # ... all the above come into play when transactions are added
    # - total
    # - amount_due

    # Round everything to 2 decimal places.
    #
    $self->[RPS::LabelRoyalty::Fast::Final::DB::LabelRoyaltyStatement::kTotal] =
      Common::RSMath::round( $self->[RPS::LabelRoyalty::Fast::Final::DB::LabelRoyaltyStatement::kTotal], 2 );

    $self->[RPS::LabelRoyalty::Fast::Final::DB::LabelRoyaltyStatement::kMinPayment] =
      Common::RSMath::round( $self->[RPS::LabelRoyalty::Fast::Final::DB::LabelRoyaltyStatement::kMinPayment], 2 );

    $self->[RPS::LabelRoyalty::Fast::Final::DB::LabelRoyaltyStatement::kPreviousBalance] =
      Common::RSMath::round( $self->[RPS::LabelRoyalty::Fast::Final::DB::LabelRoyaltyStatement::kPreviousBalance], 2 );

    $self->[RPS::LabelRoyalty::Fast::Final::DB::LabelRoyaltyStatement::kTransactionSubtotal] =
      Common::RSMath::round( $self->[RPS::LabelRoyalty::Fast::Final::DB::LabelRoyaltyStatement::kTransactionSubtotal], 2 );

    my $payeeBalance =
      $self->[RPS::LabelRoyalty::Fast::Final::DB::LabelRoyaltyStatement::kPreviousBalance] +
      $self->[RPS::LabelRoyalty::Fast::Final::DB::LabelRoyaltyStatement::kTotal] +
      $self->[RPS::LabelRoyalty::Fast::Final::DB::LabelRoyaltyStatement::kTransactionSubtotal];

    my $amountDue = 0;
    if ( $payeeBalance >= $self->[RPS::LabelRoyalty::Fast::Final::DB::LabelRoyaltyStatement::kMinPayment] ) {
        $amountDue = $payeeBalance;
    }

    my $onHold = 0;
    if ( $self->[RPS::LabelRoyalty::Fast::Final::DB::LabelRoyaltyStatement::kOnHold] ) {
        $onHold    = 1;
        $amountDue = 0;
    }

    $self->[RPS::LabelRoyalty::Fast::Final::DB::LabelRoyaltyStatement::kBalance]   = $payeeBalance;
    $self->[RPS::LabelRoyalty::Fast::Final::DB::LabelRoyaltyStatement::kAmountDue] = $amountDue;
    $self->[RPS::LabelRoyalty::Fast::Final::DB::LabelRoyaltyStatement::kOnHold]    = $onHold;

    $self->SUPER::_output($fd);
}

1;

