<?php
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, 'Method not allowed', [], 405);
}

$input = json_decode(file_get_contents('php://input'), true);
if (!$input) {
    jsonResponse(false, 'Invalid JSON data');
}

$restaurantId = (int) ($input['restaurant_id'] ?? 0);
$tableId = (int) ($input['table_id'] ?? 0);
$orderType = trim($input['order_type'] ?? 'dine_in');
$customerName = trim($input['customer_name'] ?? '');
$customerPhone = trim($input['customer_phone'] ?? '');
$customerAddress = trim($input['customer_address'] ?? '');
$customerCity = trim($input['customer_city'] ?? '');
$orderNotes = trim($input['order_notes'] ?? '');
$promoCode = trim($input['promo_code'] ?? '');
$items = $input['items'] ?? [];
$csrfToken = trim($input['csrf_token'] ?? $_SERVER['HTTP_X_CSRF_TOKEN'] ?? '');

if ($restaurantId <= 0) {
    jsonResponse(false, 'Invalid restaurant');
}

if (empty($customerName)) {
    jsonResponse(false, 'Please enter your name');
}
if (empty($customerPhone)) {
    jsonResponse(false, 'Please enter your phone number');
}
if (empty($items) || !is_array($items)) {
    jsonResponse(false, 'Cart is empty');
}
if ($orderType === 'delivery' && empty($customerAddress)) {
    jsonResponse(false, 'Please enter your delivery address');
}

$db = Database::getInstance();

$csrf = new CSRF();
if (!$csrf->verify($csrfToken)) {
    $csrfTokenInput = $_SERVER['HTTP_X_CSRF_TOKEN'] ?? '';
    if (!$csrf->verify($csrfTokenInput)) {
        jsonResponse(false, 'Invalid security token. Please refresh the page.');
    }
}

$restaurant = $db->query(
    "SELECT * FROM restaurants WHERE id = ? AND status = 'active'",
    [$restaurantId]
)->fetch();

if (!$restaurant) {
    jsonResponse(false, 'Restaurant is not available');
}

$settings = $db->query(
    "SELECT * FROM restaurant_settings WHERE restaurant_id = ?",
    [$restaurantId]
)->fetch();

$operatingMode = (int) ($settings['operating_mode'] ?? $restaurant['operating_mode'] ?? 1);
if ($operatingMode !== 2) {
    jsonResponse(false, 'Online ordering is not enabled for this restaurant');
}

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

if ($orderType === 'dine_in' && empty($settings['dine_in_enabled'])) {
    jsonResponse(false, 'Dine-in ordering is not available');
}
if ($orderType === 'takeaway' && empty($settings['takeaway_enabled'])) {
    jsonResponse(false, 'Takeaway ordering is not available');
}
if ($orderType === 'delivery' && empty($settings['delivery_enabled'])) {
    jsonResponse(false, 'Delivery ordering is not available');
}

$sessionId = $_SESSION['menu_session_id'] ?? '';
if (!empty($sessionId)) {
    $recentOrder = $db->query(
        "SELECT id FROM orders WHERE restaurant_id = ? AND customer_phone = ? AND created_at > DATE_SUB(NOW(), INTERVAL 30 SECOND) LIMIT 1",
        [$restaurantId, $customerPhone]
    )->fetch();
    if ($recentOrder) {
        jsonResponse(false, 'Please wait a moment before placing another order');
    }
}

$orderService = new OrderService();
$validatedItems = [];
$itemErrors = [];

$variationIds = array_filter(array_map(function($ci) { return (int)($ci['variation_id'] ?? 0); }, $items));
$menuItemIds = array_unique(array_map(function($ci) { return (int)($ci['menu_item_id'] ?? $ci['id'] ?? 0); }, $items));
$menuItemIds = array_filter($menuItemIds);
$variationsMap = [];
if (!empty($menuItemIds)) {
    $placeholders = implode(',', array_fill(0, count($menuItemIds), '?'));
    $allVariations = $db->query(
        "SELECT menu_item_id, COUNT(*) as cnt FROM item_variations WHERE menu_item_id IN ({$placeholders}) AND restaurant_id = ? AND status = 1 GROUP BY menu_item_id",
        array_merge(array_values($menuItemIds), [$restaurantId])
    )->fetchAll();
    foreach ($allVariations as $v) {
        $variationsMap[(int) $v['menu_item_id']] = (int) $v['cnt'];
    }
}

foreach ($items as $idx => $cartItem) {
    $menuItemId = (int) ($cartItem['menu_item_id'] ?? $cartItem['id'] ?? 0);
    $variationId = (int) ($cartItem['variation_id'] ?? 0);
    $addonIds = $cartItem['addon_ids'] ?? ($cartItem['addons'] ?? []);
    $quantity = (int) ($cartItem['quantity'] ?? 1);
    $itemNotes = trim($cartItem['item_notes'] ?? $cartItem['notes'] ?? '');

    if ($menuItemId <= 0) {
        $itemErrors[] = 'Invalid item at position ' . ($idx + 1);
        continue;
    }
    if ($quantity <= 0) {
        $itemErrors[] = 'Invalid quantity for item #' . $menuItemId;
        continue;
    }

    $menuItem = $db->query(
        "SELECT * FROM menu_items WHERE id = ? AND restaurant_id = ? AND is_available = 1",
        [$menuItemId, $restaurantId]
    )->fetch();

    if (!$menuItem) {
        $itemErrors[] = 'Item #' . $menuItemId . ' is no longer available';
        continue;
    }

    if ($menuItem['stock_status'] === 'limited' && (int) $menuItem['stock_quantity'] < $quantity) {
        $itemErrors[] = $menuItem['name'] . ' has insufficient stock';
        continue;
    }

    $unitPrice = (float) $menuItem['regular_price'];
    $variationPrice = 0;
    $variationName = null;

    if ($variationId > 0) {
        $variation = $db->query(
            "SELECT * FROM item_variations WHERE id = ? AND menu_item_id = ? AND restaurant_id = ? AND status = 1",
            [$variationId, $menuItemId, $restaurantId]
        )->fetch();
        if (!$variation) {
            $itemErrors[] = 'Invalid variation for ' . $menuItem['name'];
            continue;
        }
        $variationPrice = (float) $variation['price'];
        $variationName = $variation['name'];
    } elseif (!empty($variationsMap[$menuItemId] ?? null)) {
        $firstVar = $db->query(
            "SELECT * FROM item_variations WHERE menu_item_id = ? AND restaurant_id = ? AND status = 1 ORDER BY sort_order ASC LIMIT 1",
            [$menuItemId, $restaurantId]
        )->fetch();
        if ($firstVar) {
            $variationId = (int) $firstVar['id'];
            $variationPrice = (float) $firstVar['price'];
            $variationName = $firstVar['name'];
        }
    }

    $addonsTotal = 0;
    $validatedAddons = [];
    if (!empty($addonIds) && is_array($addonIds)) {
        foreach ($addonIds as $addonId) {
            $addonId = (int) $addonId;
            if ($addonId <= 0) continue;
            $addon = $db->query(
                "SELECT * FROM addons WHERE id = ? AND addon_group_id IN (
                    SELECT addon_group_id FROM item_addon_groups WHERE menu_item_id = ?
                ) AND restaurant_id = ? AND status = 1",
                [$addonId, $menuItemId, $restaurantId]
            )->fetch();
            if ($addon) {
                $addonsTotal += (float) $addon['price'];
                $validatedAddons[] = [
                    'id'    => $addon['id'],
                    'name'  => $addon['name'],
                    'price' => (float) $addon['price'],
                ];
            }
        }
    }

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

    $validatedItems[] = [
        'menu_item_id'   => $menuItemId,
        'item_name'      => $menuItem['name'],
        'variation_id'   => $variationId ?: null,
        'variation_name' => $variationName,
        'quantity'       => $quantity,
        'unit_price'     => $unitPrice,
        'variation_price' => $variationPrice,
        'addons_total'   => $addonsTotal,
        'item_total'     => $itemTotal,
        'item_notes'     => $itemNotes,
        'addons'         => $validatedAddons,
        'price'          => $unitPrice + $variationPrice,
    ];
}

if (!empty($itemErrors)) {
    jsonResponse(false, implode('; ', $itemErrors));
}

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

$recalcData = [
    'items'     => $validatedItems,
    'order_type' => $orderType,
];
$recalculated = $orderService->recalculateOrder($recalcData, $settings);

$subtotal = $recalculated['subtotal'];
$taxPercent = (float) ($settings['tax_percent'] ?? 0);
$serviceChargePercent = (float) ($settings['service_charge_percent'] ?? 0);
$deliveryCharge = $recalculated['delivery_charge'];
$discount = 0;

$offerData = null;
if (!empty($promoCode)) {
    $offer = $db->query(
        "SELECT * FROM offers WHERE restaurant_id = ? AND coupon_code = ? AND is_active = 1
         AND (start_date IS NULL OR start_date <= CURDATE())
         AND (end_date IS NULL OR end_date >= CURDATE())",
        [$restaurantId, $promoCode]
    )->fetch();

    if ($offer) {
        $minOrder = (float) ($offer['min_order'] ?? 0);
        if ($subtotal >= $minOrder) {
            $discountType = $offer['discount_value'] ?? 0;
            if ($offer['offer_type'] === 'percentage') {
                $discount = round($subtotal * ((float) $discountType / 100), 2);
            } else {
                $discount = min((float) $discountType, $subtotal);
            }
            $discount = round($discount, 2);
            $offerData = $offer;
        }
    }
}

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

$minOrder = (float) ($settings['min_order'] ?? 0);
if ($minOrder > 0 && $subtotal < $minOrder) {
    jsonResponse(false, 'Minimum order amount is ' . formatCurrency($minOrder));
}

$db->beginTransaction();

try {
    $customer = null;
    if (!empty($customerPhone)) {
        $customer = $db->query(
            "SELECT * FROM customers WHERE restaurant_id = ? AND phone = ? LIMIT 1",
            [$restaurantId, $customerPhone]
        )->fetch();
    }

    if ($customer) {
        $db->update('customers', [
            'name'          => $customerName,
            'address'       => $customerAddress ?: $customer['address'],
            'city'          => $customerCity ?: $customer['city'],
            'total_orders'  => $customer['total_orders'] + 1,
            'total_spent'   => $customer['total_spent'] + $grandTotal,
            'last_order_at' => date('Y-m-d H:i:s'),
        ], 'id = ?', [$customer['id']]);
        $customerId = $customer['id'];
    } else {
        $customerId = $db->insert('customers', [
            'restaurant_id' => $restaurantId,
            'name'          => $customerName,
            'phone'         => $customerPhone,
            'email'         => '',
            'address'       => $customerAddress,
            'city'          => $customerCity,
            'total_orders'  => 1,
            'total_spent'   => $grandTotal,
            'last_order_at' => date('Y-m-d H:i:s'),
        ]);
    }

    $prefix = $settings['order_prefix'] ?? 'ORD';
    $orderNumber = $orderService->generateOrderNumber($restaurantId, $prefix);

    $orderId = $db->insert('orders', [
        'restaurant_id'     => $restaurantId,
        'customer_id'       => $customerId,
        'table_id'          => $tableId ?: null,
        'order_number'      => $orderNumber,
        'order_type'        => $orderType,
        'customer_name'     => $customerName,
        'customer_phone'    => $customerPhone,
        'customer_address'  => $customerAddress,
        'customer_city'     => $customerCity,
        'order_notes'       => $orderNotes,
        'subtotal'          => $subtotal,
        'discount'          => $discount,
        'tax'               => $tax,
        'service_charge'    => $serviceCharge,
        'delivery_charge'   => $deliveryCharge,
        'grand_total'       => $grandTotal,
        'payment_method'    => 'cash',
        'payment_status'    => 'pending',
        'order_status'      => 'new',
        'created_at'        => date('Y-m-d H:i:s'),
    ]);

    foreach ($validatedItems as $vItem) {
        $orderItemId = $db->insert('order_items', [
            'order_id'        => $orderId,
            'menu_item_id'    => $vItem['menu_item_id'],
            'item_name'       => $vItem['item_name'],
            'variation_name'  => $vItem['variation_name'],
            'quantity'        => $vItem['quantity'],
            'unit_price'      => $vItem['unit_price'],
            'variation_price' => $vItem['variation_price'],
            'addons_total'    => $vItem['addons_total'],
            'item_total'      => $vItem['item_total'],
            'item_notes'      => $vItem['item_notes'],
        ]);

        if (!empty($vItem['addons'])) {
            foreach ($vItem['addons'] as $addon) {
                $db->insert('order_item_addons', [
                    'order_item_id' => $orderItemId,
                    'addon_name'    => $addon['name'],
                    'addon_price'   => $addon['price'],
                ]);
            }
        }

        $db->query(
            "UPDATE menu_items SET order_count = order_count + ? WHERE id = ?",
            [$vItem['quantity'], $vItem['menu_item_id']]
        );
    }

    if (!empty($settings['sound_notification'])) {
        $notification = new Notification();
        $adminUsers = $db->query(
            "SELECT id FROM users WHERE restaurant_id = ? AND role_id IN (2,3,4,5)",
            [$restaurantId]
        )->fetchAll();
        foreach ($adminUsers as $u) {
            $notification->create(
                $u['id'],
                $restaurantId,
                'New Order',
                'Order #' . $orderNumber . ' from ' . $customerName,
                'order',
                '/restaurant-admin/orders.php'
            );
        }
    }

    $db->commit();

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

} catch (Exception $e) {
    $db->rollback();
    error_log('Order placement error: ' . $e->getMessage());
    jsonResponse(false, 'Failed to place order. Please try again.', [], 500);
}
