<?php
// classes/Order.php - Order management and countdown handler

require_once __DIR__ . '/Database.php';
require_once __DIR__ . '/Cart.php';

class Order {
    private $db;

    public function __construct() {
        $this->db = Database::getInstance()->getConnection();
    }

    public function checkout($userId) {
        $cart = new Cart();
        $cartTotals = $cart->getTotals($userId);
        $cartItems = $cart->getDetails($userId);

        if ($cartTotals['total_items'] <= 0) {
            throw new Exception("Your cart is empty.");
        }

        try {
            $this->db->beginTransaction();

            // 1. Insert order (expired_at is computed +20 minutes automatically by Database Trigger)
            $stmt = $this->db->prepare("INSERT INTO orders (user_id, total_amount, status) VALUES (?, ?, 'pending')");
            $stmt->execute([$userId, $cartTotals['total_amount']]);
            $orderId = $this->db->lastInsertId();

            // 2. Insert order items & check/deduct inventory stock
            foreach ($cartItems as $item) {
                // Fetch & lock stock level
                $stmt = $this->db->prepare("SELECT stock FROM products WHERE id = ? FOR UPDATE");
                $stmt->execute([$item['product_id']]);
                $prod = $stmt->fetch();

                if (!$prod || $prod['stock'] < $item['quantity']) {
                    throw new Exception("Product '" . $item['product_name'] . "' is out of stock.");
                }

                // Deduct inventory
                $stmt = $this->db->prepare("UPDATE products SET stock = stock - ? WHERE id = ?");
                $stmt->execute([$item['quantity'], $item['product_id']]);

                // Record item in order
                $stmt = $this->db->prepare("INSERT INTO order_items (order_id, product_id, size, quantity, price_per_unit) VALUES (?, ?, ?, ?, ?)");
                $stmt->execute([$orderId, $item['product_id'], $item['size'] ?? 'Free Size', $item['quantity'], $item['unit_price']]);
            }

            // 3. Clear user's shopping cart
            $stmt = $this->db->prepare("DELETE FROM cart_items WHERE user_id = ?");
            $stmt->execute([$userId]);

            $this->db->commit();
            return $orderId;

        } catch (Exception $e) {
            $this->db->rollBack();
            throw $e;
        }
    }

    public function getStatusAndCountdown($orderId) {
        $stmt = $this->db->prepare("
            SELECT 
                id, 
                user_id,
                total_amount, 
                status, 
                created_at, 
                expired_at,
                TIMESTAMPDIFF(SECOND, NOW(), expired_at) as remaining_seconds
            FROM orders
            WHERE id = ?
        ");
        $stmt->execute([$orderId]);
        $order = $stmt->fetch();

        if (!$order) return null;

        // Auto-check and update to 'expired' if time is up and status is still pending
        if ($order['status'] === 'pending' && $order['remaining_seconds'] <= 0) {
            $this->expireOrder($orderId);
            $order['status'] = 'expired';
            $order['remaining_seconds'] = 0;
        }

        return $order;
    }

    public function pay($orderId, $paymentMethod, $transactionId) {
        $order = $this->getStatusAndCountdown($orderId);

        if (!$order) {
            throw new Exception("Order not found.");
        }
        if ($order['status'] === 'expired') {
            throw new Exception("This order has expired and cannot be paid.");
        }
        if ($order['status'] !== 'pending') {
            throw new Exception("This order is already processed.");
        }

        try {
            $this->db->beginTransaction();

            // Insert payment log
            $stmt = $this->db->prepare("
                INSERT INTO payments (order_id, payment_method, transaction_id, amount, payment_status, paid_at)
                VALUES (?, ?, ?, ?, 'completed', NOW())
            ");
            $stmt->execute([$orderId, $paymentMethod, $transactionId, $order['total_amount']]);

            // Update order status to paid
            $stmt = $this->db->prepare("UPDATE orders SET status = 'paid' WHERE id = ?");
            $stmt->execute([$orderId]);

            $this->db->commit();
            return true;
        } catch (Exception $e) {
            $this->db->rollBack();
            throw $e;
        }
    }

    // Helper to change order to expired and return products to stock
    private function expireOrder($orderId) {
        try {
            $this->db->beginTransaction();

            // Set state to expired
            $stmt = $this->db->prepare("UPDATE orders SET status = 'expired' WHERE id = ?");
            $stmt->execute([$orderId]);

            // Retrieve items to restore inventory stock levels
            $stmt = $this->db->prepare("SELECT product_id, quantity FROM order_items WHERE order_id = ?");
            $stmt->execute([$orderId]);
            $items = $stmt->fetchAll();

            foreach ($items as $item) {
                $stmt = $this->db->prepare("UPDATE products SET stock = stock + ? WHERE id = ?");
                $stmt->execute([$item['quantity'], $item['product_id']]);
            }

            $this->db->commit();
        } catch (Exception $e) {
            $this->db->rollBack();
        }
    }
}
