<?php\
\
namespace App\\Controllers;\
\
use App\\Models\\EmployeeModel;\
use App\\Models\\AppointmentSettingModel;\
use App\\Models\\BlockedDateModel;\
use App\\Models\\AppointmentModel;\
use CodeIgniter\\I18n\\Time;\
\
class Appointment extends BaseController\
{\
    public function index($slug)\
    {\
        $employeeModel = new EmployeeModel();\
        $employee = $employeeModel->where('slug', $slug)->first();\
\
        if (!$employee) {\
            return view('errors/html/error_404', ['message' => 'Employee not found']);\
        }\
\
        return view('card/appointment', ['employee' => $employee]);\
    }\
\
    public function slots($slug)\
    {\
        if (!$this->request->isAJAX()) {\
            return $this->response->setStatusCode(403);\
        }\
\
        $date = $this->request->getPost('date'); // YYYY-MM-DD format\
        if (!$date) {\
            return $this->response->setJSON(['error' => 'Date is required']);\
        }\
\
        $employeeModel = new EmployeeModel();\
        $employee = $employeeModel->where('slug', $slug)->first();\
\
        if (!$employee) {\
            return $this->response->setJSON(['error' => 'Employee not found']);\
        }\
\
        $time = Time::parse($date);\
        $dayOfWeek = $time->format('l');\
\
        // Check blocked dates\
        $blockedDateModel = new BlockedDateModel();\
        $isBlocked = $blockedDateModel->where('employee_id', $employee['id'])\
                                      ->where('blocked_date', $date)\
                                      ->first();\
        if ($isBlocked) {\
            return $this->response->setJSON(['slots' => []]);\
        }\
\
        // Get settings for the day\
        $settingModel = new AppointmentSettingModel();\
        $setting = $settingModel->where('employee_id', $employee['id'])\
                                ->where('day_of_week', $dayOfWeek)\
                                ->where('is_active', 1)\
                                ->first();\
\
        if (!$setting) {\
            return $this->response->setJSON(['slots' => []]);\
        }\
\
        // Generate slots\
        $slots = [];\
        $startTime = Time::parse($date . ' ' . $setting['start_time']);\
        $endTime = Time::parse($date . ' ' . $setting['end_time']);\
        \
        $duration = $setting['slot_duration'] + $setting['buffer_minutes'];\
\
        // Get existing appointments\
        $appointmentModel = new AppointmentModel();\
        $appointments = $appointmentModel->where('employee_id', $employee['id'])\
                                         ->where('appointment_date', $date)\
                                         ->whereIn('status', ['confirmed', 'completed'])\
                                         ->findAll();\
        \
        $bookedTimes = array_column($appointments, 'start_time');\
\
        while ($startTime->isBefore($endTime)) {\
            $timeStr = $startTime->format('H:i:s');\
            \
            // Check if time is in the past for today\
            $isPast = false;\
            if ($date === Time::now()->toDateString() && $startTime->isBefore(Time::now())) {\
                $isPast = true;\
            }\
\
            $isBooked = in_array($timeStr, $bookedTimes) || $isPast;\
\
            // Ensure slot ends before end time\
            $slotEnd = $startTime->addMinutes($setting['slot_duration']);\
            if ($slotEnd->isAfter($endTime)) {\
                break;\
            }\
\
            $slots[] = [\
                'time' => $startTime->format('h:i A'),\
                'value' => $timeStr,\
                'available' => !$isBooked\
            ];\
\
            $startTime = $startTime->addMinutes($duration);\
        }\
\
        return $this->response->setJSON(['slots' => $slots]);\
    }\
\
    public function book($slug)\
    {\
        $employeeModel = new EmployeeModel();\
        $employee = $employeeModel->where('slug', $slug)->first();\
\
        if (!$employee) {\
            return redirect()->back()->with('error', 'Employee not found');\
        }\
\
        $rules = [\
            'date' => 'required|valid_date',\
            'time' => 'required',\
            'name' => 'required',\
            'phone' => 'required',\
            'email' => 'required|valid_email'\
        ];\
\
        if (!$this->validate($rules)) {\
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());\
        }\
\
        $date = $this->request->getPost('date');\
        $time = $this->request->getPost('time');\
\
        // Re-verify availability\
        $appointmentModel = new AppointmentModel();\
        $existing = $appointmentModel->where('employee_id', $employee['id'])\
                                     ->where('appointment_date', $date)\
                                     ->where('start_time', $time)\
                                     ->whereIn('status', ['confirmed', 'completed'])\
                                     ->first();\
        \
        if ($existing) {\
            return redirect()->back()->withInput()->with('error', 'Sorry, this time slot was just booked. Please choose another time.');\
        }\
\
        // Get setting to calculate end time\
        $timeObj = Time::parse($date);\
        $dayOfWeek = $timeObj->format('l');\
        \
        $settingModel = new AppointmentSettingModel();\
        $setting = $settingModel->where('employee_id', $employee['id'])\
                                ->where('day_of_week', $dayOfWeek)\
                                ->first();\
        \
        $duration = $setting ? $setting['slot_duration'] : 30;\
        $endTime = Time::parse($date . ' ' . $time)->addMinutes($duration)->format('H:i:s');\
\
        // Create booking\
        $reference = 'FO-' . date('Y') . '-' . strtoupper(substr(md5(uniqid()), 0, 6));\
\
        $data = [\
            'employee_id' => $employee['id'],\
            'appointment_date' => $date,\
            'start_time' => $time,\
            'end_time' => $endTime,\
            'customer_name' => $this->request->getPost('name'),\
            'customer_phone' => $this->request->getPost('phone'),\
            'customer_email' => $this->request->getPost('email'),\
            'customer_company' => $this->request->getPost('company'),\
            'purpose' => $this->request->getPost('purpose') ?? 'General Meeting',\
            'message' => $this->request->getPost('message'),\
            'booking_reference' => $reference,\
            'status' => 'confirmed'\
        ];\
\
        try {\
            $appointmentModel->insert($data);\
            return redirect()->to('booking/' . $reference);\
        } catch (\\Exception $e) {\
            // Likely a unique constraint violation (double booking)\
            return redirect()->back()->withInput()->with('error', 'Sorry, this time slot was just booked. Please choose another time.');\
        }\
    }\
}\

