<?php
require_once '../db.php';
require_once './soft_delete_helpers.php';

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(["success" => false, "message" => "Method not allowed"]);
    exit;
}

$data = json_decode(file_get_contents("php://input"), true);
if (!is_array($data)) {
    $data = [];
}

$id = isset($data["id"]) ? (int) $data["id"] : 0;
$status = isset($data["status"]) ? trim((string) $data["status"]) : "";
$cancelledBy = isset($data["cancelledBy"]) ? trim((string) $data["cancelledBy"]) : "admin";

$allowedStatuses = ["pending", "confirmed", "cancelled", "fulfilled", "no_show"];
if ($id <= 0 || !in_array($status, $allowedStatuses, true)) {
    http_response_code(400);
    echo json_encode(["success" => false, "message" => "Invalid reservation id or status."]);
    exit;
}

[$softDeleteReady, $softDeleteError] = reservationEnsureSoftDeleteColumns($conn);
if (!$softDeleteReady) {
    http_response_code(500);
    echo json_encode(["success" => false, "message" => $softDeleteError]);
    exit;
}

// Lock cancelled reservations to avoid accidental status changes in admin UI.
$existingStmt = $conn->prepare("SELECT status, cancelled_by FROM reservations WHERE id = ? AND admin_deleted = 0 LIMIT 1");
if (!$existingStmt) {
    http_response_code(500);
    echo json_encode(["success" => false, "message" => "Failed to prepare lookup query."]);
    exit;
}

$existingStmt->bind_param("i", $id);
$existingStmt->execute();
$existingResult = $existingStmt->get_result();
$existingReservation = $existingResult ? $existingResult->fetch_assoc() : null;
$existingStmt->close();

if (!$existingReservation) {
    http_response_code(404);
    echo json_encode(["success" => false, "message" => "Reservation not found."]);
    exit;
}

$currentStatus = (string) ($existingReservation["status"] ?? "");
$currentCancelledByRaw = (string) ($existingReservation["cancelled_by"] ?? "");
$currentCancelledBy = strtolower(trim($currentCancelledByRaw));
if ($currentCancelledBy === "0") {
    // Legacy rows from incorrect bind type in user cancellation endpoint.
    $currentCancelledBy = "guest";
}

if ($currentStatus === "cancelled" && $status !== "cancelled") {
    http_response_code(409);
    echo json_encode([
        "success" => false,
        "message" => "Cancelled reservations are locked and cannot be changed."
    ]);
    exit;
}

if ($currentStatus === "cancelled" && $status === "cancelled") {
    echo json_encode(["success" => true, "message" => "Reservation is already cancelled."]);
    $conn->close();
    exit;
}

if ($status === "cancelled" && !in_array($cancelledBy, ["guest", "admin"], true)) {
    $cancelledBy = "admin";
}

if ($status === "cancelled") {
    $stmt = $conn->prepare("UPDATE reservations SET status = ?, cancelled_by = ? WHERE id = ? AND admin_deleted = 0");
    if (!$stmt) {
        http_response_code(500);
        echo json_encode(["success" => false, "message" => "Failed to prepare update query."]);
        exit;
    }
    $stmt->bind_param("ssi", $status, $cancelledBy, $id);
    $stmt->execute();
} else {
    $stmt = $conn->prepare("UPDATE reservations SET status = ?, cancelled_by = NULL WHERE id = ? AND admin_deleted = 0");
    if (!$stmt) {
        http_response_code(500);
        echo json_encode(["success" => false, "message" => "Failed to prepare update query."]);
        exit;
    }
    $stmt->bind_param("si", $status, $id);
    $stmt->execute();
}

if ($stmt->affected_rows < 0) {
    http_response_code(500);
    echo json_encode(["success" => false, "message" => "Unable to update reservation status."]);
    $stmt->close();
    exit;
}

$stmt->close();
echo json_encode(["success" => true, "message" => "Reservation status updated."]);
$conn->close();
