<?php
if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

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

$auth = new Auth();
$auth->requireRole(['restaurant_admin', 'restaurant_manager', 'cashier', 'kitchen_staff', 'waiter']);

$csrf = new CSRF();
$restaurantId = $auth->restaurantId();
$userId = $auth->userId();
$db = Database::getInstance();

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    jsonResponse(false, 'Invalid request');
}

if (empty($_POST['csrf_token']) || !$csrf->verify($_POST['csrf_token'])) {
    jsonResponse(false, 'Invalid CSRF token');
}

$orderId = (int)($_POST['order_id'] ?? 0);
$newStatus = $_POST['order_status'] ?? '';
$reason = trim($_POST['reason'] ?? '');

if ($orderId <= 0) jsonResponse(false, 'Invalid order ID');

$validStatuses = ['confirmed', 'preparing', 'ready', 'served', 'completed', 'cancelled', 'rejected'];
if (!in_array($newStatus, $validStatuses)) jsonResponse(false, 'Invalid status');

$order = $db->query("SELECT * FROM orders WHERE id = ? AND restaurant_id = ?", [$orderId, $restaurantId])->fetch();
if (!$order) jsonResponse(false, 'Order not found');

if (in_array($order['order_status'], ['completed', 'cancelled', 'rejected'])) {
    jsonResponse(false, 'Cannot change status of a ' . $order['order_status'] . ' order');
}

$validTransitions = [
    'new' => ['confirmed', 'rejected'],
    'confirmed' => ['preparing', 'cancelled', 'rejected'],
    'preparing' => ['ready', 'cancelled'],
    'ready' => ['served', 'cancelled'],
    'served' => ['completed', 'cancelled'],
];

if (!isset($validTransitions[$order['order_status']]) || !in_array($newStatus, $validTransitions[$order['order_status']])) {
    jsonResponse(false, 'Cannot change from "' . $order['order_status'] . '" to "' . $newStatus . '"');
}

if (in_array($newStatus, ['rejected', 'cancelled']) && empty($reason)) {
    jsonResponse(false, 'Reason is required for rejection/cancellation');
}

$db->beginTransaction();

try {
    $db->update('orders', [
        'order_status' => $newStatus,
        'cancellation_reason' => in_array($newStatus, ['cancelled', 'rejected']) ? $reason : null,
    ], 'id = ?', [$orderId]);

    $db->insert('order_status_history', [
        'order_id' => $orderId,
        'from_status' => $order['order_status'],
        'to_status' => $newStatus,
        'notes' => $reason ?: null,
        'changed_by' => $userId,
    ]);

    if ($newStatus === 'completed' && $order['table_id']) {
        $db->update('tables', ['status' => 'available'], 'id = ?', [$order['table_id']]);
    }

    $db->commit();

    $activityLog = new ActivityLog();
    $activityLog->log($userId, $restaurantId, 'orders', 'status_change', 'Order ' . $order['order_number'] . ' changed from "' . $order['order_status'] . '" to "' . $newStatus . '"' . ($reason ? ' Reason: ' . $reason : ''));

    jsonResponse(true, 'Order status updated to "' . ucfirst($newStatus) . '"');
} catch (Exception $e) {
    $db->rollBack();
    jsonResponse(false, 'Failed to update order status');
}
