<?php

namespace Modules\Hotel\Livewire;

use Modules\Hotel\Entities\Reservation;
use Modules\Hotel\Entities\Guest;
use Modules\Hotel\Entities\RoomType;
use Modules\Hotel\Entities\RatePlan;
use Modules\Hotel\Enums\ReservationStatus;
use Modules\Hotel\Helpers\HotelHelper;
use Jantinnerezo\LivewireAlert\LivewireAlert;
use Livewire\Component;
use Livewire\WithPagination;
use Livewire\Attributes\On;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;

class Reservations extends Component
{
    use LivewireAlert, WithPagination;

    public $showAddReservationModal = false;
    public $showEditReservationModal = false;
    public $showEditReservationFormModal = false;
    public $confirmCancelReservationModal = false;
    public $activeReservation;
    public $activeReservationForEdit = null;
    public $search = '';
    public $filterStatus = '';
    public $filterDate = '';

    public function mount()
    {
        $this->filterDate = now()->format('Y-m-d');
    }

    public function showEditReservation($id)
    {
        $this->activeReservation = Reservation::with([
            'primaryGuest',
            'ratePlan',
            'reservationRooms.roomType',
            'stays.folio.folioPayments',
        ])->findOrFail($id);
        $this->showEditReservationModal = true;
    }

    public function closeViewReservationModal()
    {
        $this->showEditReservationModal = false;
        $this->activeReservation = null;
    }

    public function openEditReservationForm($id)
    {
        $reservation = Reservation::findOrFail($id);
        if (!in_array($reservation->status->value, ['tentative', 'confirmed'])) {
            $this->alert('warning', __('hotel::modules.reservation.onlyTentativeConfirmedEditable'), [
                'toast' => true,
                'position' => 'top-end',
                'showCancelButton' => false,
                'cancelButtonText' => __('app.close')
            ]);
            return;
        }
        $this->showEditReservationModal = false;
        $this->activeReservation = null;
        $this->activeReservationForEdit = $id;
        $this->showEditReservationFormModal = true;
    }

    public function closeEditReservationForm()
    {
        $this->showEditReservationFormModal = false;
        $this->activeReservationForEdit = null;
    }

    protected function getListeners()
    {
        return [
            'reservationUpdated' => 'handleReservationUpdated',
            'closeEditReservationModal' => 'closeEditReservationForm',
            'reservationAdded' => '$refresh',
            'hideAddReservation' => 'hideAddReservation',
        ];
    }

    public function hideAddReservation()
    {
        $this->showAddReservationModal = false;
    }

    public function clearFilters()
    {
        $this->filterStatus = '';
    }

    public function handleReservationUpdated()
    {
        $this->closeEditReservationForm();
        $this->closeViewReservationModal();
    }

    public function showCancelReservation($id)
    {
        $this->confirmCancelReservationModal = true;
        $this->activeReservation = Reservation::findOrFail($id);
    }

    public function cancelReservation($id)
    {
        $reservation = Reservation::findOrFail($id);
        $reservation->update([
            'status' => ReservationStatus::CANCELLED,
            'cancelled_at' => now(),
            'cancelled_by' => Auth::id(),
        ]);

        $this->confirmCancelReservationModal = false;
        $this->alert('success', __('hotel::modules.reservation.reservationCancelled'), [
            'toast' => true,
            'position' => 'top-end',
            'showCancelButton' => false,
            'cancelButtonText' => __('app.close')
        ]);

        $this->activeReservation = null;
    }

    public function render()
    {
        $query = Reservation::with(['primaryGuest', 'ratePlan', 'reservationRooms.roomType'])
            ->when($this->search, function ($q) {
                $q->where(function ($query) {
                    $query->where('reservation_number', 'like', '%' . $this->search . '%')
                        ->orWhereHas('primaryGuest', function ($q) {
                            $q->where('first_name', 'like', '%' . $this->search . '%')
                                ->orWhere('last_name', 'like', '%' . $this->search . '%')
                                ->orWhere('email', 'like', '%' . $this->search . '%')
                                ->orWhere('phone', 'like', '%' . $this->search . '%');
                        });
                });
            })
            ->when($this->filterStatus, function ($q) {
                $q->where('status', $this->filterStatus);
            })
            ->when($this->filterDate, function ($q) {
                $q->whereDate('check_in_date', $this->filterDate);
            })
            ->orderBy('check_in_date', 'desc');

        return view('hotel::livewire.reservations', [
            'reservations' => $query->paginate(20),
            'statuses' => ReservationStatus::cases(),
        ]);
    }
}
