<?php

namespace App\Http\Controllers\Owner;

use App\Http\Controllers\Controller;

use Illuminate\Http\Request;

use App\Http\Helpers\ResponseBuilder;
use App\Http\Helpers\ParamsValidator;
use App\Http\History\HistoryData;
use App\Http\History\HistoryTables;
use App\Modules\BookingAdditional\Application\CreateFromBookingExtraPassenger\CreateFromBookingExtraPassengerBookingAdditionalQuery;
use App\Modules\Shared\Domain\Bus\Query\QueryBus;
use Illuminate\Support\Facades\DB;

class c_Booking_Extra extends Controller
{
    private $oDomain;
    /** @var HistoryData */
    private $history;
    /** @var HistoryData */
    private $historyPassengers;

    public function __construct(
        private QueryBus $queryBus
    ) {
        $this->oDomain = "Booking Extra";
        $this->history = new HistoryData(HistoryTables::booking_extra);
        $this->historyPassengers = new HistoryData(HistoryTables::BOOKING_EXTRA_PASSENGER);
    }

    public static function findBooking($Id_BookingExtra)
    {
        $found = DB::select('SELECT `fn_booking_tour_detail_find_booking`(?,?) as Id_Booking', [$Id_BookingExtra, 2]);
        return count($found) ? $found[0]->Id_Booking : null;
    }

    public function Insert(Request $Request)
    {
        $oSucces    = true;
        $oResponse  = array();
        $oValParams = array(
            'BookingExtra_Quantity'     => 'required|int',
            'BookingExtra_Feature'      => 'string',
            'Id_BookingTour'            => 'required|int',
            'Id_Provider'               => 'required|int',
            'Id_Extra'                  => 'required|int',
            'Passenger'                 => 'required|string'
        );


        // VALIDANDO DATOS
        $oResponse = ParamsValidator::Validate_Request($Request, $oValParams, $this->oDomain);

        //  INGRESANDO DATOS  
        if ($oResponse["Response_Code"] == 200) {
            $oParam = array(
                $Request->input("BookingExtra_Quantity"),
                $Request->input("BookingExtra_Feature"),
                1,
                $Request->input("Id_BookingTour"),
                $Request->input("Id_Provider"),
                $Request->input("Id_Extra"),
                1,
                1
            );
            $oData = DB::select('call sp_booking_extra_insert(?,?,?,?,?,?,?,?)', $oParam);

            //  RESPONSE
            if ($oData[0]->Response_Success == 1) {
                $Id_Booking = BookingTour::findBooking($Request->input('Id_BookingTour'));

                $this->history->insert(
                    [$Request->all()],
                    $Request,
                    $Id_Booking
                );

                $oPassenger = json_decode($Request->input("Passenger"));

                for ($k = 0; $k < count($oPassenger); $k++) {
                    $oParam = [
                        $oPassenger[$k]->BookingExtraPassenger_DateEntryStart,
                        $oPassenger[$k]->BookingExtraPassenger_DateEntryEnd,
                        $oData[0]->Response_Id,
                        $oPassenger[$k]->Id_BookingTourPassenger,
                        1
                    ];
                    $oDataPax = DB::select('call sp_booking_extra_passenger_insert_dates(?,?,?,?,?)', $oParam);

                    if ($oDataPax[0]->Response_Success == 0) {
                        $oSucces = false;
                        break;
                    }
                    $this->queryBus->ask(new CreateFromBookingExtraPassengerBookingAdditionalQuery($oDataPax[0]->Response_Id));

                    $this->historyPassengers->insert(
                        $this->historyPassengers->old($oDataPax[0]->Response_Id),
                        $Request,
                        $Id_Booking
                    );
                }

                if ($oSucces == true) {
                    $oData = array(
                        array(
                            "Response_Status"   => 200,
                            "Response_Code"     => 200,
                            "Response_Message"  => "Pasajeros guardados con éxito",
                            "Response_Reason"   => null
                        )
                    );

                    $oData = json_decode(json_encode($oData));
                }
            } else {
            }

            $oResponse["Response_Status"]           = $oData[0]->Response_Status;
            $oResponse["Response_Code"]             = $oData[0]->Response_Code;
            $oResponse["Response_Domain"]           = $this->oDomain;
            $oResponse["Response_Message"]          = $oData[0]->Response_Message;
            $oResponse["Response_Data"]             = null;
            $oResponse["Response_Error_Message"]    = $oData[0]->Response_Message;
            $oResponse["Response_Error_Reason"]     = $oData[0]->Response_Reason;
        }

        return ResponseBuilder::Response($oResponse);
    }
    public function Update(Request $Request)
    {
        $oResponse  = array();
        $oValParams = array(
            'Id_BookingExtra'       => 'required|int',
            'BookingExtra_Quantity' => 'required|int',
            'BookingExtra_Feature'  => 'string',
            'BookingExtra_Included' => 'required|int',
            'Id_Provider'           => 'required|int',
            'Id_BookingTour'        => 'required|int',
            'Id_Extra'              => 'required|int'
        );


        // VALIDANDO DATOS
        $oResponse = ParamsValidator::Validate_Request($Request, $oValParams, $this->oDomain);

        //  INGRESANDO DATOS
        if ($oResponse["Response_Code"] == 200) {
            $this->history->obtainOld($Request->input('Id_BookingExtra'));

            $oParam = array(
                $Request->input("Id_BookingExtra"),
                $Request->input("BookingExtra_Feature"),
                $Request->input("BookingExtra_Included"),
                $Request->input("Id_Provider"),
                $Request->input("Id_BookingTour"),
                $Request->input("Id_Extra"),
                1
            );
            $oData = DB::select('call sp_booking_extra_update(?,?,?,?,?,?,?)', $oParam);

            //  RESPONSE
            if ($oData[0]->Response_Success == 1) {
                $this->history->update(
                    $this->findBooking($Request->input('Id_BookingExtra')),
                    $this->history->oldValue,
                    [$Request->all()],
                    $Request
                );
            } else {
            }

            $oResponse["Response_Status"]           = $oData[0]->Response_Status;
            $oResponse["Response_Code"]             = $oData[0]->Response_Code;
            $oResponse["Response_Domain"]           = $this->oDomain;
            $oResponse["Response_Message"]          = $oData[0]->Response_Message;
            $oResponse["Response_Data"]             = null;
            $oResponse["Response_Error_Message"]    = $oData[0]->Response_Message;
            $oResponse["Response_Error_Reason"]     = $oData[0]->Response_Reason;
        }

        return ResponseBuilder::Response($oResponse);
    }
    public function Delete(Request $Request, $Id)
    {
        $oResponse  = array();

        // VALIDANDO DATOS
        $oResponse = ParamsValidator::Validate_Id($Id, $this->oDomain);

        //  INGRESANDO DATOS
        if ($oResponse["Response_Code"] == 200) {
            $this->history->obtainOld($Id);

            $oParam     = array($Id);
            $oData      = DB::select('call sp_booking_extra_delete(?)', $oParam);

            //  RESPONSE
            if ($oData[0]->Response_Success == 1) {
                $this->history->delete(
                    $this->findBooking($Id),
                    $this->history->oldValue,
                    $Request
                );
            } else {
            }

            $oResponse["Response_Status"]           = $oData[0]->Response_Status;
            $oResponse["Response_Code"]             = $oData[0]->Response_Code;
            $oResponse["Response_Domain"]           = $this->oDomain;
            $oResponse["Response_Message"]          = $oData[0]->Response_Message;
            $oResponse["Response_Data"]             = null;
            $oResponse["Response_Error_Message"]    = $oData[0]->Response_Message;
            $oResponse["Response_Error_Reason"]     = $oData[0]->Response_Reason;
        }

        return ResponseBuilder::Response($oResponse);
    }
    public function Index(Request $Request, $Id)
    {
        $oResponse  = array();

        // VALIDANDO DATOS
        $oResponse = ParamsValidator::Validate_Id($Id, $this->oDomain);

        //  INGRESANDO DATOS
        if ($oResponse["Response_Code"] == 200) {
            $oParam = array($Id);
            $oData  = DB::select('call sp_booking_extra_index(?)', $oParam);

            $oResponse["Response_Status"]           = 200;
            $oResponse["Response_Code"]             = 200;
            $oResponse["Response_Domain"]           = $this->oDomain;
            $oResponse["Response_Message"]          = $this->oDomain . " Index";
            $oResponse["Response_Data"]             = $oData;
            $oResponse["Response_Error_Message"]    = "";
            $oResponse["Response_Error_Reason"]     = "";
        }

        return ResponseBuilder::Response($oResponse);
    }
    public function List(Request $Request, $Id_BookingTour)
    {
        $oResponse  = array();

        $oResponse = ParamsValidator::Validate_Id($Id_BookingTour, $this->oDomain);

        if ($oResponse["Response_Code"] == 200) {
            $oParam = array($Id_BookingTour);
            $oData  = DB::select('call sp_booking_extra_list(?)', $oParam);

            $oResponse["Response_Status"]           = 200;
            $oResponse["Response_Code"]             = 200;
            $oResponse["Response_Domain"]           = $this->oDomain;
            $oResponse["Response_Message"]          = $this->oDomain . " list";
            $oResponse["Response_Data"]             = $oData;
            $oResponse["Response_Error_Message"]    = "";
            $oResponse["Response_Error_Reason"]     = "";
        }

        return ResponseBuilder::Response($oResponse);
    }
}
