<?php

namespace App\Classes\Modules\Billplzs\Processors;

use Illuminate\Http\Request;
use App\Models\Wallet;
use App\Models\Group;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\Modules\Transactions\Processors\CreatePaymentTransactionProcessor;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\Modules\Wallets\Services\UpdatesWalletBalance;
use App\Classes\Modules\Orders\Processors\UpdateDoFromVTPortalProcessor;
use App\Classes\Modules\Orders\Processors\UpdateDoFromYDPortalProcessor;

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

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

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

    /** @var UpdatesWalletBalance */
    private $updatesWalletBalance;

    /** @var CreatePaymentTransactionProcessor */
    private $createPaymentTransactionProcessor;

    /**
     * CreateUserProcessor constructor.
     * @param UpdatesTransactionStatus $updatesTransactionStatus
     * @param UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor
     * @param UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor
     * @param UpdatesWalletBalance $updatesWalletBalance
     * @param CreatePaymentTransactionProcessor $createPaymentTransactionProcessor
     */
    public function __construct(UpdatesTransactionStatus $updatesTransactionStatus, UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor, UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor, UpdatesWalletBalance $updatesWalletBalance, CreatePaymentTransactionProcessor $createPaymentTransactionProcessor)
    {
        $this->updatesTransactionStatus = $updatesTransactionStatus;
        $this->updateDoFromVTPortalProcessor = $updateDoFromVTPortalProcessor;
        $this->updateDoFromYDPortalProcessor = $updateDoFromYDPortalProcessor;
        $this->updatesWalletBalance = $updatesWalletBalance;
        $this->createPaymentTransactionProcessor = $createPaymentTransactionProcessor;
    }


    /**
     * @param Request $request
     * @throws \App\Classes\Exceptions\MalformedRequestException
     */
    public function execute($transaction, $status)
    {
        $invoice = $transaction->owner;
        $packingList = $invoice->owner;

        $this->updatesTransactionStatus->execute($transaction, $status);

        // check if is wallet top up
        if ($transaction->owner instanceof Wallet && $status === ApprovalStatus::APPROVED) {

            $this->updatesWalletBalance->execute($transaction->owner, $transaction->amount);

            $group = Group::where('reference', $transaction->payment_reference)->first();
            
            // check if is group payment
            if ($group) {
                foreach ($group->groupTransactions as $groupTransaction) {
                    $invoice = $groupTransaction->transaction;
                    $this->createPaymentTransactionProcessor->execute($invoice, PaymentMethodType::WALLET, null);
                }
    
                $group->status = $status;
                $group->save();
            }
        }

        if (!$transaction->owner instanceof Wallet) {
            $totalPaidAmount = $invoice->transactions->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('amount');

            if (($invoice->amount - $totalPaidAmount) < 0.01) {
                $this->updatesTransactionStatus->execute($invoice, ApprovalStatus::COMPLETED);

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

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