<?php
namespace App\Core;

use RuntimeException;

class Cart {
    private static function &items(): array {
        if (!isset($_SESSION['cart']) || !is_array($_SESSION['cart'])) $_SESSION['cart'] = [];
        return $_SESSION['cart'];
    }

    public static function add(int $productId, int $qty = 1, ?int $variantId = null): array {
        if ($productId < 1) throw new RuntimeException('Invalid product.');
        $qty = max(1, $qty);
        $product = Database::safeFetchOne(
            'SELECT p.*, v.shop_name FROM products p LEFT JOIN vendors v ON v.id=p.vendor_id WHERE p.id=? AND p.status="published" LIMIT 1',
            [$productId]
        );
        if (!$product) throw new RuntimeException('Product is unavailable.');

        $variant = null;
        if ($variantId) {
            $variant = Database::safeFetchOne('SELECT * FROM product_variants WHERE id=? AND product_id=? LIMIT 1', [$variantId, $productId]);
            if (!$variant) throw new RuntimeException('Selected product option is unavailable.');
        }

        $stock = (int)($variant['stock'] ?? $product['stock'] ?? 0);
        if ($stock < 1) throw new RuntimeException('Product is out of stock.');
        $key = $variantId ? $productId . ':' . $variantId : (string)$productId;
        $items =& self::items();
        $current = (int)($items[$key]['qty'] ?? 0);
        $newQty = min($stock, $current + $qty);
        $items[$key] = ['product'=>$product, 'variant'=>$variant, 'variant_id'=>$variantId, 'qty'=>$newQty];
        return self::summary();
    }

    public static function update(string|int $key, int $qty): array {
        $key = (string)$key;
        $items =& self::items();
        if ($qty <= 0) {
            unset($items[$key]);
            return self::summary();
        }
        if (!isset($items[$key])) return self::summary();
        $stock = (int)($items[$key]['variant']['stock'] ?? $items[$key]['product']['stock'] ?? 0);
        $items[$key]['qty'] = max(1, min($qty, max(1, $stock)));
        return self::summary();
    }

    public static function remove(string|int $key): array {
        $items =& self::items();
        unset($items[(string)$key]);
        return self::summary();
    }

    public static function clear(): void { unset($_SESSION['cart']); }

    public static function summary(): array {
        $items = self::items();
        $count = 0;
        $subtotal = 0.0;
        foreach ($items as $key => $item) {
            $product = $item['product'];
            $variant = $item['variant'] ?? null;
            $price = (float)($variant['price'] ?? (($product['sale_price'] ?: $product['regular_price']) ?? 0));
            $qty = max(1, (int)($item['qty'] ?? 1));
            $count += $qty;
            $subtotal += $price * $qty;
            $items[$key]['unit_price'] = $price;
            $items[$key]['line_total'] = $price * $qty;
        }
        return ['items'=>$items, 'count'=>$count, 'subtotal'=>round($subtotal, 2)];
    }
}
