<?php
// app/Controllers/WaiterController.php

class WaiterController {
    public function index() {
        if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'waiter') {
            header('Location: ' . BASE_URL . '/lsign');
            exit;
        }

        FeatureGate::enforceSubscription($_SESSION['restaurant_id']);

        require_once 'app/Views/waiter/pos.php';
    }

    public function getData() {
        header('Content-Type: application/json');
        if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'waiter') {
            echo json_encode(['error' => 'Unauthorized']);
            exit;
        }
        FeatureGate::enforceSubscription($_SESSION['restaurant_id']);

        $db = getDB();
        $rest_id = $_SESSION['restaurant_id'];

        $categories = $db->prepare('SELECT * FROM categories WHERE restaurant_id = ? AND status="active"');
        $categories->execute([$rest_id]);

        $products = $db->prepare('SELECT * FROM products WHERE restaurant_id = ? AND status="active"');
        $products->execute([$rest_id]);

        // Retrieve the waiter's assigned cashier_id
        $userStmt = $db->prepare('SELECT cashier_id FROM users WHERE id = ?');
        $userStmt->execute([$_SESSION['user_id']]);
        $cashier_id = $userStmt->fetchColumn();
        if ($cashier_id === false) {
            $cashier_id = null;
        }

        if ($cashier_id !== null) {
            $floors = $db->prepare('SELECT * FROM floors WHERE restaurant_id = ? AND cashier_id = ?');
            $floors->execute([$rest_id, $cashier_id]);

            $tables = $db->prepare('SELECT t.* FROM tables t JOIN floors f ON t.floor_id = f.id WHERE t.restaurant_id = ? AND f.cashier_id = ?');
            $tables->execute([$rest_id, $cashier_id]);
        } else {
            $floors = $db->prepare('SELECT * FROM floors WHERE restaurant_id = ?');
            $floors->execute([$rest_id]);

            $tables = $db->prepare('SELECT * FROM tables WHERE restaurant_id = ?');
            $tables->execute([$rest_id]);
        }

        // Waiters see all pending or active dining orders on their assigned floors/tables
        if ($cashier_id !== null) {
            $orders = $db->prepare('
                SELECT o.*, t.name as table_name, w.name as waiter_name 
                FROM orders o 
                JOIN tables t ON t.id = o.table_id 
                JOIN floors f ON f.id = t.floor_id
                LEFT JOIN users w ON w.id = o.waiter_id
                WHERE o.restaurant_id = ? 
                  AND f.cashier_id = ? 
                  AND o.payment_status = "unpaid" 
                  AND o.status != "voided"
                  AND NOT (o.status = "pending" AND o.waiter_id IS NULL)
            ');
            $orders->execute([$rest_id, $cashier_id]);
        } else {
            $orders = $db->prepare('
                SELECT o.*, t.name as table_name, w.name as waiter_name 
                FROM orders o 
                JOIN tables t ON t.id = o.table_id 
                LEFT JOIN users w ON w.id = o.waiter_id
                WHERE o.restaurant_id = ? 
                  AND o.payment_status = "unpaid" 
                  AND o.status != "voided"
                  AND NOT (o.status = "pending" AND o.waiter_id IS NULL)
            ');
            $orders->execute([$rest_id]);
        }
        $orders_res = $orders->fetchAll();

        foreach($orders_res as &$order) {
            $itemsStmt = $db->prepare('SELECT oi.*, p.name FROM order_items oi JOIN products p ON p.id = oi.product_id WHERE oi.order_id = ?');
            $itemsStmt->execute([$order['id']]);
            $order['items'] = $itemsStmt->fetchAll();
        }

        // Fetch settings for tax/discount
        $settingsStmt = $db->prepare('SELECT setting_key, setting_value FROM restaurant_settings WHERE restaurant_id = ?');
        $settingsStmt->execute([$rest_id]);
        $rows = $settingsStmt->fetchAll();
        $s = [];
        foreach ($rows as $r) { $s[$r['setting_key']] = $r['setting_value']; }
        $tax_rate = floatval($s['tax_rate'] ?? 5);
        $discount_rate = floatval($s['discount_rate'] ?? 0);

        // Fetch active coupons
        $couponsStmt = $db->prepare('SELECT * FROM restaurant_coupons WHERE restaurant_id = ? AND status = "active" AND expiry_date >= DATE(NOW())');
        $couponsStmt->execute([$rest_id]);
        $couponsList = $couponsStmt->fetchAll();

        echo json_encode([
            'categories' => $categories->fetchAll(),
            'products' => $products->fetchAll(),
            'floors' => $floors->fetchAll(),
            'tables' => $tables->fetchAll(),
            'my_orders' => $orders_res,
            'currency' => FeatureGate::currency($rest_id),
            'tax_rate' => $tax_rate,
            'discount_rate' => $discount_rate,
            'coupons' => $couponsList
        ]);
        exit;
    }

    public function placeOrder() {
        header('Content-Type: application/json');
        $data = json_decode(file_get_contents('php://input'), true);

        if (!$data || !isset($_SESSION['user_id'])) {
            echo json_encode(['success' => false, 'message' => 'Invalid request']);
            exit;
        }
        FeatureGate::enforceSubscription($_SESSION['restaurant_id']);

        $db = getDB();
        $db->beginTransaction();

        try {
            $subtotal = 0;
            foreach ($data['items'] as $item) {
                $subtotal += ($item['price'] * $item['quantity']);
            }

            $rest_id = $_SESSION['restaurant_id'];

            // Get settings for tax/discount
            $settingsStmt = $db->prepare('SELECT setting_key, setting_value FROM restaurant_settings WHERE restaurant_id = ?');
            $settingsStmt->execute([$rest_id]);
            $rows = $settingsStmt->fetchAll();
            $s = [];
            foreach ($rows as $r) { $s[$r['setting_key']] = $r['setting_value']; }
            $tax_rate = floatval($s['tax_rate'] ?? 5);
            $discount_rate = floatval($s['discount_rate'] ?? 0);

            $coupon_discount = 0;
            $coupon_code = !empty($data['coupon_code']) ? strtoupper(trim($data['coupon_code'])) : null;
            if ($coupon_code) {
                // Find table to get floor_id
                $tblStmt = $db->prepare('SELECT floor_id FROM tables WHERE id = ? LIMIT 1');
                $tblStmt->execute([$data['table_id']]);
                $floor_id = $tblStmt->fetchColumn();

                $cpn = $db->prepare('SELECT * FROM restaurant_coupons WHERE restaurant_id = ? AND (floor_id IS NULL OR floor_id = ?) AND code = ? AND status="active" AND expiry_date >= DATE(NOW()) LIMIT 1');
                $cpn->execute([$rest_id, $floor_id, $coupon_code]);
                $coupon = $cpn->fetch();
                if ($coupon) {
                    $coupon_discount = CouponHelper::calculateDiscount($coupon, $data['items'], $subtotal);
                }
            }

            $base_discount = $subtotal * ($discount_rate / 100);
            $discount_amount = $base_discount + $coupon_discount;
            $taxable = max(0, $subtotal - $discount_amount);
            $tax = $taxable * ($tax_rate / 100);
            $total = $taxable + $tax;

            // Fetch waiter's cashier_id
            $userStmt = $db->prepare('SELECT cashier_id FROM users WHERE id = ?');
            $userStmt->execute([$_SESSION['user_id']]);
            $cashier_id = $userStmt->fetchColumn();
            if ($cashier_id === false) {
                $cashier_id = null;
            }

            $session_id = null;
            if ($cashier_id) {
                $sessStmt = $db->prepare('SELECT id FROM sessions WHERE user_id = ? AND status = "open" ORDER BY id DESC LIMIT 1');
                $sessStmt->execute([$cashier_id]);
                $session_id = $sessStmt->fetchColumn() ?: null;
            } else {
                $activeStmt = $db->prepare('SELECT id, user_id FROM sessions WHERE restaurant_id = ? AND status = "open" ORDER BY id DESC LIMIT 1');
                $activeStmt->execute([$rest_id]);
                $activeSession = $activeStmt->fetch(\PDO::FETCH_ASSOC);
                if ($activeSession) {
                    $session_id = $activeSession['id'];
                    $cashier_id = $activeSession['user_id'];
                }
            }

            // Calculate next sequential order number for this restaurant
            $order_number = FeatureGate::getNextOrderNumber($rest_id, $session_id, $cashier_id);

            // Waiter creates order as "pending"
            $stmt = $db->prepare('INSERT INTO orders (restaurant_id, order_number, session_id, table_id, waiter_id, cashier_id, order_type, status, subtotal, discount, tax, total, notes, coupon_code, coupon_discount) VALUES (?, ?, ?, ?, ?, ?, "dining", "pending", ?, ?, ?, ?, ?, ?, ?)');
            $stmt->execute([
                $rest_id,
                $order_number,
                $session_id,
                $data['table_id'],
                $_SESSION['user_id'],
                $cashier_id,
                $subtotal,
                $discount_amount,
                $tax,
                $total,
                $data['notes'] ?? '',
                $coupon_code,
                $coupon_discount
            ]);

            $order_id = $db->lastInsertId();

            $itemStmt = $db->prepare('INSERT INTO order_items (order_id, product_id, quantity, price, subtotal) VALUES (?, ?, ?, ?, ?)');
            foreach ($data['items'] as $item) {
                $item_sub = $item['price'] * $item['quantity'];
                $itemStmt->execute([$order_id, $item['id'], $item['quantity'], $item['price'], $item_sub]);
            }

            // Mark table as occupied
            $tblStmt = $db->prepare('UPDATE tables SET status = "occupied" WHERE id = ?');
            $tblStmt->execute([$data['table_id']]);

            $db->commit();
            echo json_encode(['success' => true, 'message' => 'Order sent to Cashier!']);
        } catch (\Exception $e) {
            $db->rollBack();
            echo json_encode(['success' => false, 'message' => $e->getMessage()]);
        }
        exit;
    }
}
