<?php
declare(strict_types=1);

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

class CartService
{
    private const KEY = 'zylon_cart';

    public function getItems(): array
    {
        $this->ensureSession();
        return array_values($_SESSION[self::KEY] ?? []);
    }

    public function addProduct(int $productId, int $qty = 1): bool
    {
        $qty = max(1, $qty);
        $product = (new Product())->find($productId);
        if (!$product || (int)$product['stock'] < 1) {
            return false;
        }

        $this->ensureSession();
        $cart = $_SESSION[self::KEY] ?? [];
        $key = (string)$productId;
        if (isset($cart[$key])) {
            $cart[$key]['quantity'] = min((int)$product['stock'], (int)$cart[$key]['quantity'] + $qty);
        } else {
            $cart[$key] = [
                'product_id' => (int)$product['id'],
                'sku' => (string)$product['sku'],
                'product_title' => (string)$product['title'],
                'price' => (float)$product['price'],
                'quantity' => min((int)$product['stock'], $qty),
                'stock' => (int)$product['stock'],
            ];
        }

        $_SESSION[self::KEY] = $cart;
        return true;
    }

    public function updateQuantity(int $productId, int $qty): void
    {
        $this->ensureSession();
        $key = (string)$productId;
        if (!isset($_SESSION[self::KEY][$key])) {
            return;
        }

        if ($qty <= 0) {
            unset($_SESSION[self::KEY][$key]);
            return;
        }

        $stock = (int)$_SESSION[self::KEY][$key]['stock'];
        $_SESSION[self::KEY][$key]['quantity'] = min($stock, max(1, $qty));
    }

    public function removeProduct(int $productId): void
    {
        $this->ensureSession();
        unset($_SESSION[self::KEY][(string)$productId]);
    }

    public function clear(): void
    {
        $this->ensureSession();
        $_SESSION[self::KEY] = [];
    }

    public function totals(): array
    {
        $items = $this->getItems();
        $subtotal = 0.0;
        foreach ($items as $item) {
            $subtotal += (float)$item['price'] * (int)$item['quantity'];
        }
        $shipping = $subtotal > 0 ? (float)DEFAULT_SHIPPING_FEE : 0.0;
        $discount = 0.0;
        $grandTotal = max(0.0, $subtotal + $shipping - $discount);

        return [
            'items_count' => count($items),
            'subtotal' => $subtotal,
            'shipping' => $shipping,
            'discount' => $discount,
            'grand_total' => $grandTotal,
        ];
    }

    private function ensureSession(): void
    {
        if (session_status() !== PHP_SESSION_ACTIVE) {
            session_start();
        }
        if (!isset($_SESSION[self::KEY]) || !is_array($_SESSION[self::KEY])) {
            $_SESSION[self::KEY] = [];
        }
    }
}
