<?php

namespace App\Livewire\Appointments;

use Livewire\Component;
use Livewire\WithPagination;
use Livewire\Attributes\On;
use App\Models\Appointment;
use App\Models\Technician;
use Carbon\Carbon;

class Index extends Component
{
    use WithPagination;

    public $search = '';
    public $statusFilter = '';
    public $technicianFilter = '';
    public $dateFilter = '';
    public $typeFilter = '';
    public $view = 'list'; // list or calendar
    public $selectedDate;
    public $showForm = false;
    public $selectedAppointment = null;

    protected $queryString = [
        'search' => ['except' => ''],
        'statusFilter' => ['except' => ''],
        'technicianFilter' => ['except' => ''],
        'dateFilter' => ['except' => ''],
        'typeFilter' => ['except' => ''],
        'view' => ['except' => 'list']
    ];

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

    public function updatingSearch()
    {
        $this->resetPage();
    }

    public function updatingStatusFilter()
    {
        $this->resetPage();
    }

    public function updatingTechnicianFilter()
    {
        $this->resetPage();
    }

    public function updatingDateFilter()
    {
        $this->resetPage();
    }

    public function updatingTypeFilter()
    {
        $this->resetPage();
    }

    public function setView($view)
    {
        $this->view = $view;
    }

    public function clearFilters()
    {
        $this->search = '';
        $this->statusFilter = '';
        $this->technicianFilter = '';
        $this->dateFilter = '';
        $this->typeFilter = '';
        $this->resetPage();
    }

    public function createAppointment()
    {
        $this->selectedAppointment = null;
        $this->showForm = true;
    }

    public function editAppointment($appointmentId)
    {
        $this->selectedAppointment = Appointment::find($appointmentId);
        $this->showForm = true;
    }

    #[On('appointment-saved')]
    public function refreshAppointments()
    {
        $this->showForm = false;
        $this->resetPage();
    }

    #[On('close-appointment-form')]
    public function closeForm()
    {
        $this->showForm = false;
    }

    #[On('appointment-updated')]
    public function refreshData()
    {
        // This will trigger a re-render
    }

    public function confirmAppointment($appointmentId)
    {
        $appointment = Appointment::find($appointmentId);
        if ($appointment && $appointment->confirm()) {
            session()->flash('message', 'Appointment confirmed successfully!');
            $this->dispatch('appointment-updated');
        }
    }

    public function checkInAppointment($appointmentId)
    {
        $appointment = Appointment::find($appointmentId);
        if ($appointment && $appointment->checkIn()) {
            session()->flash('message', 'Customer checked in successfully!');
            $this->dispatch('appointment-updated');
        }
    }

    public function completeAppointment($appointmentId)
    {
        $appointment = Appointment::find($appointmentId);
        if ($appointment && $appointment->complete()) {
            session()->flash('message', 'Appointment completed successfully!');
            $this->dispatch('appointment-updated');
        }
    }

    public function cancelAppointment($appointmentId)
    {
        $appointment = Appointment::find($appointmentId);
        if ($appointment && $appointment->cancel()) {
            session()->flash('message', 'Appointment cancelled successfully!');
            $this->dispatch('appointment-updated');
        }
    }

    public function markNoShow($appointmentId)
    {
        $appointment = Appointment::find($appointmentId);
        if ($appointment && $appointment->markNoShow()) {
            session()->flash('message', 'Appointment marked as no-show.');
            $this->dispatch('appointment-updated');
        }
    }

    public function getAppointmentsProperty()
    {
        $query = Appointment::query()
            ->with(['customer', 'vehicle', 'assignedTechnician'])
            ->when($this->search, function ($q) {
                $q->whereHas('customer', function ($customer) {
                    $customer->where('first_name', 'like', '%' . $this->search . '%')
                            ->orWhere('last_name', 'like', '%' . $this->search . '%')
                            ->orWhere('email', 'like', '%' . $this->search . '%');
                })->orWhereHas('vehicle', function ($vehicle) {
                    $vehicle->where('make', 'like', '%' . $this->search . '%')
                           ->orWhere('model', 'like', '%' . $this->search . '%')
                           ->orWhere('license_plate', 'like', '%' . $this->search . '%');
                })->orWhere('service_requested', 'like', '%' . $this->search . '%');
            })
            ->when($this->statusFilter, function ($q) {
                $q->where('status', $this->statusFilter);
            })
            ->when($this->technicianFilter, function ($q) {
                $q->where('assigned_technician_id', $this->technicianFilter);
            })
            ->when($this->typeFilter, function ($q) {
                $q->where('appointment_type', $this->typeFilter);
            })
            ->when($this->dateFilter, function ($q) {
                switch ($this->dateFilter) {
                    case 'today':
                        $q->whereDate('scheduled_datetime', today());
                        break;
                    case 'tomorrow':
                        $q->whereDate('scheduled_datetime', today()->addDay());
                        break;
                    case 'this_week':
                        $q->whereBetween('scheduled_datetime', [
                            now()->startOfWeek(),
                            now()->endOfWeek()
                        ]);
                        break;
                    case 'next_week':
                        $q->whereBetween('scheduled_datetime', [
                            now()->addWeek()->startOfWeek(),
                            now()->addWeek()->endOfWeek()
                        ]);
                        break;
                    case 'overdue':
                        $q->where('status', 'scheduled')
                          ->where('scheduled_datetime', '<', now());
                        break;
                }
            })
            ->orderBy('scheduled_datetime', 'asc');

        return $query->paginate(15);
    }

    public function getTechniciansProperty()
    {
        return Technician::where('status', 'active')
            ->orderBy('first_name')
            ->get();
    }

    public function getTodayStatsProperty()
    {
        $today = today();
        return [
            'total' => Appointment::whereDate('scheduled_datetime', $today)->count(),
            'confirmed' => Appointment::whereDate('scheduled_datetime', $today)->where('status', 'confirmed')->count(),
            'in_progress' => Appointment::whereDate('scheduled_datetime', $today)->where('status', 'in_progress')->count(),
            'completed' => Appointment::whereDate('scheduled_datetime', $today)->where('status', 'completed')->count(),
        ];
    }

    public function render()
    {
        return view('livewire.appointments.index', [
            'appointments' => $this->appointments,
            'technicians' => $this->technicians,
            'todayStats' => $this->todayStats,
        ]);
    }
}
