<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Product;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;

class CartController extends Controller
{
    private function getCartKey(Request $request): string
    {
        if ($request->user()) {
            return 'cart_user_' . $request->user()->id;
        }
        return 'cart_session_' . ($request->header('X-Session-ID') ?: session()->getId());
    }

    private function getCart(Request $request): array
    {
        return Cache::get($this->getCartKey($request), ['items' => []]);
    }

    private function saveCart(Request $request, array $cart): void
    {
        Cache::put($this->getCartKey($request), $cart, now()->addDays(7));
    }

    public function index(Request $request)
    {
        $cart = $this->getCart($request);
        $total = collect($cart['items'])->sum(fn($i) => $i['price'] * $i['quantity']);

        return response()->json([
            'success' => true,
            'data' => ['cart' => $cart, 'total' => $total],
        ]);
    }

    private function getStockForSize(Product $product, string $size): int
    {
        $sizes = $product->sizes ?? [];
        foreach ($sizes as $s) {
            if (($s['label'] ?? '') === $size) {
                return isset($s['stock']) ? (int)$s['stock'] : $product->stock;
            }
        }
        return $product->stock ?? 0;
    }

    public function addItem(Request $request)
    {
        $request->validate([
            'product_id' => 'required|integer',
            'quantity'   => 'required|integer|min:1',
            'price'      => 'required|numeric',
        ]);

        $product = Product::find($request->product_id);
        if (!$product) {
            return response()->json(['success' => false, 'message' => 'Product not found'], 404);
        }

        $size  = $request->size ?? $product->size ?? '100ml';
        $stock = $this->getStockForSize($product, $size);

        $cart  = $this->getCart($request);
        $found = false;

        foreach ($cart['items'] as &$item) {
            if ($item['product_id'] == $request->product_id && $item['size'] == $size) {
                $newQty = $item['quantity'] + $request->quantity;
                if ($stock > 0 && $newQty > $stock) {
                    return response()->json(['success' => false, 'message' => "Only {$stock} in stock for {$size}"], 422);
                }
                $item['quantity'] = $newQty;
                $found = true;
                break;
            }
        }

        if (!$found) {
            if ($stock <= 0) {
                return response()->json(['success' => false, 'message' => 'Out of stock'], 422);
            }
            if ($request->quantity > $stock) {
                return response()->json(['success' => false, 'message' => "Only {$stock} in stock for {$size}"], 422);
            }
            $salePrice     = $product->sale_price ? (float)$product->sale_price : null;
            $originalPrice = (float)$product->price;
            $effectivePrice = $request->price ?: $salePrice ?: $originalPrice;

            $cart['items'][] = [
                'id'             => time() . rand(100, 999),
                'product_id'     => $product->id,
                'size'           => $size,
                'quantity'       => $request->quantity,
                'price'          => $effectivePrice,
                'original_price' => $originalPrice,
                'stock'          => $stock,
                'product'        => [
                    'id'       => $product->id,
                    'name'     => $product->name,
                    'slug'     => $product->slug,
                    'subtitle' => $product->subtitle,
                    'image'    => $product->image,
                    'color'    => $product->color,
                    'images'   => [['image_path' => $product->image]],
                ],
            ];
        }

        $this->saveCart($request, $cart);

        return response()->json(['success' => true, 'data' => ['cart' => $cart]]);
    }

    public function updateItem(Request $request, $itemId)
    {
        $cart = $this->getCart($request);

        foreach ($cart['items'] as &$item) {
            if ($item['id'] == $itemId) {
                $newQty = (int)$request->quantity;
                if ($newQty <= 0) {
                    // Remove item if qty goes to 0
                    $cart['items'] = array_values(array_filter($cart['items'], fn($i) => $i['id'] != $itemId));
                    $this->saveCart($request, $cart);
                    return response()->json(['success' => true, 'data' => ['cart' => $cart]]);
                }
                $stock = $item['stock'] ?? 0;
                if ($stock > 0 && $newQty > $stock) {
                    $newQty = $stock;
                }
                $item['quantity'] = $newQty;
                break;
            }
        }

        $this->saveCart($request, $cart);

        return response()->json(['success' => true, 'data' => ['cart' => $cart]]);
    }

    public function removeItem(Request $request, $itemId)
    {
        $cart = $this->getCart($request);
        $cart['items'] = array_values(array_filter($cart['items'], fn($i) => $i['id'] != $itemId));
        $this->saveCart($request, $cart);

        return response()->json(['success' => true, 'data' => ['cart' => $cart]]);
    }

    public function clear(Request $request)
    {
        $this->saveCart($request, ['items' => []]);
        return response()->json(['success' => true, 'data' => ['cart' => ['items' => []]]]);
    }
}
