<?php
declare(strict_types=1);

require_once __DIR__ . '/config/database.php';
require_once __DIR__ . '/config/session.php';
require_once __DIR__ . '/config/mailer.php';

function bookingError(string $message = 'error'): void
{
    http_response_code(400);
    echo $message;
    exit;
}

function bookingJsonResponse(array $payload, int $status = 200): void
{
    http_response_code($status);
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode($payload);
    exit;
}

function bookingServicePriceByName(string $serviceName): float
{
    $nameKey = strtolower(trim($serviceName));
    if (strpos($nameKey, 'restaurant') !== false || strpos($nameKey, 'dining') !== false) {
        return 49.00;
    }
    if (strpos($nameKey, 'pool') !== false) {
        return 29.00;
    }
    if (strpos($nameKey, 'spa') !== false || strpos($nameKey, 'massage') !== false) {
        return 79.00;
    }
    if (strpos($nameKey, 'fitness') !== false || strpos($nameKey, 'gym') !== false) {
        return 19.00;
    }
    if (strpos($nameKey, 'meeting') !== false) {
        return 99.00;
    }
    if (strpos($nameKey, 'laundry') !== false) {
        return 15.00;
    }
    return 39.00;
}

function bookingEscape(string $value): string
{
    return htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
}

function bookingFormatDate(string $date): string
{
    $ts = strtotime($date);
    if ($ts === false) {
        return $date;
    }
    return date('F j, Y', $ts);
}

function bookingBuildConfirmationEmail(array $data): string
{
    $guestName = bookingEscape((string)($data['guest_name'] ?? 'Guest'));
    $bookingId = bookingEscape((string)($data['booking_id'] ?? '-'));
    $reservationLabel = bookingEscape((string)($data['reservation_label'] ?? 'Reservation'));
    $selectedLabel = bookingEscape((string)($data['selected_label'] ?? '-'));
    $checkIn = bookingEscape((string)($data['check_in'] ?? '-'));
    $checkOut = bookingEscape((string)($data['check_out'] ?? '-'));
    $guestCount = bookingEscape((string)($data['guest_count'] ?? '-'));
    $phone = bookingEscape((string)($data['phone'] ?? '-'));
    $specialRequests = trim((string)($data['special_requests'] ?? ''));
    $specialRequestsText = $specialRequests !== '' ? bookingEscape($specialRequests) : 'None';
    $totalPrice = bookingEscape((string)($data['total_price'] ?? '0.00'));
    $unitPriceLabel = bookingEscape((string)($data['unit_price_label'] ?? ''));

    return <<<HTML
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <style>
        body { font-family: Arial, sans-serif; color: #1f2937; background: #f5f7fb; margin: 0; padding: 24px; }
        .card { max-width: 680px; margin: 0 auto; background: #ffffff; border: 1px solid #dbe5ef; border-radius: 12px; overflow: hidden; }
        .header { padding: 20px 24px; background: #0f2942; color: #ffffff; }
        .header h2 { margin: 0; font-size: 22px; }
        .content { padding: 22px 24px; }
        .kicker { margin: 0 0 14px; color: #4b5f75; }
        .meta { width: 100%; border-collapse: collapse; margin: 10px 0 16px; }
        .meta td { border-bottom: 1px solid #e6edf5; padding: 10px 0; vertical-align: top; }
        .meta td:first-child { width: 40%; color: #607286; font-weight: 600; }
        .total { margin-top: 6px; padding: 12px 14px; border: 1px solid #cfe0f3; border-radius: 10px; background: #f3f8fe; font-size: 16px; }
        .footer { margin-top: 18px; color: #607286; font-size: 12px; }
    </style>
</head>
<body>
    <div class="card">
        <div class="header">
            <h2>Zemaraim Booking Confirmation</h2>
        </div>
        <div class="content">
            <p class="kicker">Hello {$guestName}, your {$reservationLabel} has been received successfully.</p>
            <table class="meta">
                <tr><td>Booking ID</td><td>#{$bookingId}</td></tr>
                <tr><td>Reservation Type</td><td>{$reservationLabel}</td></tr>
                <tr><td>Selected {$reservationLabel}</td><td>{$selectedLabel}</td></tr>
                <tr><td>Check In</td><td>{$checkIn}</td></tr>
                <tr><td>Check Out</td><td>{$checkOut}</td></tr>
                <tr><td>Guests</td><td>{$guestCount}</td></tr>
                <tr><td>Contact Number</td><td>{$phone}</td></tr>
                <tr><td>Special Requests</td><td>{$specialRequestsText}</td></tr>
                <tr><td>Rate Details</td><td>{$unitPriceLabel}</td></tr>
            </table>
            <div class="total"><strong>Total Cost:</strong> \${$totalPrice}</div>
            <p class="footer">Status: Pending confirmation. Our team will contact you if any additional information is required.</p>
        </div>
    </div>
</body>
</html>
HTML;
}

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    bookingError('error');
}

if (!function_exists('isLoggedIn') || !isLoggedIn()) {
    bookingJsonResponse([
        'status' => 'error',
        'code' => 'login_required',
        'message' => 'Please login before making a reservation.'
    ], 401);
}

$roomId = (int)($_POST['room_id'] ?? 0);
$facilityId = (int)($_POST['facility_id'] ?? 0);
$reservationType = strtolower(trim((string)($_POST['reservation_type'] ?? 'room')));
if ($reservationType !== 'service') {
    $reservationType = 'room';
}
$checkIn = trim((string)($_POST['check_in'] ?? ''));
$checkOut = trim((string)($_POST['check_out'] ?? ''));
$guests = (int)($_POST['adult'] ?? 0);
$roomCount = (int)($_POST['room_count'] ?? 1);
$name = trim((string)($_POST['name'] ?? ''));
$email = trim((string)($_POST['email'] ?? ''));
$phone = trim((string)($_POST['phone'] ?? ''));
$message = trim((string)($_POST['message'] ?? ''));

if ($checkIn === '' || $checkOut === '' || $guests <= 0 || $name === '' || $email === '' || $phone === '') {
    bookingError('error');
}

if ($reservationType === 'room' && $roomId <= 0) {
    bookingError('error');
}

if ($reservationType === 'service' && $facilityId <= 0) {
    bookingError('error');
}

if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    bookingError('error');
}

$checkInDate = DateTime::createFromFormat('Y-m-d', $checkIn);
$checkOutDate = DateTime::createFromFormat('Y-m-d', $checkOut);
if (!$checkInDate || !$checkOutDate) {
    bookingError('error');
}

$nightCount = (int)$checkInDate->diff($checkOutDate)->format('%a');
if ($nightCount < 1) {
    bookingError('error');
}

if ($roomCount < 1) {
    $roomCount = 1;
}

$totalPrice = 0.0;
$servicePrice = 0.0;
$serviceTotalPrice = 0.0;
$roomTypeName = '';
$facilityName = '';
if ($reservationType === 'room') {
    $roomStmt = $conn->prepare("SELECT id, room_type, max_guests, price_per_night, is_available FROM rooms WHERE id = ? LIMIT 1");
    if (!$roomStmt) {
        bookingError('error');
    }
    $roomStmt->bind_param('i', $roomId);
    $roomStmt->execute();
    $roomResult = $roomStmt->get_result();
    $room = $roomResult ? $roomResult->fetch_assoc() : null;
    $roomStmt->close();

    if (!$room || (int)$room['is_available'] !== 1) {
        bookingError('error');
    }

    if ($guests > (int)$room['max_guests']) {
        bookingError('error');
    }

    $roomTypeName = trim((string)($room['room_type'] ?? 'Room'));
    $pricePerNight = (float)$room['price_per_night'];
    $totalPrice = $pricePerNight * $nightCount * $roomCount;
} else {
    $facilityStmt = $conn->prepare("SELECT id, name FROM facilities WHERE id = ? AND is_active = 1 LIMIT 1");
    if (!$facilityStmt) {
        bookingError('error');
    }
    $facilityStmt->bind_param('i', $facilityId);
    $facilityStmt->execute();
    $facilityResult = $facilityStmt->get_result();
    $facility = $facilityResult ? $facilityResult->fetch_assoc() : null;
    $facilityStmt->close();

    if (!$facility) {
        bookingError('error');
    }

    $facilityName = trim((string)($facility['name'] ?? 'Service'));
    $servicePrice = bookingServicePriceByName((string)($facility['name'] ?? ''));
    $serviceTotalPrice = $servicePrice * max(1, $guests) * max(1, $nightCount);
}

$userId = function_exists('getCurrentUserId') ? (int)(getCurrentUserId() ?? 0) : 0;
if ($userId <= 0) {
    bookingJsonResponse([
        'status' => 'error',
        'code' => 'login_required',
        'message' => 'Session expired. Please login again.'
    ], 401);
}

$fullNameParts = preg_split('/\s+/', trim($name));
$firstName = trim((string)($fullNameParts[0] ?? ''));
$lastName = trim((string)implode(' ', array_slice((array)$fullNameParts, 1)));
if ($firstName !== '' || $lastName !== '' || $phone !== '' || $email !== '') {
    $updateUser = $conn->prepare("UPDATE users SET first_name = ?, last_name = ?, email = ?, phone = ?, updated_at = NOW() WHERE id = ? LIMIT 1");
    if ($updateUser) {
        $updateUser->bind_param('ssssi', $firstName, $lastName, $email, $phone, $userId);
        $updateUser->execute();
        $updateUser->close();
    }
}

$bookingId = 0;
if ($reservationType === 'room') {
    $reservationStmt = $conn->prepare(
        "INSERT INTO reservations (
            user_id, room_id, check_in_date, check_out_date, number_of_guests,
            number_of_rooms, total_price, status, special_requests, payment_status, created_at, updated_at
        ) VALUES (?, ?, ?, ?, ?, ?, ?, 'pending', ?, 'unpaid', NOW(), NOW())"
    );

    if (!$reservationStmt) {
        bookingError('error');
    }

    $reservationStmt->bind_param(
        'iissiids',
        $userId,
        $roomId,
        $checkIn,
        $checkOut,
        $guests,
        $roomCount,
        $totalPrice,
        $message
    );

    if (!$reservationStmt->execute()) {
        $reservationStmt->close();
        bookingError('error');
    }

    $bookingId = (int)$reservationStmt->insert_id;
    $reservationStmt->close();
} else {
    $hasServicePriceColumn = false;
    $hasServiceTotalPriceColumn = false;
    $servicePriceColumnResult = $conn->query("SHOW COLUMNS FROM service_reservations LIKE 'service_price'");
    if ($servicePriceColumnResult instanceof mysqli_result) {
        $hasServicePriceColumn = $servicePriceColumnResult->num_rows > 0;
        $servicePriceColumnResult->free();
    }
    $serviceTotalPriceColumnResult = $conn->query("SHOW COLUMNS FROM service_reservations LIKE 'total_price'");
    if ($serviceTotalPriceColumnResult instanceof mysqli_result) {
        $hasServiceTotalPriceColumn = $serviceTotalPriceColumnResult->num_rows > 0;
        $serviceTotalPriceColumnResult->free();
    }

    if ($hasServicePriceColumn && $hasServiceTotalPriceColumn) {
        $serviceStmt = $conn->prepare(
            "INSERT INTO service_reservations (
                user_id, facility_id, service_start_date, service_end_date, number_of_guests,
                service_price, total_price, status, special_requests, created_at, updated_at
            ) VALUES (?, ?, ?, ?, ?, ?, ?, 'pending', ?, NOW(), NOW())"
        );

        if (!$serviceStmt) {
            bookingError('error');
        }

        $serviceStmt->bind_param(
            'iissidds',
            $userId,
            $facilityId,
            $checkIn,
            $checkOut,
            $guests,
            $servicePrice,
            $serviceTotalPrice,
            $message
        );
    } elseif ($hasServicePriceColumn) {
        $serviceStmt = $conn->prepare(
            "INSERT INTO service_reservations (
                user_id, facility_id, service_start_date, service_end_date, number_of_guests,
                service_price, status, special_requests, created_at, updated_at
            ) VALUES (?, ?, ?, ?, ?, ?, 'pending', ?, NOW(), NOW())"
        );

        if (!$serviceStmt) {
            bookingError('error');
        }

        $serviceStmt->bind_param(
            'iissids',
            $userId,
            $facilityId,
            $checkIn,
            $checkOut,
            $guests,
            $servicePrice,
            $message
        );
    } else {
        $serviceStmt = $conn->prepare(
            "INSERT INTO service_reservations (
                user_id, facility_id, service_start_date, service_end_date, number_of_guests,
                status, special_requests, created_at, updated_at
            ) VALUES (?, ?, ?, ?, ?, 'pending', ?, NOW(), NOW())"
        );

        if (!$serviceStmt) {
            bookingError('error');
        }

        $serviceStmt->bind_param(
            'iissis',
            $userId,
            $facilityId,
            $checkIn,
            $checkOut,
            $guests,
            $message
        );
    }

    if (!$serviceStmt->execute()) {
        $serviceStmt->close();
        bookingError('error');
    }

    $bookingId = (int)$serviceStmt->insert_id;
    $serviceStmt->close();
}

$reservationLabel = $reservationType === 'service' ? 'Service Booking' : 'Room Booking';
$selectedLabel = $reservationType === 'service' ? $facilityName : $roomTypeName;
$formattedCheckIn = bookingFormatDate($checkIn);
$formattedCheckOut = bookingFormatDate($checkOut);
$effectiveTotal = $reservationType === 'service' ? $serviceTotalPrice : $totalPrice;
$rateLabel = $reservationType === 'service'
    ? '$' . number_format($servicePrice, 2) . ' per guest per day'
    : '$' . number_format(($totalPrice / max(1, ($nightCount * $roomCount))), 2) . ' per room per night';

$emailSubject = 'Your Zemaraim ' . ($reservationType === 'service' ? 'Service Reservation' : 'Room Reservation') . ' Confirmation';
$emailBody = bookingBuildConfirmationEmail([
    'guest_name' => $name,
    'booking_id' => (string)$bookingId,
    'reservation_label' => $reservationLabel,
    'selected_label' => $selectedLabel !== '' ? $selectedLabel : ($reservationType === 'service' ? 'Service' : 'Room'),
    'check_in' => $formattedCheckIn,
    'check_out' => $formattedCheckOut,
    'guest_count' => (string)$guests,
    'phone' => $phone,
    'special_requests' => $message,
    'total_price' => number_format($effectiveTotal, 2),
    'unit_price_label' => $rateLabel,
]);

$emailSent = sendEmail($email, $name !== '' ? $name : 'Guest', $emailSubject, $emailBody);
$responseMessage = $reservationType === 'service'
    ? 'Service reservation confirmed successfully.'
    : 'Room reservation confirmed successfully.';
if (!$emailSent) {
    $responseMessage .= ' Booking created, but we could not send the confirmation email.';
}

bookingJsonResponse([
    'status' => 'success',
    'code' => 'sent',
    'email_sent' => $emailSent,
    'reservation_type' => $reservationType,
    'booking_id' => $bookingId,
    'room_total_price' => $reservationType === 'room' ? $totalPrice : null,
    'service_price' => $reservationType === 'service' ? $servicePrice : null,
    'service_total_price' => $reservationType === 'service' ? $serviceTotalPrice : null,
    'message' => $responseMessage
]);
