<?php

namespace App\Classes\Modules\Transactions\Processors;

use App\Classes\Exceptions\MalformedRequestException;
use App\Classes\Modules\Transactions\Services\CreatesTransaction;
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
use App\Classes\Modules\Bookings\Services\CalculatesBookingCurrencyAverageRate;
use App\Classes\Modules\Companies\Services\FetchesCompany;
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Models\Booking;
use App\Models\Transaction;
use Illuminate\Support\Facades\Log;

class CreateReceiptVoucherTransactionProcessor
{

    /** @var CreatesTransaction */
    private $createsTransaction;

    /** @var GeneratesTransactionBillNumber */
    private $generatesTransactionBillNumber;

    /** @var CalculatesBookingCurrencyAverageRate */
    private $calculatesBookingCurrencyAverageRate;

    /** @var FetchesCompany */
    private $fetchesCompany;

    /** @var CreateInvoiceDocumentProcessor */
    private $invoiceDocumentProcessor;


    /**
     * CreateReceiptVoucherTransactionProcessor constructor.
     * @param CreatesTransaction $createsTransaction
     * @param GeneratesTransactionBillNumber $generatesTransactionBillNumber
     * @param CalculatesBookingCurrencyAverageRate $calculatesBookingCurrencyAverageRate
     * @param FetchesCompany $fetchesCompany
     * @param CreateInvoiceDocumentProcessor $invoiceDocumentProcessor
     */
    public function __construct(CreatesTransaction $createsTransaction, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CalculatesBookingCurrencyAverageRate $calculatesBookingCurrencyAverageRate, FetchesCompany $fetchesCompany, CreateInvoiceDocumentProcessor $invoiceDocumentProcessor)
    {
        $this->createsTransaction = $createsTransaction;
        $this->generatesTransactionBillNumber = $generatesTransactionBillNumber;
        $this->calculatesBookingCurrencyAverageRate = $calculatesBookingCurrencyAverageRate;
        $this->fetchesCompany = $fetchesCompany;
        $this->invoiceDocumentProcessor = $invoiceDocumentProcessor;
    }

    /**
     * @param Booking $booking
     * @param Transaction $transaction
     * @param bool $isRegenerate
     * @return void
     * @throws MalformedRequestException
     */
    public function execute(Booking $booking, Transaction $transaction, bool $isRegenerate = false)
    {
        $purchaseOrder = $booking->transactions()
            ->where('type', TransactionType::PURCHASE_ORDER)
            // ->complete()
            ->first();

        if(!$transaction->type === TransactionType::PAYMENT){
            return;
        }

        if(!($transaction->status === ApprovalStatus::APPROVED || $transaction->status === ApprovalStatus::COMPLETED)){
            return;
        }
        Log::info('CreateReceiptVoucherTransactionProcessor booking id: '. $booking->id);
        Log::info('CreateReceiptVoucherTransactionProcessor transaction: '. json_encode($transaction));

        //If payment receipt voucher already exists, return (unless you want to regenerate)
        if($transaction->transactions()->where('type', TransactionType::RECEIPT_VOUCHER)->exists() && !$isRegenerate){
            return;
        }

        $billNumber = $this->generatesTransactionBillNumber->execute('RV-');

        $booking_currency_average_rate = $this->calculatesBookingCurrencyAverageRate->execute($booking, TransactionType::PAYMENT);

        $transaction_object = new TransactionObject(
            $billNumber,
            TransactionType::RECEIPT_VOUCHER,
            $transaction->issuer,
            $transaction->receiver,
            $transaction->recipient_bank_account_id,
            $transaction->payment_method,
            $transaction->amount,
            $transaction->original_amount,
            $transaction->currency_id,
            $transaction->original_currency_id,
            $booking_currency_average_rate,
            0,
            0,
            null,
            ApprovalStatus::APPROVED
        );
        $invoice_transaction = $this->createsTransaction->execute($transaction, $transaction_object);

        $voucherRedemption = $transaction->voucherRedemption;

        $supplier = $this->fetchesCompany->execute(['id' => $transaction->receiver]);

        // receipt voucher - Receipt is mandatory for customer who wants e-invoice and those who does not
        $this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::RECEIPT_VOUCHER, $voucherRedemption);
    }
}
