<?php

namespace App\Classes\Modules\Bookings\ControllersLogic;


use App\Classes\Exceptions\MalformedRequestException;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Bookings\Services\CalculatesBookingOutstanding;
use App\Classes\Modules\Bookings\Services\FetchesBookingQuotation;
use App\Classes\Modules\Bookings\Services\GeneratesBookingQuotation;
use App\Classes\Modules\Companies\Services\FetchesCompanyPaymentAttemptLimit;
use App\Classes\Modules\Currencies\DataTransferObjects\CurrencyConversionObject;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Models\Booking;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class FetchBookingPaymentQuotationLogic extends AbstractControllerLogic
{

    /**
     * @return array
     */
    protected function notification():array {
        return [
            'title' => 'Fetch Currency Conversion',
            'message' => 'You have successfully retrieved a currency conversion'
        ];
    }

    /** @var FetchesBookingQuotation */
    private $fetchBookingQuotation;

    /** @var GeneratesBookingQuotation */
    private $generatesBookingQuotation;

    /** @var FetchesCompanyPaymentAttemptLimit */
    private $fetchesCompanyPaymentAttemptLimit;

    /** @var CalculatesBookingOutstanding */
    private $calculatesBookingOutstanding;

    /**
     * FetchBookingPaymentQuotationLogic constructor.
     * @param FetchesBookingQuotation $fetchBookingQuotation
     * @param GeneratesBookingQuotation $generatesBookingQuotation
     * @param FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit
     * @param CalculatesBookingOutstanding $calculatesBookingOutstanding
     */
    public function __construct(FetchesBookingQuotation $fetchBookingQuotation, GeneratesBookingQuotation $generatesBookingQuotation, FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit, CalculatesBookingOutstanding $calculatesBookingOutstanding)
    {
        $this->fetchBookingQuotation = $fetchBookingQuotation;
        $this->generatesBookingQuotation = $generatesBookingQuotation;
        $this->fetchesCompanyPaymentAttemptLimit = $fetchesCompanyPaymentAttemptLimit;
        $this->calculatesBookingOutstanding = $calculatesBookingOutstanding;
    }

    /**
     * @param Request $request
     * @return JsonResponse
     * @throws MalformedRequestException
     */
    public function logic(Request $request) : JsonResponse
    {
        $booking = Booking::find($request->route('id'));

        $conversionObject = new CurrencyConversionObject(floatval(str_replace(',', '', $request->input('amount'))), $booking->convertible_currency_id, $booking->service_id,  $booking->fix_currency_id === 1 ? 0:1, PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')]);

        $outstanding = $this->calculatesBookingOutstanding->execute($booking);
        if($conversionObject->getAmount() > round($outstanding, 2)) throw new MalformedRequestException('Your payment must not be greater than '.$booking->fixedCurrency->short_code.' '. number_format((float)$outstanding, 2, '.', ','));

        //Voucherify
        $voucherCode = $request->input('voucherCode');

        return $this->response(['data' => $this->generatesBookingQuotation->execute(
            $this->fetchBookingQuotation->execute($booking->company, $conversionObject, $voucherCode),
            $this->fetchesCompanyPaymentAttemptLimit->execute($booking->company),
            $conversionObject
        )]);

    }


}
