<?php

namespace App\Services;

use App\Models\ProductVariant;
use Illuminate\Support\Collection;

class CartService
{
    private const SESSION_KEY = 'raseednow_cart';

    private const COUPON_KEY = 'raseednow_coupon_code';

    public function all(): Collection
    {
        $cart = session(self::SESSION_KEY, []);
        $ids = array_keys($cart);

        return ProductVariant::with('game')
            ->whereIn('id', $ids)
            ->get()
            ->map(function (ProductVariant $product) use ($cart) {
                $quantity = max(1, (int) ($cart[$product->id] ?? 1));
                $unitPrice = $product->sale_price_minor ?? $product->price_minor;

                return [
                    'product' => $product,
                    'quantity' => $quantity,
                    'unit_price_minor' => $unitPrice,
                    'line_total_minor' => $unitPrice * $quantity,
                ];
            })
            ->values();
    }

    public function add(ProductVariant $product, int $quantity = 1): void
    {
        if ($product->stock_available < 1) {
            return;
        }

        $cart = session(self::SESSION_KEY, []);
        $current = (int) ($cart[$product->id] ?? 0);
        $cart[$product->id] = min($product->stock_available, max(1, $current + $quantity));

        session([self::SESSION_KEY => $cart]);
    }

    public function update(ProductVariant $product, int $quantity): void
    {
        $cart = session(self::SESSION_KEY, []);

        if ($quantity <= 0) {
            unset($cart[$product->id]);
        } else {
            if ($product->stock_available < 1) {
                unset($cart[$product->id]);
            } else {
                $cart[$product->id] = min($product->stock_available, $quantity);
            }
        }

        session([self::SESSION_KEY => $cart]);
    }

    public function remove(ProductVariant $product): void
    {
        $cart = session(self::SESSION_KEY, []);
        unset($cart[$product->id]);

        session([self::SESSION_KEY => $cart]);
    }

    public function clear(): void
    {
        session()->forget(self::SESSION_KEY);
        session()->forget(self::COUPON_KEY);
    }

    public function applyCoupon(string $code): void
    {
        session([self::COUPON_KEY => strtoupper(trim($code))]);
    }

    public function removeCoupon(): void
    {
        session()->forget(self::COUPON_KEY);
    }

    public function couponCode(): ?string
    {
        return session(self::COUPON_KEY);
    }

    public function count(): int
    {
        return array_sum(session(self::SESSION_KEY, []));
    }

    public function totalMinor(): int
    {
        return $this->all()->sum('line_total_minor');
    }
}
