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

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

header('Content-Type: application/json; charset=utf-8');

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

$input = json_decode(file_get_contents('php://input'), true);
if (!$input) {
    $input = $_POST;
}

$action = $input['action'] ?? '';
$csrfToken = $input['csrf_token'] ?? '';

$csrf = new CSRF();
if (!$csrf->verify($csrfToken)) {
    jsonResponse(false, 'Invalid security token');
}

$auth = new Auth();
if (!$auth->check()) {
    jsonResponse(false, 'Unauthorized', [], 401);
}

$restaurantId = $auth->restaurantId();
if (!$restaurantId) {
    jsonResponse(false, 'No restaurant associated', [], 403);
}

$db = Database::getInstance();
$pdo = $db->getConnection();

switch ($action) {
    case 'create_order':
        handleCreateOrder($pdo, $input, $restaurantId, $auth);
        break;
    case 'mark_served':
        handleMarkServed($pdo, $input, $restaurantId, $auth);
        break;
    case 'request_bill':
        handleRequestBill($pdo, $input, $restaurantId, $auth);
        break;
    default:
        jsonResponse(false, 'Invalid action');
}

function handleCreateOrder($pdo, $input, $restaurantId, $auth)
{
    $tableId = (int) ($input['table_id'] ?? 0);
    $orderType = $input['order_type'] ?? 'dine_in';
    $customerName = trim($input['customer_name'] ?? '');
    $customerPhone = trim($input['customer_phone'] ?? '');
    $orderNotes = trim($input['order_notes'] ?? '');
    $items = $input['items'] ?? [];

    if (empty($items)) {
        jsonResponse(false, 'No items in order');
    }

    if (!in_array($orderType, ['dine_in', 'takeaway', 'delivery'])) {
        jsonResponse(false, 'Invalid order type');
    }

    if ($orderType === 'dine_in' && $tableId > 0) {
        $tableStmt = $pdo->prepare("SELECT id, status FROM tables WHERE id = ? AND restaurant_id = ?");
        $tableStmt->execute([$tableId, $restaurantId]);
        $table = $tableStmt->fetch();
        if (!$table) {
            jsonResponse(false, 'Table not found');
        }
    }

    $settingsStmt = $pdo->prepare("SELECT * FROM restaurant_settings WHERE restaurant_id = ? LIMIT 1");
    $settingsStmt->execute([$restaurantId]);
    $settings = $settingsStmt->fetch();
    $settings = $settings ?: [];

    $taxPercent = (float) ($settings['tax_percent'] ?? 0);
    $serviceChargePercent = (float) ($settings['service_charge_percent'] ?? 0);
    $deliveryCharge = 0;
    if ($orderType === 'delivery') {
        $deliveryCharge = (float) ($settings['delivery_charge'] ?? 0);
    }
    $orderPrefix = $settings['order_prefix'] ?? 'ORD';

    $stmt = $pdo->prepare(
        "SELECT order_number FROM orders WHERE restaurant_id = ? AND order_number LIKE ? ORDER BY id DESC LIMIT 1"
    );
    $datePrefix = $orderPrefix . date('ymd');
    $stmt->execute([$restaurantId, $datePrefix . '%']);
    $lastOrder = $stmt->fetch();
    if ($lastOrder) {
        $lastNumber = (int) substr($lastOrder['order_number'], -4);
        $orderNumber = $datePrefix . str_pad($lastNumber + 1, 4, '0', STR_PAD_LEFT);
    } else {
        $orderNumber = $datePrefix . '0001';
    }

    $subtotal = 0;
    $validatedItems = [];
    foreach ($items as $item) {
        $menuItemId = (int) ($item['menu_item_id'] ?? 0);
        $itemName = trim($item['item_name'] ?? '');
        $variationName = trim($item['variation_name'] ?? null);
        $quantity = (int) ($item['quantity'] ?? 1);
        $unitPrice = (float) ($item['unit_price'] ?? 0);
        $variationPrice = (float) ($item['variation_price'] ?? 0);
        $itemNotes = trim($item['item_notes'] ?? '');
        $itemAddons = $item['addons'] ?? [];

        if ($quantity <= 0 || ($menuItemId <= 0 && empty($itemName))) {
            continue;
        }

        $addonsTotal = 0;
        foreach ($itemAddons as $addon) {
            $addonsTotal += (float) ($addon['addon_price'] ?? 0) * $quantity;
        }

        $itemTotal = ($unitPrice + $variationPrice) * $quantity + $addonsTotal;
        $subtotal += $itemTotal;

        $validatedItems[] = [
            'menu_item_id'    => $menuItemId,
            'item_name'       => $itemName,
            'variation_name'  => $variationName,
            'quantity'        => $quantity,
            'unit_price'      => $unitPrice,
            'variation_price' => $variationPrice,
            'addons_total'    => $addonsTotal,
            'item_total'      => $itemTotal,
            'item_notes'      => $itemNotes,
            'addons'          => $itemAddons,
        ];
    }

    if (empty($validatedItems)) {
        jsonResponse(false, 'No valid items');
    }

    $tax = round($subtotal * ($taxPercent / 100), 2);
    $serviceCharge = round($subtotal * ($serviceChargePercent / 100), 2);
    $grandTotal = round($subtotal + $tax + $serviceCharge + $deliveryCharge, 2);

    $pdo->beginTransaction();

    try {
        $orderStmt = $pdo->prepare(
            "INSERT INTO orders (restaurant_id, customer_id, table_id, order_number, order_type,
                customer_name, customer_phone, order_notes, subtotal, discount, tax,
                service_charge, delivery_charge, grand_total, payment_method, payment_status,
                order_status, is_demo, created_at, updated_at)
             VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 0, ?, ?, ?, ?, 'pending', 'pending', 'new', 0, NOW(), NOW())"
        );
        $orderStmt->execute([
            $restaurantId,
            null,
            $tableId > 0 ? $tableId : null,
            $orderNumber,
            $orderType,
            $customerName ?: null,
            $customerPhone ?: null,
            $orderNotes ?: null,
            $subtotal,
            $tax,
            $serviceCharge,
            $deliveryCharge,
            $grandTotal,
        ]);
        $orderId = $pdo->lastInsertId();

        foreach ($validatedItems as $vItem) {
            $itemStmt = $pdo->prepare(
                "INSERT INTO order_items (order_id, menu_item_id, item_name, variation_name,
                    quantity, unit_price, variation_price, addons_total, item_total, item_notes, created_at)
                 VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())"
            );
            $itemStmt->execute([
                $orderId,
                $vItem['menu_item_id'] ?: null,
                $vItem['item_name'],
                $vItem['variation_name'],
                $vItem['quantity'],
                $vItem['unit_price'],
                $vItem['variation_price'],
                $vItem['addons_total'],
                $vItem['item_total'],
                $vItem['item_notes'] ?: null,
            ]);
            $orderItemId = $pdo->lastInsertId();

            foreach ($vItem['addons'] as $addon) {
                $addonStmt = $pdo->prepare(
                    "INSERT INTO order_item_addons (order_item_id, addon_name, addon_price)
                     VALUES (?, ?, ?)"
                );
                $addonStmt->execute([
                    $orderItemId,
                    $addon['addon_name'] ?? '',
                    $addon['addon_price'] ?? 0,
                ]);
            }
        }

        $historyStmt = $pdo->prepare(
            "INSERT INTO order_status_history (order_id, from_status, to_status, notes, changed_by, created_at)
             VALUES (?, NULL, 'new', 'Order created by waiter', ?, NOW())"
        );
        $historyStmt->execute([$orderId, $auth->userId()]);

        if ($tableId > 0) {
            $tableUpdate = $pdo->prepare(
                "UPDATE tables SET status = 'ordered', updated_at = NOW() WHERE id = ? AND restaurant_id = ?"
            );
            $tableUpdate->execute([$tableId, $restaurantId]);
        }

        $pdo->commit();

        jsonResponse(true, 'Order created successfully', [
            'order_id'    => $orderId,
            'order_number'=> $orderNumber,
            'grand_total' => $grandTotal,
        ]);

    } catch (Exception $e) {
        $pdo->rollBack();
        error_log('Waiter create order error: ' . $e->getMessage());
        jsonResponse(false, 'Failed to create order', [], 500);
    }
}

function handleMarkServed($pdo, $input, $restaurantId, $auth)
{
    $orderId = (int) ($input['order_id'] ?? 0);
    if (!$orderId) {
        jsonResponse(false, 'Invalid order ID');
    }

    $stmt = $pdo->prepare(
        "SELECT id, order_status, table_id FROM orders WHERE id = ? AND restaurant_id = ? LIMIT 1"
    );
    $stmt->execute([$orderId, $restaurantId]);
    $order = $stmt->fetch();

    if (!$order) {
        jsonResponse(false, 'Order not found');
    }

    if (!in_array($order['order_status'], ['ready'])) {
        jsonResponse(false, 'Order is not ready to be served');
    }

    $pdo->beginTransaction();

    try {
        $updateStmt = $pdo->prepare(
            "UPDATE orders SET order_status = 'served', updated_at = NOW() WHERE id = ?"
        );
        $updateStmt->execute([$orderId]);

        $historyStmt = $pdo->prepare(
            "INSERT INTO order_status_history (order_id, from_status, to_status, notes, changed_by, created_at)
             VALUES (?, 'ready', 'served', 'Marked served by waiter', ?, NOW())"
        );
        $historyStmt->execute([$orderId, $auth->userId()]);

        if ($order['table_id']) {
            $tableUpdate = $pdo->prepare(
                "UPDATE tables SET status = 'occupied', updated_at = NOW() WHERE id = ? AND restaurant_id = ?"
            );
            $tableUpdate->execute([$order['table_id'], $restaurantId]);
        }

        $pdo->commit();

        jsonResponse(true, 'Order marked as served');

    } catch (Exception $e) {
        $pdo->rollBack();
        error_log('Waiter mark served error: ' . $e->getMessage());
        jsonResponse(false, 'Failed to update order', [], 500);
    }
}

function handleRequestBill($pdo, $input, $restaurantId, $auth)
{
    $orderId = (int) ($input['order_id'] ?? 0);
    if (!$orderId) {
        jsonResponse(false, 'Invalid order ID');
    }

    $stmt = $pdo->prepare(
        "SELECT id, order_status, table_id FROM orders WHERE id = ? AND restaurant_id = ? LIMIT 1"
    );
    $stmt->execute([$orderId, $restaurantId]);
    $order = $stmt->fetch();

    if (!$order) {
        jsonResponse(false, 'Order not found');
    }

    $pdo->beginTransaction();

    try {
        if ($order['table_id']) {
            $tableUpdate = $pdo->prepare(
                "UPDATE tables SET status = 'bill_requested', updated_at = NOW() WHERE id = ? AND restaurant_id = ?"
            );
            $tableUpdate->execute([$order['table_id'], $restaurantId]);
        }

        $historyStmt = $pdo->prepare(
            "INSERT INTO order_status_history (order_id, from_status, to_status, notes, changed_by, created_at)
             VALUES (?, ?, 'bill_requested', 'Bill requested by waiter', ?, NOW())"
        );
        $historyStmt->execute([$orderId, $order['order_status'], $auth->userId()]);

        $pdo->commit();

        jsonResponse(true, 'Bill requested');

    } catch (Exception $e) {
        $pdo->rollBack();
        error_log('Waiter request bill error: ' . $e->getMessage());
        jsonResponse(false, 'Failed to request bill', [], 500);
    }
}
