package RPS::Mechanical::US::DistributeStatementsForm;

use strict;
use warnings;

use Data::Dumper;

use lib '/app/tools/common/lib';
use Common::FormObject;
use Common::DB::Item::PayeeType;

use lib '/app/tools/rps/lib';
use RPS::Payor::Payor;
use RPS::RoyaltyRun::Status;

use RPS::Mechanical::US::MechanicalRun;
use RPS::DB::Item::MechanicalStatement;
use RPS::Statement::Mechanical::US::StatementListWithPayments;

use RPS::Portal::Job::SendNotification;
use RPS::DB::Item::PortalEmailCustomText;

use base 'Common::FormObject';

sub _init {
    my ( $self, %args ) = @_;

    $self->SUPER::_init(%args);

    $self->{_sendAll}  = $args{sendAll};
    $self->{_runID}    = $args{runID};
    $self->{_payorID}  = $args{payorID};
    $self->{_filterBy} = $args{filterBy};

    $self->{MechanicalStatementList} = RPS::Statement::Mechanical::US::StatementListWithPayments->new(
        mechanicalRunID => $args{runID},
        payorID         => $args{payorID},
        filterBy        => $args{filterBy},
        pageSize        => $args{pageSize},
        page            => $args{page}
    );

    $self->{Payor} = RPS::Payor::Payor->new( payorID => $args{payorID} );

    $self->{MechanicalRun} = RPS::Mechanical::US::MechanicalRun->new(
        mechanicalRunID => $args{runID},
        loadSubs        => 0,
    );

    $self->{DistributedCount} = RPS::DB::Item::MechanicalStatement->GetDistributedCount(
        runID    => $args{runID},
        payorID  => $args{payorID},
        filterBy => $args{filterBy}
    );

    $self->{EligibleCount} = RPS::DB::Item::MechanicalStatement->GetEligibleCount(
        runID    => $args{runID},
        payorID  => $args{payorID},
        filterBy => $args{filterBy}
    );

    $self->{RoyaltyRunStatus} = new RPS::RoyaltyRun::RoyaltyRunStatusList( usMechanical => 1, payorID => $args{payorID} );

    $self->{EmailCustomNotificationText} = RPS::DB::Item::PortalEmailCustomText->GetCustomNotificationText() ? 1 : 0;

    die "ERROR - cannot distribute statements for runs in this state"
      unless ( RPS::RoyaltyRun::Status::kCommitted == $self->{MechanicalRun}->Status()
        || RPS::RoyaltyRun::Status::kClosed == $self->{MechanicalRun}->Status() );

    return $self;
}

sub save {
    my ( $self, $args ) = @_;

    my $clientID = Common::RSApp::GetClientID();
    my $runID    = $self->{_runID};
    my $payorID  = $self->{_payorID};
    my $filterBy = $self->{_filterBy};
    my @publisherIDs;

    my $statementIDParam = $args->{statementID};
    my @statementIDs;

    # Grab all the statement IDs that were select on the current page.
    if ($statementIDParam) {
        @statementIDs = ref $statementIDParam eq 'ARRAY' ? @$statementIDParam : ($statementIDParam);
    }

    # See if we need to send invites for the rest of the pages.
    if ( $self->{_sendAll} ) {

        # We already have the statement IDs we need from the current page, so
        # we need to exclude everything on the current page from the bulk update.
        my $currentPage = $self->{MechanicalStatementList};

        my %currentStatementIDs;
        foreach my $statement ( @{ $currentPage->{MechanicalStatement} } ) {
            $currentStatementIDs{ $statement->MechanicalStatementID() } = 1;
        }

        # Now we grab all of the statements.
        my $allPages = RPS::Statement::Mechanical::US::StatementListWithPayments->new(
            mechanicalRunID => $runID,
            payorID         => $payorID,
            filterBy        => $filterBy,
        );

        # And now we filter out the ones from the front page.
        foreach my $statement ( @{ $allPages->{MechanicalStatement} } ) {
            if ( !$currentStatementIDs{ $statement->MechanicalStatementID() } ) {

                # We also need to make sure distribution is set to Online
                # _and_ the statement has not been sent already.
                if ( ( $statement->Publisher->Distribution() == 1 ) && !$statement->DateSent() ) {
                    push( @statementIDs, $statement->MechanicalStatementID() );
                }
            }
        }
    }

    foreach my $statementID (@statementIDs) {
        my $statement = RPS::DB::Item::MechanicalStatement->Lookup( mechanical_statement_id => $statementID );
        $statement->date_sent(Common::DB::Item::kDateTimeNow);
        $statement->save();
        push( @publisherIDs, $statement->publisher_id );
    }

    my $publisherList = join( ",", @publisherIDs );

    # Queue a job to send a notification for each statement that was just "distributed" to the portal
    my $jobArgs = RPS::Portal::Job::SendNotification->new(
        payeeType => Common::DB::Item::PayeeType::kPayeeTypePublisherUS,
        payeeList => $publisherList,
        runID     => $runID,
        clientID  => $clientID,
    );
    my $job = $jobArgs->enqueue();

    # Need to return the final count for the success message.
    my $distributedCount = scalar @statementIDs;

    return $distributedCount;
}


1;
