<?php


namespace App\Classes\Modules\Banks\Processors;

use App\Classes\Modules\Transactions\Services\FetchesTransaction;
use App\Classes\Modules\Banks\Services\UpdatesBank;
use App\Classes\Modules\Banks\Services\CreatesOrUpdateBank;
use App\Classes\Modules\Banks\DataTransferObjects\BankObject;
use App\Classes\Modules\KeyValuePairs\DataTransferObjects\KeyValuePairObject;
use App\Classes\Modules\KeyValuePairs\Services\CreatesKeyValuePair;
use Illuminate\Database\Eloquent\Model;
use App\Models\Bank;


class UpdateBankProcessor
{
    /** @var UpdatesBank */
    private $updatesBank;

    /** @var CreatesOrUpdateBank */
    private $createsOrUpdateBank;

    /** @var CreatesKeyValuePair */
    private $createsKeyValuePair;

    /** @var FetchesTransaction */
    private $fetchesTransaction;

    /**
     * UpdateBankProcessor constructor.
     * @param UpdatesBank $updatesBank
     * @param CreatesOrUpdateBank $createsOrUpdateBank
     * @param CreatesKeyValuePair $createsKeyValuePair
     * @param FetchesTransaction $fetchesTransaction
     */
    public function __construct(
        UpdatesBank $updatesBank,
        CreatesOrUpdateBank $createsOrUpdateBank,
        CreatesKeyValuePair $createsKeyValuePair,
        FetchesTransaction $fetchesTransaction
    )
    {
        $this->updatesBank = $updatesBank;
        $this->createsOrUpdateBank = $createsOrUpdateBank;
        $this->createsKeyValuePair = $createsKeyValuePair;
        $this->fetchesTransaction = $fetchesTransaction;
    }

    /**
     * @param BankObject $bankObject
     * @param Bank $bank
     * @param string $billNo
     * @param int $transactionId
     * @return Model
     * @throws \App\Classes\Exceptions\MalformedRequestException
     * @throws \App\Classes\Exceptions\JobResourceNotFoundException
     */
    public function execute(BankObject $bankObject, Bank $bank, string $billNo, int $transactionId) {
        $result = null;
        if($billNo && $transactionId){
            $transaction = $this->fetchesTransaction->execute(['id' => $transactionId]);
            //If payment transaction do not have a bank yet, create one
            if(!$transaction->bank){
                $result = $this->createsOrUpdateBank->execute($bankObject);

                // if ($result->wasRecentlyCreated) {
                    //Key #1 for Bank
                    $kvp = $bank->attributesKVP()->where('key', 'App\Models\Bank')->where('value', $result->id)->latest()->first();
                    if(!$kvp){
                        $keyValuePairObject = new KeyValuePairObject(
                            "App\Models\Bank",
                            $result->id
                        );
                        $this->createsKeyValuePair->execute($bank, $keyValuePairObject);
                    }

                    //Key #2 for Payment Transaction (owner type: booking)
                    $keyValuePairObject = new KeyValuePairObject(
                        "App\Models\Bank",
                        $result->id
                    );
                    $this->createsKeyValuePair->execute($transaction, $keyValuePairObject);
                // }

            }
            else{
                $result = $this->updatesBank->execute($transaction->bank, $bankObject);
            }
        }
        else{
            $result = $this->updatesBank->execute($bank, $bankObject);
        }

        return $result;
    }
}
