<?php

namespace App\Livewire\Appointments;

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

class Form extends Component
{
    public $showModal = true;
    public $appointment = null;
    public $editing = false;

    // Form fields
    public $customer_id = '';
    public $vehicle_id = '';
    public $assigned_technician_id = '';
    public $scheduled_date = '';
    public $scheduled_time = '';
    public $estimated_duration_minutes = 60;
    public $appointment_type = 'maintenance';
    public $service_requested = '';
    public $customer_notes = '';
    public $internal_notes = '';

    // Options
    public $customers = [];
    public $vehicles = [];
    public $technicians = [];
    public $availableTimeSlots = [];

    public $appointmentTypes = [
        'maintenance' => 'Maintenance',
        'repair' => 'Repair',
        'inspection' => 'Inspection',
        'estimate' => 'Estimate',
        'pickup' => 'Pickup',
        'delivery' => 'Delivery'
    ];

    public $durationOptions = [
        30 => '30 minutes',
        60 => '1 hour',
        90 => '1.5 hours',
        120 => '2 hours',
        180 => '3 hours',
        240 => '4 hours',
        300 => '5 hours',
        360 => '6 hours',
        480 => '8 hours'
    ];

    protected $rules = [
        'customer_id' => 'required|exists:customers,id',
        'vehicle_id' => 'required|exists:vehicles,id',
        'assigned_technician_id' => 'nullable|exists:technicians,id',
        'scheduled_date' => 'required|date|after_or_equal:today',
        'scheduled_time' => 'required|date_format:H:i',
        'estimated_duration_minutes' => 'required|integer|min:15|max:480',
        'appointment_type' => 'required|in:maintenance,repair,inspection,estimate,pickup,delivery',
        'service_requested' => 'required|string|max:1000',
        'customer_notes' => 'nullable|string|max:1000',
        'internal_notes' => 'nullable|string|max:1000'
    ];

    public function mount($appointment = null)
    {
        $this->customers = Customer::orderBy('first_name')->get();
        $this->technicians = Technician::where('status', 'active')->orderBy('first_name')->get();
        
        if ($appointment) {
            $this->appointment = $appointment;
            $this->editing = true;
            $this->loadAppointmentData();
        } else {
            $this->scheduled_date = now()->addDay()->format('Y-m-d');
            $this->scheduled_time = '09:00';
        }
    }

    public function loadAppointmentData()
    {
        $this->customer_id = $this->appointment->customer_id;
        $this->vehicle_id = $this->appointment->vehicle_id;
        $this->assigned_technician_id = $this->appointment->assigned_technician_id;
        $this->scheduled_date = $this->appointment->scheduled_datetime->format('Y-m-d');
        $this->scheduled_time = $this->appointment->scheduled_datetime->format('H:i');
        $this->estimated_duration_minutes = $this->appointment->estimated_duration_minutes;
        $this->appointment_type = $this->appointment->appointment_type;
        $this->service_requested = $this->appointment->service_requested;
        $this->customer_notes = $this->appointment->customer_notes;
        $this->internal_notes = $this->appointment->internal_notes;
        
        $this->loadVehicles();
    }

    public function updatedCustomerId()
    {
        $this->vehicle_id = '';
        $this->loadVehicles();
    }

    public function updatedScheduledDate()
    {
        $this->checkTimeSlotAvailability();
    }

    public function updatedScheduledTime()
    {
        $this->checkTimeSlotAvailability();
    }

    public function updatedAssignedTechnicianId()
    {
        $this->checkTimeSlotAvailability();
    }

    public function loadVehicles()
    {
        if ($this->customer_id) {
            $this->vehicles = Vehicle::where('customer_id', $this->customer_id)->get();
        } else {
            $this->vehicles = [];
        }
    }

    public function checkTimeSlotAvailability()
    {
        if (!$this->scheduled_date || !$this->scheduled_time || !$this->assigned_technician_id) {
            return;
        }

        $scheduledDateTime = Carbon::parse($this->scheduled_date . ' ' . $this->scheduled_time);
        $endDateTime = $scheduledDateTime->copy()->addMinutes($this->estimated_duration_minutes);

        // Check for conflicts
        $conflicts = Appointment::where('assigned_technician_id', $this->assigned_technician_id)
            ->where('status', '!=', 'cancelled')
            ->where(function ($query) use ($scheduledDateTime, $endDateTime) {
                $query->whereBetween('scheduled_datetime', [$scheduledDateTime, $endDateTime])
                      ->orWhere(function ($q) use ($scheduledDateTime, $endDateTime) {
                          $q->where('scheduled_datetime', '<=', $scheduledDateTime)
                            ->whereRaw('DATE_ADD(scheduled_datetime, INTERVAL estimated_duration_minutes MINUTE) > ?', [$scheduledDateTime]);
                      });
            });

        if ($this->editing && $this->appointment) {
            $conflicts->where('id', '!=', $this->appointment->id);
        }

        if ($conflicts->exists()) {
            $this->addError('scheduled_time', 'This time slot conflicts with another appointment for the selected technician.');
        } else {
            $this->resetErrorBag('scheduled_time');
        }
    }

    public function save()
    {
        $this->validate();

        $scheduledDateTime = Carbon::parse($this->scheduled_date . ' ' . $this->scheduled_time);

        $data = [
            'customer_id' => $this->customer_id,
            'vehicle_id' => $this->vehicle_id,
            'assigned_technician_id' => $this->assigned_technician_id ?: null,
            'scheduled_datetime' => $scheduledDateTime,
            'estimated_duration_minutes' => $this->estimated_duration_minutes,
            'appointment_type' => $this->appointment_type,
            'service_requested' => $this->service_requested,
            'customer_notes' => $this->customer_notes,
            'internal_notes' => $this->internal_notes,
            'status' => 'scheduled'
        ];

        if ($this->editing && $this->appointment) {
            $this->appointment->update($data);
            session()->flash('message', 'Appointment updated successfully!');
        } else {
            Appointment::create($data);
            session()->flash('message', 'Appointment scheduled successfully!');
        }

        $this->dispatch('appointment-saved');
        $this->closeModal();
    }

    public function closeModal()
    {
        $this->showModal = false;
        $this->dispatch('close-appointment-form');
    }

    public function render()
    {
        return view('livewire.appointments.form');
    }
}
