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

class User
{
    private $DB_SERVER = 'localhost';
    private $DB_USERNAME = 's2300379_g5pharmaease';
    private $DB_PASSWORD = '12345';
    private $DB_DATABASE = 's2300379_g5pharmaease';
    private $conn;
    public function __construct()
    {
        $this->conn = new mysqli($this->DB_SERVER, $this->DB_USERNAME, $this->DB_PASSWORD, $this->DB_DATABASE);
        if ($this->conn->connect_error) {
            die("Connection failed: " . $this->conn->connect_error);
        }
    }
    public function getConnection()
    {
        return $this->conn;
    }
    public function getAllUsers()
    {
        $sql = "SELECT * FROM user";
        $result = $this->conn->query($sql);
        return $result;
    }

    public function getUsersPerGender($gender)
    {
        $sql = "SELECT count(user_id) FROM user WHERE gender = ?";
        $stmt = $this->conn->prepare($sql);
        $stmt->bind_param("s", $gender);
        $stmt->execute();
        $result = $stmt->get_result();
        return $result->fetch_row()[0];
    }

    public function getUsersPerStatus($status)
    {
        $sql = "SELECT count(user_id) FROM user WHERE status = ?";
        $stmt = $this->conn->prepare($sql);
        $stmt->bind_param("s", $status);
        $stmt->execute();
        $result = $stmt->get_result();
        return $result->fetch_row()[0];
    }

    public function authenticateUser($email, $password, $role)
    {
        $table = ($role === 'Admin') ? 'admin' : 'user';
        $id_column = ($role === 'Admin') ? 'admin_id' : 'user_id';
        $query = "SELECT $id_column, password FROM $table WHERE email = ?";
        $stmt = $this->conn->prepare($query);
        $stmt->bind_param('s', $email);
        $stmt->execute();
        $stmt->store_result();
        $stmt->bind_result($id, $dbPassword);

        $result = ['success' => false];
        if ($stmt->num_rows > 0) {
            $stmt->fetch();
            if ($password === $dbPassword) {
                $result = ['success' => true, 'id' => $id, 'role' => $role];
            }
        }

        $stmt->close();
        return $result;
    }

    function getPDFUsers()
    {
        $conn = new mysqli($this->DB_SERVER, $this->DB_USERNAME, $this->DB_PASSWORD, $this->DB_DATABASE);

        $query = "SELECT user_id, full_name, email, gender, status FROM user";
        $result = $conn->query($query);

        $users = [];
        if ($result->num_rows > 0) {
            while ($row = $result->fetch_assoc()) {
                $users[] = $row;
            }
        }

        $conn->close();
        return $users;
    }
    public function closeConnection()
    {
        if ($this->conn) {
            $this->conn->close();
        }
    }
    public function getAllUsersWithLimit($limit, $offset, $searchTerm = '')
    {
        $query = "SELECT * FROM user";

        if (!empty($searchTerm)) {
            $searchTerm = $this->conn->real_escape_string($searchTerm);
            $query .= " WHERE full_name LIKE '%$searchTerm%' 
                       OR email LIKE '%$searchTerm%' 
                       OR user_id LIKE '$searchTerm'";
        }

        $query .= " LIMIT $limit OFFSET $offset";

        $result = $this->conn->query($query);
        return $result;
    }

    public function getTotalUserCount($searchTerm = '')
    {
        $query = "SELECT COUNT(*) as total FROM user";

        if (!empty($searchTerm)) {
            $searchTerm = $this->conn->real_escape_string($searchTerm);
            $query .= " WHERE full_name LIKE '%$searchTerm%' 
                       OR email LIKE '%$searchTerm%' 
                       OR user_id LIKE '$searchTerm'";
        }

        $result = $this->conn->query($query);
        return $result->fetch_assoc()['total'];
    }
    public function new_user($fullName, $email, $password, $status, $gender, $phone, $address, $city)
    {
        $stmt = $this->conn->prepare("INSERT INTO user (full_name, email, password, status, gender, phone, address, city) VALUES (?,?,?,?,?,?,?,?)");
        $stmt->bind_param("ssssssss", $fullName, $email, $password, $status, $gender, $phone, $address, $city);
        
        try {
            $stmt->execute();
        } catch (Exception $e) {
            throw $e;
        }
        return true;
    }

    // Get all queue entries
    public function getAllQueues() {
        $sql = "SELECT o.order_id, o.queue_number, u.full_name, u.email 
                FROM orders o
                JOIN user u ON o.user_id = u.user_id 
                WHERE o.queue_number IS NOT NULL 
                ORDER BY o.queue_number ASC";
        return $this->conn->query($sql);
    }

    // Get current queue number
    public function getCurrentQueue() {
        $sql = "SELECT MIN(queue_number) as current_queue FROM orders WHERE queue_number IS NOT NULL";
        $result = $this->conn->query($sql);
        if ($result && $result->num_rows > 0) {
            $row = $result->fetch_assoc();
            return intval($row['current_queue'] ?? 0);
        }
        return 0;
    }

    // Delete the current queue (lowest number)
    public function deleteCurrentQueue() {
        $currentQueue = $this->getCurrentQueue();
        if ($currentQueue <= 0) {
            return false;
        }
        $sql_find_order = "SELECT order_id FROM orders WHERE queue_number = ? ORDER BY order_id ASC LIMIT 1";
        $stmt_find = $this->conn->prepare($sql_find_order);
        if (!$stmt_find) return false;
        $stmt_find->bind_param("i", $currentQueue);
        $stmt_find->execute();
        $result_find = $stmt_find->get_result();
        if ($result_find->num_rows === 0) {
            $stmt_find->close();
            return false;
        }
        $order_to_update = $result_find->fetch_assoc()['order_id'];
        $stmt_find->close();

        $sql_update = "UPDATE orders SET queue_number = NULL WHERE order_id = ? AND queue_number = ?";
        $stmt_update = $this->conn->prepare($sql_update);
        if (!$stmt_update) return false;
        $stmt_update->bind_param("ii", $order_to_update, $currentQueue);
        return $stmt_update->execute();
    }

    // Get queue debug info
    public function getQueueDebugInfo() {
        $currentQueue = $this->getCurrentQueue();
        $queueCount = 0;
        $sql = "SELECT COUNT(*) as count FROM orders WHERE queue_number IS NOT NULL";
        $result = $this->conn->query($sql);
        if ($result && $result->num_rows > 0) {
            $row = $result->fetch_assoc();
            $queueCount = $row['count'];
        }
        $sql = "SHOW TABLES LIKE 'orders'";
        $tableExists = ($this->conn->query($sql)->num_rows > 0);
        $tableStructure = [];
        if ($tableExists) {
            $sql = "DESCRIBE orders";
            $result = $this->conn->query($sql);
            while ($row = $result->fetch_assoc()) {
                $tableStructure[] = $row;
            }
        }
        return [
            'current_queue' => $currentQueue,
            'queue_count' => $queueCount,
            'table_exists' => $tableExists,
            'table_structure' => $tableStructure,
            'connection_error' => $this->conn->error,
            'php_version' => phpversion()
        ];
    }

    public function getUserDetailsByEmail($email) {
        $sql = "SELECT user_id, full_name, email FROM user WHERE email = ? LIMIT 1";
        $stmt = $this->conn->prepare($sql);
        if (!$stmt) {
            // Handle prepare error, log it, or return an error indicator
            error_log("Prepare failed: (" . $this->conn->errno . ") " . $this->conn->error);
            return null;
        }
        $stmt->bind_param("s", $email);
        $stmt->execute();
        $result = $stmt->get_result();
        if ($result && $result->num_rows > 0) {
            return $result->fetch_assoc();
        }
        $stmt->close();
        return null; // User not found or error
    }

    public function getNameByQueueNumber($queueNumber) {
        if ($queueNumber <= 0) return null;
        $sql = "SELECT u.full_name 
                FROM orders o
                JOIN user u ON o.user_id = u.user_id 
                WHERE o.queue_number = ? LIMIT 1";
        $stmt = $this->conn->prepare($sql);
        if (!$stmt) {
            error_log("Prepare failed for getNameByQueueNumber: (" . $this->conn->errno . ") " . $this->conn->error);
            return null;
        }
        $stmt->bind_param("i", $queueNumber);
        $stmt->execute();
        $result = $stmt->get_result();
        if ($result && $result->num_rows > 0) {
            $row = $result->fetch_assoc();
            $stmt->close();
            return $row['full_name'];
        }
        $stmt->close();
        return null;
    }

    /**
     * Checks if an email already exists in the user_records table.
     *
     * @param string $email The email to check.
     * @return bool True if the email exists, false otherwise.
     */
    public function isEmailRegistered(string $email): bool
    {
        $query = "SELECT user_id FROM user WHERE email = ?";
        $stmt = $this->conn->prepare($query);
        if (!$stmt) {
            error_log("Prepare failed for isEmailRegistered: (" . $this->conn->errno . ") " . $this->conn->error);
            return false; // Consider throwing an exception or handling error more robustly
        }
        $stmt->bind_param('s', $email);
        $stmt->execute();
        $stmt->store_result();
        $num_rows = $stmt->num_rows;
        $stmt->close();
        return $num_rows > 0;
    }

    /**
     * Registers a new user in the user_records table.
     *
     * @param string $name Full name of the user.
     * @param string $email Email of the user.
     * @param string $password Password for the user (plain text).
     * @param string $phone Phone number of the user.
     * @return bool True if registration is successful, false otherwise.
     */
    public function registerNewUser(string $fullName, string $email, string $password, string $phone): bool
    {
        // It's good practice to hash passwords before storing them.
        // $hashedPassword = password_hash($password, PASSWORD_DEFAULT);

        // The 'user' table has status, gender, address, city which are not NULLable or have defaults in the new schema.
        // This function needs to be updated to either accept these values or set defaults.
        // For now, setting defaults (e.g., status='active', gender='other', address='', city='')
        // Or, ensure your table schema allows NULLs or has defaults for these new columns if not provided.
        $status = 'active'; // Example default
        $gender = 'other'; // Example default
        $address = ''; // Example default
        $city = ''; // Example default

        $query = "INSERT INTO user (full_name, email, password, phone, status, gender, address, city) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
        $stmt = $this->conn->prepare($query);
        // Use the hashed password if you implement hashing: $hashedPassword
        $stmt->bind_param("ssssssss", $fullName, $email, $password, $phone, $status, $gender, $address, $city);

        if ($stmt->execute()) {
            return true;
        } else {
            // Log error $stmt->error
            return false;
        }
    }

    public function updateUserProfile($currentEmail, $newFullName, $newEmail, $newPhone, $newAddress, $newCity, $newGender) {
        // Fetch the user_id based on the currentEmail first
        $findUserSql = "SELECT user_id FROM user WHERE email = ?";
        $findStmt = $this->conn->prepare($findUserSql);
        $findStmt->bind_param("s", $currentEmail);
        $findStmt->execute();
        $result = $findStmt->get_result();
        if ($result->num_rows === 0) {
            $findStmt->close();
            return ['success' => false, 'message' => 'User not found.'];
        }
        $user = $result->fetch_assoc();
        $userId = $user['user_id'];
        $findStmt->close();

        // Now update the user's profile using user_id
        $sql = "UPDATE user SET full_name = ?, email = ?, phone = ?, address = ?, city = ?, gender = ? WHERE user_id = ?";
        $stmt = $this->conn->prepare($sql);

        if (!$stmt) {
            error_log("Prepare failed: (" . $this->conn->errno . ") " . $this->conn->error);
            return ['success' => false, 'message' => 'Database error preparing statement.'];
        }

        $stmt->bind_param("ssssssi", $newFullName, $newEmail, $newPhone, $newAddress, $newCity, $newGender, $userId);

        if ($stmt->execute()) {
            // Check if any row was actually affected
            if ($stmt->affected_rows > 0) {
                 // Update session email if it changed
                if ($currentEmail !== $newEmail) {
                    $_SESSION['user_email'] = $newEmail;
                }
                return ['success' => true, 'message' => 'Profile updated successfully.'];
            } else {
                // This can happen if the new data is the same as the old data, or user_id not found (already checked)
                return ['success' => true, 'message' => 'No changes made to the profile or user not found.'];
            }
        } else {
            error_log("Execute failed: (" . $stmt->errno . ") " . $stmt->error);
            // Check for duplicate email if that's a constraint
            if ($this->conn->errno == 1062) { // Error code for duplicate entry
                 return ['success' => false, 'message' => 'Email already exists.'];
            }
            return ['success' => false, 'message' => 'Failed to update profile.'];
        }
        $stmt->close();
    }

    public function addUserToQueue($fullName, $email) {
        // This function needs to be adapted. "queue" table is now "orders".
        // Adding to queue likely means creating an order and assigning a queue_number.
        // This requires user_id. Let's assume we find user_id by email.
        // Also, queue_number generation logic is needed.

        $userDetails = $this->getUserDetailsByEmail($email);
        if (!$userDetails) {
            // Handle case where user is not found, or create the user first.
            // For now, let's assume user must exist.
            error_log("User with email $email not found, cannot add to queue.");
            return ['success' => false, 'message' => 'User not found.'];
        }
        $userId = $userDetails['user_id'];

        // Determine the next queue number. This is a simplified example.
        // In a real application, this needs to be atomic to prevent race conditions.
        $sqlMaxQueue = "SELECT MAX(queue_number) as max_queue FROM orders";
        $resultMaxQueue = $this->conn->query($sqlMaxQueue);
        $maxQueue = 0;
        if ($resultMaxQueue && $resultMaxQueue->num_rows > 0) {
            $row = $resultMaxQueue->fetch_assoc();
            $maxQueue = intval($row['max_queue'] ?? 0);
        }
        $nextQueueNumber = $maxQueue + 1;

        // Create a new order with this user_id and queue_number
        // Assuming 'date' is current timestamp and other order details are not set here.
        $sqlInsertOrder = "INSERT INTO orders (user_id, date, queue_number) VALUES (?, NOW(), ?)";
        $stmt = $this->conn->prepare($sqlInsertOrder);
        if (!$stmt) {
            error_log("Prepare failed for adding to queue: " . $this->conn->error);
            return ['success' => false, 'message' => 'Database error.'];
        }
        $stmt->bind_param("ii", $userId, $nextQueueNumber);
        if ($stmt->execute()) {
            // $orderId = $this->conn->insert_id; // Get the new order_id if needed
            return ['success' => true, 'queue_number' => $nextQueueNumber, 'user_id' => $userId];
        } else {
            error_log("Execute failed for adding to queue: " . $stmt->error);
            return ['success' => false, 'message' => 'Failed to add to queue.'];
        }
    }

    public function deleteUserById($id)
    {
        $query = "DELETE FROM user WHERE user_id = ?";
        $stmt = $this->conn->prepare($query);
        if (!$stmt) {
            return false;
        }
        $stmt->bind_param("i", $id);
        if ($stmt->execute()) {
            $stmt->close();
            return true;
        }
        $stmt->close();
        return false;
    }

    // Product Management Methods
    public function getAllProducts()
    {
        $sql = "SELECT product_id, name, price, description, stock, admin_id, image_path FROM products";
        $result = $this->conn->query($sql);
        if (!$result) {
            return false; 
        }
        return $result;
    }

    public function getProductById($id)
    {
        // The image path is not in the 'product' table according to the schema.
        // If image information is stored elsewhere or associated differently, this needs adjustment.
        $sql = "SELECT product_id, name, price, description, stock, admin_id, image_path FROM products WHERE product_id = ?";
        $stmt = $this->conn->prepare($sql);
        if (!$stmt) {
            return null;
        }
        $stmt->bind_param("i", $id);
        $stmt->execute();
        $result = $stmt->get_result();
        if ($result && $result->num_rows > 0) {
            $product = $result->fetch_assoc();
            $stmt->close();
            return $product;
        }
        $stmt->close();
        return null;
    }

    public function addProduct($name, $price, $description, $stock, $admin_id, $imagePath = null)
    {
        $sql = "INSERT INTO products (name, price, description, stock, admin_id, image_path) VALUES (?, ?, ?, ?, ?, ?)";
        $stmt = $this->conn->prepare($sql);
        if (!$stmt) {
            return false;
        }
        $stmt->bind_param("sdsiss", $name, $price, $description, $stock, $admin_id, $imagePath);
        
        if ($stmt->execute()) {
            $stmt->close();
            return true;
        }
        $stmt->close();
        return false;
    }

    public function updateProduct($id, $name, $price, $description, $stock, $admin_id, $imagePath = null)
    {
        $sql = "UPDATE products SET name = ?, price = ?, description = ?, stock = ?, admin_id = ?, image_path = ? WHERE product_id = ?";
        $stmt = $this->conn->prepare($sql);
        $stmt->bind_param("sdsissi", $name, $price, $description, $stock, $admin_id, $imagePath, $id);

        if ($stmt->execute()) {
            return true;
        } else {
            return false;
        }
    }

    public function deleteProduct($id)
    {
        // Before deleting a product, consider implications for orderdetails.
        // You might want to set product_id in orderdetails to NULL or prevent deletion if orders exist.
        // For now, direct deletion:
        $sql = "DELETE FROM products WHERE product_id = ?";
        $stmt = $this->conn->prepare($sql);
        $stmt->bind_param("i", $id);
        return $stmt->execute();
    }

    public function getUserById($id)
    {
        // Assuming this is for the 'user' table
        $sql = "SELECT user_id, full_name, email, status, gender, phone, address, city FROM user WHERE user_id = ?";
        $stmt = $this->conn->prepare($sql);
        $stmt->bind_param("i", $id);
        $stmt->execute();
        $result = $stmt->get_result();
        if ($result->num_rows > 0) {
            return $result->fetch_assoc();
        }
        return null;
    }

    public function updateUserRecord($id, $fullName, $email, $gender, $status, $phone, $address, $city)
    {
        $sql = "UPDATE user SET full_name = ?, email = ?, gender = ?, status = ?, phone = ?, address = ?, city = ? WHERE user_id = ?";
        $stmt = $this->conn->prepare($sql);
        $stmt->bind_param("sssssssi", $fullName, $email, $gender, $status, $phone, $address, $city, $id);
        
        if ($stmt->execute()) {
            return $stmt->affected_rows > 0;
        } else {
            // Log error: $stmt->error
            return false;
        }
    }

    // End Product Management Methods

    public function createOrder($userId, $cartItems, $queueNumber = null) {
        // Start transaction
        $this->conn->begin_transaction();

        try {
            // If no cart items provided or empty, throw exception
            if (empty($cartItems)) {
                throw new Exception("No items in cart.");
            }

            // If no queue number provided, generate a new one
            if ($queueNumber === null) {
                // Get the highest queue number + 1
                $sql = "SELECT COALESCE(MAX(queue_number), 0) + 1 AS next_queue FROM orders";
                $result = $this->conn->query($sql);
                $row = $result->fetch_assoc();
                $queueNumber = $row['next_queue'];
            }

            // Insert into orders table
            $sqlOrder = "INSERT INTO orders (user_id, date, queue_number) VALUES (?, NOW(), ?)";
            $stmtOrder = $this->conn->prepare($sqlOrder);
            if (!$stmtOrder) {
                throw new Exception("Order statement prepare failed: " . $this->conn->error);
            }
            $stmtOrder->bind_param("ii", $userId, $queueNumber);
            $stmtOrder->execute();
            $orderId = $this->conn->insert_id;
            $stmtOrder->close();

            if (!$orderId) {
                 throw new Exception("Failed to create order.");
            }

            // Insert into orderdetails table
            $sqlDetail = "INSERT INTO orderdetails (order_id, product_id, quantity) VALUES (?, ?, ?)";
            $stmtDetail = $this->conn->prepare($sqlDetail);
            if (!$stmtDetail) {
                throw new Exception("OrderDetail statement prepare failed: " . $this->conn->error);
            }

            foreach ($cartItems as $item) {
                // Ensure item has product_id and quantity
                if (!isset($item['product_id']) || !isset($item['quantity'])) {
                    throw new Exception("Cart item is missing product_id or quantity.");
                }
                $stmtDetail->bind_param("iii", $orderId, $item['product_id'], $item['quantity']);
                $stmtDetail->execute();
                if ($stmtDetail->affected_rows === 0) {
                    throw new Exception("Failed to insert order detail for product_id: " . $item['product_id']);
                }
                // Update stock
                $this->updateProductStock($item['product_id'], -$item['quantity']);
            }
            $stmtDetail->close();

            // Commit transaction
            $this->conn->commit();
            return ['success' => true, 'order_id' => $orderId, 'queue_number' => $queueNumber];

        } catch (Exception $e) {
            $this->conn->rollback();
            error_log("Order creation failed: " . $e->getMessage());
            return ['success' => false, 'message' => $e->getMessage()];
        }
    }

    public function updateProductStock($productId, $quantityChange) {
        // quantityChange is negative for sale, positive for restock
        $sql = "UPDATE products SET stock = stock + ? WHERE product_id = ?";
        $stmt = $this->conn->prepare($sql);
        if (!$stmt) {
            error_log("Update stock prepare failed: " . $this->conn->error);
            return false;
        }
        $stmt->bind_param("ii", $quantityChange, $productId);
        if (!$stmt->execute()) {
            error_log("Update stock execute failed: " . $stmt->error);
            return false;
        }
        return $stmt->affected_rows > 0;
    }

    public function getOrderHistory($userId) {
        $sql = "SELECT o.order_id, o.date, o.queue_number, od.product_id, p.name as product_name, od.quantity, p.price 
                FROM orders o
                JOIN orderdetails od ON o.order_id = od.order_id
                JOIN products p ON od.product_id = p.product_id
                WHERE o.user_id = ?
                ORDER BY o.date DESC";
        $stmt = $this->conn->prepare($sql);
        $stmt->bind_param("i", $userId);
        $stmt->execute();
        $result = $stmt->get_result();
        $orders = [];
        while ($row = $result->fetch_assoc()) {
            $orders[$row['order_id']]['date'] = $row['date'];
            $orders[$row['order_id']]['queue_number'] = $row['queue_number'];
            $orders[$row['order_id']]['items'][] = [
                'product_id' => $row['product_id'],
                'product_name' => $row['product_name'],
                'quantity' => $row['quantity'],
                'price' => $row['price']
            ];
        }
        $stmt->close();
        return $orders;
    }
    
    // Method to get admin details by email
    public function getAdminByEmail($email) {
        $sql = "SELECT admin_id, full_name, email, number FROM admin WHERE email = ? LIMIT 1";
        $stmt = $this->conn->prepare($sql);
        if (!$stmt) {
            error_log("Admin prepare failed: " . $this->conn->error);
            return null;
        }
        $stmt->bind_param("s", $email);
        $stmt->execute();
        $result = $stmt->get_result();
        if ($result && $result->num_rows > 0) {
            return $result->fetch_assoc();
        }
        $stmt->close();
        return null;
    }

    public function getOrderDetailsById($orderId) {
        $orderDetails = [];

        // Get general order info (user_id, date, queue_number) and user info (full_name, email)
        $sqlOrder = "SELECT o.order_id, o.user_id, o.date, o.queue_number, u.full_name, u.email
                     FROM orders o
                     JOIN user u ON o.user_id = u.user_id
                     WHERE o.order_id = ?";
        $stmtOrder = $this->conn->prepare($sqlOrder);
        if (!$stmtOrder) {
            error_log("getOrderDetailsById (Order) prepare failed: " . $this->conn->error);
            return null;
        }
        $stmtOrder->bind_param("i", $orderId);
        $stmtOrder->execute();
        $resultOrder = $stmtOrder->get_result();
        if ($resultOrder->num_rows > 0) {
            $orderDetails = $resultOrder->fetch_assoc();
        } else {
            $stmtOrder->close();
            return null; // Order not found
        }
        $stmtOrder->close();

        // Get items in the order
        $sqlItems = "SELECT od.product_id, p.name as product_name, od.quantity, p.price as price_each
                     FROM orderdetails od
                     JOIN products p ON od.product_id = p.product_id
                     WHERE od.order_id = ?";
        $stmtItems = $this->conn->prepare($sqlItems);
        if (!$stmtItems) {
            error_log("getOrderDetailsById (Items) prepare failed: " . $this->conn->error);
            return null; // Or return partial data if desired
        }
        $stmtItems->bind_param("i", $orderId);
        $stmtItems->execute();
        $resultItems = $stmtItems->get_result();
        $items = [];
        $grandTotal = 0;
        while ($row = $resultItems->fetch_assoc()) {
            $sub_total = $row['price_each'] * $row['quantity'];
            $items[] = [
                'product_id' => $row['product_id'],
                'name' => $row['product_name'], // Changed from product_name for consistency with PDF expectations
                'quantity' => $row['quantity'],
                'price_each' => $row['price_each'],
                'sub_total' => $sub_total
            ];
            $grandTotal += $sub_total;
        }
        $stmtItems->close();

        $orderDetails['items'] = $items;
        $orderDetails['grand_total'] = $grandTotal;

        return $orderDetails;
    }

    // Get active cart for a user
    public function getActiveCart($userId) {
        // We'll use a temporary session-based cart system
        // Start by checking if this user has a cart entry in the session
        if (!isset($_SESSION['cart']) || !isset($_SESSION['cart'][$userId])) {
            // No cart exists yet for this user
            return [];
        }
        
        // Retrieve the cart items from session
        $cartItems = $_SESSION['cart'][$userId];
        
        // Now get the product details for each item
        $result = [];
        foreach ($cartItems as $item) {
            $productId = $item['product_id'];
            $quantity = $item['quantity'];
            
            // Get product details from the database
            $product = $this->getProductById($productId);
            
            if ($product) {
                // Add to result with product details and quantity
                $result[] = [
                    'product_id' => $productId,
                    'name' => $product['name'],
                    'price' => $product['price'],
                    'quantity' => $quantity
                ];
            }
        }
        
        return $result;
    }
    
    // Add an item to the cart
    public function addToCart($userId, $productId, $quantity = 1) {
        // Initialize cart if not exists
        if (!isset($_SESSION['cart'])) {
            $_SESSION['cart'] = [];
        }
        
        if (!isset($_SESSION['cart'][$userId])) {
            $_SESSION['cart'][$userId] = [];
        }
        
        // Check if product already exists in cart
        $found = false;
        foreach ($_SESSION['cart'][$userId] as &$item) {
            if ($item['product_id'] == $productId) {
                // Update quantity
                $item['quantity'] += $quantity;
                $found = true;
                break;
            }
        }
        
        // If not found, add new item
        if (!$found) {
            $_SESSION['cart'][$userId][] = [
                'product_id' => $productId,
                'quantity' => $quantity
            ];
        }
        
        return true;
    }
    
    // Remove an item from the cart
    public function removeCartItem($userId, $productId) {
        if (!isset($_SESSION['cart']) || !isset($_SESSION['cart'][$userId])) {
            return false;
        }
        
        foreach ($_SESSION['cart'][$userId] as $key => $item) {
            if ($item['product_id'] == $productId) {
                // Remove this item
                unset($_SESSION['cart'][$userId][$key]);
                // Reindex the array
                $_SESSION['cart'][$userId] = array_values($_SESSION['cart'][$userId]);
                return true;
            }
        }
        
        return false;
    }
    
    // Clear the entire cart for a user
    public function clearCart($userId) {
        if (isset($_SESSION['cart']) && isset($_SESSION['cart'][$userId])) {
            $_SESSION['cart'][$userId] = [];
            return true;
        }
        return false;
    }
}

function getUserData() {
    $userModel = new User(); // Instantiate User class to use its connection
    $conn = $userModel->getConnection();

    $email = $_SESSION['user_email'] ?? null;
    $userData = [
        'full_name' => '', // Changed from first_name, last_name
        'phone' => '',
        'email' => $email, // Use session email as default or for query
        'address' => '',
        'city' => '',
        'gender' => '' // Initialize gender
    ];

    if ($email) {
        // Adjusted query to select all necessary fields including gender from the 'user' table
        $stmt = $conn->prepare("SELECT full_name, phone, email, address, city, gender FROM user WHERE email = ?");
        if ($stmt) {
            $stmt->bind_param("s", $email);
            $stmt->execute();
            $result = $stmt->get_result();
            if ($dbUserData = $result->fetch_assoc()) {
                $userData['full_name'] = $dbUserData['full_name'] ?? '';
                $userData['phone'] = $dbUserData['phone'] ?? '';
                $userData['email'] = $dbUserData['email'] ?? $email; // Fallback to session email
                $userData['address'] = $dbUserData['address'] ?? '';
                $userData['city'] = $dbUserData['city'] ?? '';
                $userData['gender'] = $dbUserData['gender'] ?? ''; // Fetch gender
            }
            $stmt->close();
        } else {
            // Log error or handle prepare statement failure
            error_log("Failed to prepare statement in getUserData: " . $conn->error);
        }
    }
    // $userModel->closeConnection(); // Connection usually closed at script end or by __destruct if defined
    return $userData;
}