<?php

require_once BASE_PATH . '/app/controllers/customer/CustomerBaseController.php';
require_once BASE_PATH . '/app/models/Booking.php';
require_once BASE_PATH . '/app/models/Service.php';
require_once BASE_PATH . '/app/models/BookingStatusLog.php';
require_once BASE_PATH . '/app/models/SpaActivityLog.php';

class CustomerBookingController extends CustomerBaseController
{
    private Booking $bookings;
    private Service $services;
    private SpaActivityLog $activityLog;

    public function __construct()
    {
        $this->requireCustomer();
        $this->bookings = new Booking();
        $this->services = new Service();
        $this->activityLog = new SpaActivityLog();
    }

    public function index(): void
    {
        $customerId = (int) $_SESSION['user']['id'];
        $status = (string) ($_GET['status'] ?? '');
        $allowed = ['', 'pending', 'confirmed', 'in_progress', 'completed', 'cancelled'];
        if (!in_array($status, $allowed, true)) { $status = ''; }
        $bookings = $this->bookings->getForCustomer($customerId, $status);
        require BASE_PATH . '/app/views/customer/bookings.php';
    }

    public function create(): void
    {
        $service = $this->services->findActiveById((int) ($_GET['service_id'] ?? 0));
        $services = $this->services->getPublic();
        require BASE_PATH . '/app/views/booking/create.php';
    }

    public function availableSlots(): void
    {
        header('Content-Type: application/json; charset=utf-8');
        try {
            $slots = $this->bookings->getAvailableSlots((int) ($_GET['service_id'] ?? 0), (string) ($_GET['date'] ?? ''));
            echo json_encode(['ok' => true, 'slots' => $slots], JSON_UNESCAPED_UNICODE);
        } catch (Throwable $e) {
            http_response_code(422);
            echo json_encode(['ok' => false, 'message' => $e->getMessage()], JSON_UNESCAPED_UNICODE);
        }
    }

    public function store(): void
    {
        $this->requirePost(); $this->validateCsrf();
        try {
            $booking = $this->bookings->createForCustomer((int) $_SESSION['user']['id'], $_POST);
            $this->activityLog->record(
                (int) $_SESSION['user']['id'],
                'customer.booking.create',
                'booking',
                (int) $booking['id'],
                ['service_id' => (int) $booking['service_id'], 'booking_date' => $booking['booking_date'], 'start_time' => $booking['start_time']]
            );
            $this->flashSuccess('Đã gửi yêu cầu đặt lịch. Spa sẽ xác nhận sớm.');
            $this->detailRedirect((int) $booking['id']);
        } catch (Throwable $e) {
            $this->flashError($e->getMessage());
            header('Location: ' . BASE_URL . '/?url=customer/booking/create&service_id=' . (int) ($_POST['service_id'] ?? 0)); exit;
        }
    }

    public function detail(): void
    {
        $booking = $this->bookings->findForCustomer((int) ($_GET['id'] ?? 0), (int) $_SESSION['user']['id']);
        if (!$booking) { http_response_code(404); require BASE_PATH . '/app/views/errors/404.php'; return; }
        $statusLogs = (new BookingStatusLog())->getForBooking((int) $booking['id']);
        require BASE_PATH . '/app/views/customer/booking-detail.php';
    }

    public function cancel(): void
    {
        $this->requirePost(); $this->validateCsrf();
        $id = (int) ($_POST['booking_id'] ?? 0);
        try { $this->bookings->cancelByCustomer($id, (int) $_SESSION['user']['id']); $this->activityLog->record((int) $_SESSION['user']['id'], 'customer.booking.cancel', 'booking', $id); $this->flashSuccess('Đã hủy lịch hẹn.'); }
        catch (Throwable $e) { $this->flashError($e->getMessage()); }
        $this->detailRedirect($id);
    }

    private function detailRedirect(int $id): never { header('Location: ' . BASE_URL . '/?url=customer/booking&id=' . $id); exit; }
}
