<?php

namespace App\Http\Controllers\Owner\Booking;

use App\Http\Controllers\Controller;
use App\Http\Controllers\Owner\Booking\Dto\BookingUpdateLocationDTO;
use App\Http\Controllers\Owner\c_Admin_Session;
use Illuminate\Http\Request;
use App\Http\Helpers\ResponseBuilder;
use App\Http\History\HistoryTables;
use App\Modules\Booking\Application\Index\IndexBookingQuery;
use App\Modules\Booking\Application\Update\UpdateBookingQuery;
use App\Modules\Booking\Infraestructure\BookingHistory;
use App\Modules\BookingTour\Application\BookingTourResponse;
use App\Modules\BookingTour\Application\Index\IndexBookingTourQuery;
use App\Modules\BookingTour\Application\Update\UpdateBookingTourQuery;
use App\Modules\BookingTourPassenger\Application\Update\UpdateBookingTourPassengerQuery;
use App\Modules\History\Application\Insert\InsertHistoryQuery;
use App\Modules\History\Domain\HistoryOperation;
use App\Modules\LodgingPlace\Application\Insert\InsertLodgingPlaceQuery;
use App\Modules\LodgingPlace\Application\Insert\InsertLodgingPlaceResponse;
use App\Modules\LodgingPlace\Domain\LodgingPlaceStatus;
use App\Modules\Shared\Domain\Bus\Query\QueryBus;
use App\Modules\Shared\Validator\Infraestructure\LaravelDTOGenerator;
use Illuminate\Support\Facades\DB;

class BookingUpdateLocationController extends Controller
{
    private $domain;

    public function __construct(
        private QueryBus $queryBus,
        private LaravelDTOGenerator $dtoGenerator,
    ) {
        $this->domain = "Booking";
    }
    public function findBooking($Id)
    {
        $found = DB::select(
            'Call sp_booking_index(?)',
            [$Id]
        );
        return count($found) ? $found[0]->Id_Booking : null;
    }

    public function __invoke(Request $request)
    {

        /** @var BookingUpdateLocationDTO $dto */
        $dto = $this->dtoGenerator->generate($request->all(), $this->domain, BookingUpdateLocationDTO::class);
        $adminSession = c_Admin_Session::check($request);
        // --------------------------------------------------------------------------------------------------------------

        if (!is_null($dto->LodgingPlace_PickUp)) {
            $PickUp = json_decode($dto->LodgingPlace_PickUp);
            // dd($PickUp);
            /** @var InsertLodgingPlaceResponse $responsePickUp */
            $responsePickUp = $this->queryBus->ask(new InsertLodgingPlaceQuery(
                $PickUp->LodgingPlace_Name,
                $PickUp->LodgingPlace_Direction,
                $PickUp->LodgingPlace_Longitude ?? '',
                $PickUp->LodgingPlace_Latitude ?? '',
                LodgingPlaceStatus::ACTIVE,
                $PickUp->LodgingPlace_Icon ?? '',
                $PickUp->LodgingPlace_Place,
                $PickUp->Id_Booking,
                $adminSession['Id_Admin']
            ));
            // dd($responsePickUp->id());
            $dto->Id_LodgingPlace_PickUp = $responsePickUp->id();
        }
        if (!is_null($dto->LodgingPlace_DropOff)) {
            $DropOff = json_decode($dto->LodgingPlace_DropOff);
            /** @var InsertLodgingPlaceResponse $responseDropOff */
            $responseDropOff = $this->queryBus->ask(new InsertLodgingPlaceQuery(
                $DropOff->LodgingPlace_Name,
                $DropOff->LodgingPlace_Direction,
                $DropOff->LodgingPlace_Longitude ?? '',
                $DropOff->LodgingPlace_Latitude ?? '',
                LodgingPlaceStatus::ACTIVE,
                $DropOff->LodgingPlace_Icon ?? '',
                $DropOff->LodgingPlace_Place,
                $DropOff->Id_Booking,
                $adminSession['Id_Admin']
            ));
            // dd($responsePickUp->id());
            $dto->Id_LodgingPlace_DropOff = $responseDropOff->id();
        }
        // --------------------------------------------------------------------------------------------------------------
        // $adminSession = c_Admin_Session::check($request);

        $lastResponse = BookingHistory::getBookingIndexHistory($dto->Id_Booking);

        /** @var UpdateBookingQueryResponse $response */
        $this->queryBus->ask(new UpdateBookingQuery(
            $dto->Id_Booking,
            $dto->Id_LodgingPlace_PickUp,
            $dto->Id_LodgingPlace_DropOff,
            $adminSession['Id_Admin'],
        ));
        $firstResponse = BookingHistory::getBookingIndexHistory($dto->Id_Booking);

        $this->queryBus->ask(new InsertHistoryQuery(
            json_encode($firstResponse),
            json_encode($lastResponse),
            HistoryOperation::UPDATE,
            $dto->Id_Booking,
            $dto->Id_Booking,
            HistoryTables::BOOKING,
            $adminSession['Id_Admin'],
        ));

        // ------------------------------Modificar el pickup y dropoff de todos los pasajeros de booking_tour---------------------------------- 
        $bParam = DB::select('call sp_booking_tour_list(?)', [$dto->Id_Booking]);
        foreach ($bParam as $element) {

            //update bookingtour
            /** @var UpdateBookingTourQueryResponse $response */
            $this->queryBus->ask(new UpdateBookingTourQuery(
                $element->Id_BookingTour,
                $dto->Id_LodgingPlace_PickUp,
                $dto->Id_LodgingPlace_DropOff,
                $adminSession['Id_Admin'],
            ));

            $oParam = array(
                'all',
                $element->Id_BookingTour,
                0,
                ''
            );
            $oData  = DB::select('call sp_booking_tour_passenger_list(?,?,?,?)', $oParam);
            foreach ($oData as $value) {

                /** @var UpdateBookingTourPassengerQueryResponse $response */
                $this->queryBus->ask(new UpdateBookingTourPassengerQuery(
                    $value->Id_BookingTourPassenger,
                    $dto->Id_LodgingPlace_PickUp,
                    $dto->Id_LodgingPlace_DropOff,
                    $adminSession['Id_Admin'],
                ));
            }
        }

        // -------------------------------------------------------------------------------------------

        // -----------------------------------------------------------

        $oResponse = [];
        $oResponse["Response_Status"]           = 200;
        $oResponse["Response_Code"]             = 200;
        $oResponse["Response_Domain"]           = $this->domain;
        $oResponse["Response_Message"]          = 'Actualizado con éxito';
        $oResponse["Response_Data"]             = null;
        $oResponse["Response_Error_Message"]    = '';
        $oResponse["Response_Error_Reason"]     = '';
        // $this->history->updateBasic($dto->Id_Room, $request);
        return ResponseBuilder::Response($oResponse);
    }
}
