<?php

namespace App\Classes\Modules\Transactions\Processors;

use Illuminate\Http\Request;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\Modules\Transactions\Processors\CreateStorageInvoiceDocTransactionProcessor;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\Modules\Orders\Processors\UpdateDoFromVTPortalProcessor;
use App\Classes\Modules\Orders\Processors\UpdateDoFromYDPortalProcessor;
use Illuminate\Support\Facades\Log;

class ReleaseGoodsToCustomerProcessor
{
    /** @var UpdatesTransactionStatus */
    private $updatesTransactionStatus;

    /** @var UpdateDoFromVTPortalProcessor */
    private $updateDoFromVTPortalProcessor;

    /** @var UpdateDoFromYDPortalProcessor */
    private $updateDoFromYDPortalProcessor;

    /** @var CreateStorageInvoiceDocTransactionProcessor */
    private $createStorageInvoiceDocTransactionProcessor;

    /**
     * ReleaseGoodsToCustomerProcessor constructor.
     * @param UpdatesTransactionStatus $updatesTransactionStatus
     * @param UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor
     * @param UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor
     * @param CreateStorageInvoiceDocTransactionProcessor $createStorageInvoiceDocTransactionProcessor
     */
    public function __construct(UpdatesTransactionStatus $updatesTransactionStatus, UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor, UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor, CreateStorageInvoiceDocTransactionProcessor $createStorageInvoiceDocTransactionProcessor)
    {
        $this->updatesTransactionStatus = $updatesTransactionStatus;
        $this->updateDoFromVTPortalProcessor = $updateDoFromVTPortalProcessor;
        $this->updateDoFromYDPortalProcessor = $updateDoFromYDPortalProcessor;
        $this->createStorageInvoiceDocTransactionProcessor = $createStorageInvoiceDocTransactionProcessor;
    }


    /**
     * @param $packingList
     * @param $invoice
     * @throws \App\Classes\Exceptions\MalformedRequestException
     */
    public function execute($packingList, $invoice = null)
    {
        $result = false;
        $totalInvoicesAmountPaid = 0.00;
        $totalInvoicesAmount = 0.00;
        $invoiceTransactions = $packingList->transactions()->where('status', [ApprovalStatus::APPROVED])->whereIn('type', [TransactionType::SHIPPING_INVOICE, TransactionType::STORAGE_INVOICE])->get();

        //Part 1: Process each single invoice type and get the total of all invoices
        foreach($invoiceTransactions as $invoiceTransaction){

            $totalInvoiceAmountPaid = $invoiceTransaction->transactions->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('amount');
            if ($invoice && $invoice->type == $invoiceTransaction->type) {
                if(($invoice->amount - $totalInvoiceAmountPaid) < 0.01){
                    $this->updatesTransactionStatus->execute($invoice, ApprovalStatus::COMPLETED);

                    if($invoice->type == TransactionType::STORAGE_INVOICE){
                        $this->createStorageInvoiceDocTransactionProcessor->execute($packingList);
                    }
                }
            }

            $totalInvoicesAmount = $totalInvoicesAmount + $invoiceTransaction->amount;
            $totalInvoicesAmountPaid = $totalInvoicesAmountPaid + $totalInvoiceAmountPaid;
        }

        Log::channel('storage_invoices')->info('Total invoice amount paid 1: '.$totalInvoicesAmount); //cief todo: to be removed
        Log::channel('storage_invoices')->info('Total invoice amount paid 2: '.$totalInvoicesAmountPaid); //cief todo: to be removed

        //Part 2: Based on the collected info for all the total of all invoices
        if (($totalInvoicesAmount - $totalInvoicesAmountPaid) < 0.01 && $totalInvoicesAmountPaid > 0.01) {
            Log::channel('storage_invoices')->info('Total invoice amount paid 3: '.$totalInvoicesAmountPaid); //cief todo: to be removed

            $packingList->status = ApprovalStatus::APPROVED;
            $packingList->save();

            if (app()->environment('production')) {
                $this->updateDoFromVTPortalProcessor->execute($packingList);
                $this->updateDoFromYDPortalProcessor->execute($packingList);
            }

            $result = true;
        }

        return $result;
    }
}
