<?php

namespace App\Http\Controllers\Owner\BookingTourPassenger;

use App\Http\Controllers\Controller;
use App\Http\Controllers\Owner\BookingTourPassenger\Dto\BookingTourPassengerDeleteDTO;
use App\Http\Controllers\Owner\c_Booking_Equipment_Passenger;
use App\Http\Controllers\Owner\Passenger\PassengerUpdater;
use App\Http\Helpers\ResponseBuilder;
use App\Http\History\HistoryData;
use App\Http\History\HistoryTables;
use App\Modules\BookingEquipmentPassenger\Application\BookingEquipmentPassengerResponses;
use App\Modules\BookingEquipmentPassenger\Application\List\ListBookingEquipmentPassengerQuery;
use App\Modules\BookingExtraPassenger\Application\BookingExtraPassengerResponses;
use App\Modules\BookingExtraPassenger\Application\List\ListBookingExtraPassengerQuery;
use App\Modules\BookingTourPassenger\Application\BookingTourPassengerNotificationCreator;
use App\Modules\BookingTourPassenger\Application\Index\IndexBookingTourPassengerQuery;
use App\Modules\BookingTourPassenger\Domain\BookingTourPassengerStatus;
use App\Modules\BookingUpgradePassenger\Application\BookingUpgradePassengerResponses;
use App\Modules\BookingUpgradePassenger\Application\List\ListBookingUpgradePassengerQuery;
use App\Modules\Shared\Domain\Bus\Command\CommandBus;
use App\Modules\Shared\Domain\Bus\Query\QueryBus;
use App\Modules\Shared\Infraestructure\Requester;
use App\Modules\Shared\Validator\Infraestructure\LaravelDTOGenerator;
use App\Providers\BookingItemPassenger\BookingItemPassenger;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

final class BookingTourPassengerDeleteController extends Controller
{

    private $domain = "BookingTourPassenger";
    private HistoryData $history;

    public function __construct(
        private QueryBus $queryBus,
        private CommandBus $commandBus,
        private BookingItemPassenger $bookingItemPassenger,
        private PassengerUpdater $passengerUpdater,
        private LaravelDTOGenerator $dtoGenerator,
    ) {
        $this->history = new HistoryData(HistoryTables::BOOKING_TOUR_PASSENGER);
    }

    private function findBooking($Id)
    {
        $found = DB::select(
            'Call sp_booking_tour_passenger_index(?, ?)',
            [$Id, config('var.PATH_PUBLIC') . config('var.USER_COUNTRY_THUMB')]
        );

        return count($found) ? $found[0]->Id_Booking : null;
    }

    public function __invoke(Request $request, $Id)
    {
        /** @var BookingTourPassengerDeleteDTO $dto */
        $dto = $this->dtoGenerator->generate($request->all(), $this->domain, BookingTourPassengerDeleteDTO::class);

        /** @var IndexBookingTourPassengerResponse */
        $indexResponse = $this->queryBus->ask(new IndexBookingTourPassengerQuery($Id));
        $index = $indexResponse->response()[0];

        $itemPassengers = $this->getItemPassengers($Id);
        $this->checkCanDelete($itemPassengers, $Id);
        $this->deleteItemPassengers($itemPassengers, $request);
        $this->sendDeleteNotification($Id, $request->header('Token'));

        $this->history->obtainOld($Id);
        $this->delete($index, $dto->Keep_InvoiceDetail);

        $this->history->update(
            $this->findBooking($Id),
            $this->history->oldValue,
            [],
            $request
        );

        return ResponseBuilder::generate([], 'Pasajero eliminado con éxito', $this->domain);
    }

    private function getItemPassengers($id)
    {
        /** @var BookingUpgradePassengerResponses */
        $upgrade = $this->queryBus->ask(new ListBookingUpgradePassengerQuery(idBookingTourPassengers: [$id]));
        /** @var BookingExtraPassengerResponses */
        $extra = $this->queryBus->ask(new ListBookingExtraPassengerQuery(idBookingTourPassengers: [$id]));
        /** @var BookingEquipmentPassengerResponses */
        $equipment = $this->queryBus->ask(new ListBookingEquipmentPassengerQuery(idBookingTourPassengers: [$id]));
        return [
            'upgrade' => $upgrade->data(),
            'extra' => $extra->data(),
            'equipment' => $equipment->data(),
        ];
    }

    private function checkCanDelete($itemPassengers, $id)
    {
        $this->checkCanDeleteItems($itemPassengers);
        $this->checkCanDeletePassenger($id);
    }

    private function checkCanDeleteItems($itemPassengers)
    {

        foreach ($itemPassengers['upgrade'] as $upgradePassenger) {
            $this->bookingItemPassenger->canDeleteBookingUpgradePassenger($upgradePassenger->Id_BookingUpgradePassenger);
        }
        foreach ($itemPassengers['extra'] as $extraPassenger) {
            $this->bookingItemPassenger->canDeleteBookingExtraPassenger($extraPassenger->Id_BookingExtraPassenger);
        }
    }

    private function checkCanDeletePassenger($id) {}

    private function deleteItemPassengers($itemPassengers, Request $request)
    {
        foreach ($itemPassengers['equipment'] as $equipmentPassenger) {
            c_Booking_Equipment_Passenger::removeBookingEquipmentPassenger($equipmentPassenger->Id_BookingEquipmentPassenger, 1, $request);
        }
        foreach ($itemPassengers['upgrade'] as $upgradePassenger) {
            $this->bookingItemPassenger->deleteBookingUpgradePassenger($upgradePassenger->Id_BookingUpgradePassenger, 1, $request);
        }
        foreach ($itemPassengers['extra'] as $extraPassenger) {
            $this->bookingItemPassenger->deleteBookingExtraPassenger($extraPassenger->Id_BookingExtraPassenger, 1, $request);
        }
    }

    private function delete($index, $keepInvoice)
    {
        $oParam = [$index->Id_BookingTourPassenger, BookingTourPassengerStatus::DELETED, $keepInvoice];
        $response = Requester::requestUpdate('call sp_booking_tour_passenger_status_alter(?,?,?,@sts,@cod,@msg)', $oParam);

        $this->passengerUpdater->updateLockHtlCampBookingPassenger($index->Id_Passenger);
    }

    private function sendDeleteNotification($Id, $token)
    {
        (new BookingTourPassengerNotificationCreator($this->commandBus))
            ->__invoke($Id, $token);
    }
}
