<?php
/**
 * Cart Class
 * Handles shopping cart operations including abandoned carts
 */

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

class Cart {
    private $db;
    private $product;

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

    /**
     * Get or create cart for user/session
     */
    public function getOrCreateCart($userId = null, $sessionId = null) {
        // If user_id is provided, verify it exists
        if ($userId) {
            $userExists = $this->db->fetchOne("SELECT id FROM users WHERE id = ?", [$userId]);
            if (!$userExists) {
                // User doesn't exist, treat as guest
                $userId = null;
            }
        }

        // Ensure session_id is always set for guest carts
        if (!$sessionId) {
            $sessionId = session_id();
            if (!$sessionId || empty($sessionId)) {
                // If session_id is still empty, generate one
                $sessionId = bin2hex(random_bytes(16));
                if (session_status() === PHP_SESSION_ACTIVE) {
                    $_SESSION['session_id'] = $sessionId;
                }
            }
        }

        if ($userId) {
            $cart = $this->db->fetchOne(
                "SELECT * FROM cart WHERE user_id = ? ORDER BY updated_at DESC LIMIT 1",
                [$userId]
            );
        } else {
            $cart = $this->db->fetchOne(
                "SELECT * FROM cart WHERE session_id = ? AND user_id IS NULL ORDER BY updated_at DESC LIMIT 1",
                [$sessionId]
            );
        }

        if (!$cart) {
            // Ensure at least one of user_id or session_id is provided
            if (!$userId && !$sessionId) {
                // Generate a session ID if none provided
                $sessionId = session_id() ?: bin2hex(random_bytes(16));
            }
            
            try {
                $this->db->execute(
                    "INSERT INTO cart (user_id, session_id) VALUES (?, ?)",
                    [$userId ?: null, $sessionId]
                );
                $cartId = $this->db->lastInsertId();
                return $this->db->fetchOne("SELECT * FROM cart WHERE id = ?", [$cartId]);
            } catch (Exception $e) {
                error_log("Error creating cart: " . $e->getMessage());
                throw new Exception("Failed to create cart: " . $e->getMessage());
            }
        }

        return $cart;
    }

    /**
     * Get cart items
     */
    public function getCartItems($cartId) {
        return $this->db->fetchAll(
            "SELECT ci.*, p.name, p.slug, p.image, p.sku,
                    COALESCE(p.sale_price, p.price) as current_price
             FROM cart_items ci
             INNER JOIN products p ON ci.product_id = p.id
             WHERE ci.cart_id = ? AND p.is_active = 1",
            [$cartId]
        );
    }

    /**
     * Add product to cart
     */
    public function addToCart($productId, $quantity = 1, $userId = null, $sessionId = null) {
        // Get product first (without active check for cart operations)
        $product = $this->db->fetchOne(
            "SELECT * FROM products WHERE id = ?",
            [$productId]
        );
        
        if (!$product) {
            return ['success' => false, 'message' => 'Produsul nu a fost găsit'];
        }
        
        // Check if product is active
        if (!$product['is_active']) {
            return ['success' => false, 'message' => 'Produsul nu este disponibil'];
        }
        
        // Check stock
        if ($product['stock_quantity'] < $quantity) {
            return ['success' => false, 'message' => 'Stoc insuficient'];
        }

        try {
            $cart = $this->getOrCreateCart($userId, $sessionId);
            
            if (!$cart || !isset($cart['id'])) {
                return ['success' => false, 'message' => 'Eroare la crearea coșului'];
            }
            
            $price = $product['sale_price'] ?? $product['price'];

            // Check if product already in cart
            $existingItem = $this->db->fetchOne(
                "SELECT * FROM cart_items WHERE cart_id = ? AND product_id = ?",
                [$cart['id'], $productId]
            );

            if ($existingItem) {
                // Update quantity
                $newQuantity = $existingItem['quantity'] + $quantity;
                if ($product['stock_quantity'] < $newQuantity) {
                    return ['success' => false, 'message' => 'Stoc insuficient'];
                }

                $this->db->execute(
                    "UPDATE cart_items SET quantity = ?, price_at_add = ? WHERE id = ?",
                    [$newQuantity, $price, $existingItem['id']]
                );
            } else {
                // Add new item
                try {
                    $this->db->execute(
                        "INSERT INTO cart_items (cart_id, product_id, quantity, price_at_add) 
                         VALUES (?, ?, ?, ?)",
                        [$cart['id'], $productId, $quantity, $price]
                    );
                } catch (PDOException $e) {
                    // If duplicate key error, try to update instead
                    if ($e->getCode() == 23000) {
                        $existingItem = $this->db->fetchOne(
                            "SELECT * FROM cart_items WHERE cart_id = ? AND product_id = ?",
                            [$cart['id'], $productId]
                        );
                        if ($existingItem) {
                            $newQuantity = $existingItem['quantity'] + $quantity;
                            if ($product['stock_quantity'] < $newQuantity) {
                                return ['success' => false, 'message' => 'Stoc insuficient'];
                            }
                            $this->db->execute(
                                "UPDATE cart_items SET quantity = ?, price_at_add = ? WHERE id = ?",
                                [$newQuantity, $price, $existingItem['id']]
                            );
                        } else {
                            throw $e;
                        }
                    } else {
                        throw $e;
                    }
                }
            }

            // Update cart timestamp
            $this->db->execute(
                "UPDATE cart SET updated_at = NOW() WHERE id = ?",
                [$cart['id']]
            );

            return ['success' => true, 'cart_id' => $cart['id']];
        } catch (Exception $e) {
            error_log("Add to cart error: " . $e->getMessage() . " | Product ID: " . $productId);
            return ['success' => false, 'message' => 'Eroare: ' . $e->getMessage()];
        }
    }

    /**
     * Update cart item quantity
     */
    public function updateCartItem($cartItemId, $quantity) {
        $item = $this->db->fetchOne(
            "SELECT ci.* FROM cart_items ci WHERE ci.id = ?",
            [$cartItemId]
        );

        if (!$item) {
            return ['success' => false, 'message' => 'Item not found'];
        }

        if ($quantity <= 0) {
            return $this->removeCartItem($cartItemId);
        }

        // Check stock
        if (!$this->product->isInStock($item['product_id'], $quantity)) {
            return ['success' => false, 'message' => 'Not enough stock available'];
        }

        $this->db->execute(
            "UPDATE cart_items SET quantity = ? WHERE id = ?",
            [$quantity, $cartItemId]
        );

        return ['success' => true];
    }

    /**
     * Remove item from cart
     */
    public function removeCartItem($cartItemId) {
        $this->db->execute("DELETE FROM cart_items WHERE id = ?", [$cartItemId]);
        return ['success' => true];
    }

    /**
     * Get cart total
     */
    public function getCartTotal($cartId, $userId = null) {
        $items = $this->getCartItems($cartId);
        $total = 0;

        require_once __DIR__ . '/B2B.php';
        $b2b = new B2B();

        foreach ($items as $item) {
            $product = $this->product->getProductById($item['product_id']);
            if ($product) {
                // Use B2B class to calculate price (handles product-specific prices and group discounts)
                $price = $b2b->calculateProductPrice($product, $userId);
            } else {
                $price = $item['price_at_add'];
            }

            $total += $price * $item['quantity'];
        }

        return $total;
    }

    /**
     * Get cart count
     */
    public function getCartCount($cartId) {
        $result = $this->db->fetchOne(
            "SELECT SUM(quantity) as total FROM cart_items WHERE cart_id = ?",
            [$cartId]
        );
        return $result['total'] ?? 0;
    }

    /**
     * Merge carts (when user logs in)
     */
    public function mergeCarts($sessionCartId, $userCartId, $mergeType = 'merge') {
        $sessionItems = $this->getCartItems($sessionCartId);
        $userItems = $this->getCartItems($userCartId);

        if ($mergeType === 'replace') {
            // Delete user cart items and move session items
            $this->db->execute("DELETE FROM cart_items WHERE cart_id = ?", [$userCartId]);
            $this->db->execute(
                "UPDATE cart_items SET cart_id = ? WHERE cart_id = ?",
                [$userCartId, $sessionCartId]
            );
        } elseif ($mergeType === 'keep') {
            // Keep user cart, delete session cart
            $this->db->execute("DELETE FROM cart_items WHERE cart_id = ?", [$sessionCartId]);
        } else {
            // Merge: add session items to user cart, avoiding duplicates
            foreach ($sessionItems as $sessionItem) {
                $existing = $this->db->fetchOne(
                    "SELECT * FROM cart_items WHERE cart_id = ? AND product_id = ?",
                    [$userCartId, $sessionItem['product_id']]
                );

                if ($existing) {
                    // Update quantity
                    $newQuantity = $existing['quantity'] + $sessionItem['quantity'];
                    $this->db->execute(
                        "UPDATE cart_items SET quantity = ? WHERE id = ?",
                        [$newQuantity, $existing['id']]
                    );
                } else {
                    // Add new item
                    $this->db->execute(
                        "UPDATE cart_items SET cart_id = ? WHERE id = ?",
                        [$userCartId, $sessionItem['id']]
                    );
                }
            }
            $this->db->execute("DELETE FROM cart WHERE id = ?", [$sessionCartId]);
        }

        // Update user cart timestamp
        $this->db->execute(
            "UPDATE cart SET updated_at = NOW() WHERE id = ?",
            [$userCartId]
        );

        return ['success' => true];
    }

    /**
     * Get abandoned carts
     */
    public function getAbandonedCarts($hours = 24) {
        return $this->db->fetchAll(
            "SELECT c.*, u.email, u.first_name, u.last_name, u.phone,
                    COUNT(ci.id) as items_count
             FROM cart c
             LEFT JOIN users u ON c.user_id = u.id
             LEFT JOIN cart_items ci ON c.id = ci.cart_id
             WHERE c.updated_at < DATE_SUB(NOW(), INTERVAL ? HOUR)
             AND c.id NOT IN (SELECT DISTINCT cart_id FROM orders WHERE cart_id = c.id)
             AND (c.email_count < ? OR c.email_count IS NULL)
             GROUP BY c.id
             HAVING items_count > 0",
            [$hours, MAX_ABANDONED_CART_EMAILS]
        );
    }

    /**
     * Clear cart
     */
    public function clearCart($cartId) {
        $this->db->execute("DELETE FROM cart_items WHERE cart_id = ?", [$cartId]);
        return ['success' => true];
    }
}
?>

