<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Cart;
use App\Models\CartItem;
use App\Models\Product;
use App\Models\ProductVariant;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class CartApiController extends Controller
{
    /**
     * Helper to get or create cart based on Auth or X-Guest-Cart-Token header.
     */
    private function getCart(Request $request)
    {
        if (Auth::check()) {
            $cart = Cart::firstOrCreate(['user_id' => Auth::id()]);
            
            // Migrate guest cart if token is passed
            $guestToken = $request->header('X-Guest-Cart-Token');
            if ($guestToken) {
                $guestCart = Cart::where('session_id', $guestToken)->first();
                if ($guestCart && $guestCart->id !== $cart->id) {
                    foreach ($guestCart->items as $item) {
                        $existingItem = $cart->items()
                            ->where('product_id', $item->product_id)
                            ->where('product_variant_id', $item->product_variant_id)
                            ->first();

                        if ($existingItem) {
                            $existingItem->update(['quantity' => $existingItem->quantity + $item->quantity]);
                            $item->delete();
                        } else {
                            $item->update(['cart_id' => $cart->id]);
                        }
                    }
                    $guestCart->delete();
                }
            }
            return $cart;
        }

        $guestToken = $request->header('X-Guest-Cart-Token');
        if (!$guestToken) {
            $guestToken = $request->session()->getId();
        }
        return Cart::firstOrCreate(['session_id' => $guestToken]);
    }

    /**
     * Retrieve the current cart details.
     */
    public function index(Request $request)
    {
        $cart = $this->getCart($request);

        // ✅ Eager load everything in ONE query set — fixes N+1 completely
        $cart->load(['items.product.media', 'items.variant']);

        $items = [];
        $subtotal = 0.00;

        foreach ($cart->items as $item) {
            $price = $item->variant && $item->variant->price !== null && floatval($item->variant->price) > 0
                ? $item->variant->price 
                : $item->product->price;

            $imageUrl = $item->product->getFirstMediaUrl('images', 'webp') 
                ?: ($item->product->getFirstMediaUrl('images') 
                ?: '/images/placeholder.jpg');

            $items[] = [
                'id'             => $item->id,
                'product_id'     => $item->product_id,
                'variant_id'     => $item->product_variant_id,
                'name'           => $item->product->name,
                'slug'           => $item->product->slug,
                'sku'            => $item->variant?->sku ?? $item->product->sku,
                'price'          => (float)$price,
                'reseller_price' => (float)$item->product->reseller_price,
                'quantity'       => $item->quantity,
                'options'        => $item->variant?->options ?? [],
                'image_url'      => $imageUrl,
                'stock'          => $item->variant ? $item->variant->quantity : $item->product->quantity,
            ];

            $subtotal += $price * $item->quantity;
        }

        return response()->json([
            'cart_items'      => $items,
            'subtotal'        => $subtotal,
            'guest_cart_token' => !Auth::check()
                ? ($request->header('X-Guest-Cart-Token') ?: $request->session()->getId())
                : null,
        ]);
    }

    /**
     * Add an item to the cart.
     */
    public function add(Request $request)
    {
        $request->validate([
            'product_id' => 'required|integer|exists:products,id',
            'variant_id' => 'nullable|integer|exists:product_variants,id',
            'quantity' => 'nullable|integer|min:1',
        ]);

        $cart = $this->getCart($request);
        $productId = $request->product_id;
        $variantId = $request->variant_id;
        $quantity = $request->input('quantity', 1);

        $product = Product::find($productId);
        if (!$product || !$product->is_visible) {
            return response()->json(['success' => false, 'message' => 'Product is not available.'], 422);
        }

        // Verify stock limit
        $availableStock = $product->quantity;
        if ($variantId) {
            $variant = ProductVariant::find($variantId);
            if (!$variant || $variant->product_id !== $productId) {
                return response()->json(['success' => false, 'message' => 'Invalid product variant selected.'], 422);
            }
            $availableStock = $variant->quantity;
        }

        // Check current quantity in cart
        $cartItem = $cart->items()
            ->where('product_id', $productId)
            ->where('product_variant_id', $variantId)
            ->first();

        $currentQty = $cartItem ? $cartItem->quantity : 0;
        $newQty = $currentQty + $quantity;

        if ($newQty > $availableStock) {
            return response()->json([
                'success' => false,
                'message' => 'Requested quantity exceeds available stock (' . $availableStock . ' available).'
            ], 422);
        }

        if ($cartItem) {
            $cartItem->update(['quantity' => $newQty]);
        } else {
            $cart->items()->create([
                'product_id' => $productId,
                'product_variant_id' => $variantId,
                'quantity' => $quantity,
            ]);
        }

        return response()->json([
            'success' => true,
            'message' => 'Product added to cart successfully.',
        ]);
    }

    /**
     * Update the quantity of an item in the cart.
     */
    public function update(Request $request)
    {
        $request->validate([
            'cart_item_id' => 'required|integer|exists:cart_items,id',
            'quantity' => 'required|integer',
        ]);

        $cart = $this->getCart($request);
        $cartItemId = $request->cart_item_id;
        $quantity = $request->quantity;

        // ✅ Eager load product+variant in one go to avoid lazy N+1 on stock check
        $cartItem = $cart->items()->with(['product', 'variant'])->find($cartItemId);
        if (!$cartItem) {
            return response()->json(['success' => false, 'message' => 'Item not found in cart.'], 404);
        }

        if ($quantity <= 0) {
            $cartItem->delete();
            return response()->json(['success' => true, 'message' => 'Item removed from cart.']);
        }

        // Verify stock limit (no extra query — already loaded)
        $availableStock = $cartItem->variant ? $cartItem->variant->quantity : $cartItem->product->quantity;
        if ($quantity > $availableStock) {
            return response()->json([
                'success' => false,
                'message' => 'Quantity exceeds available stock (' . $availableStock . ' available).'
            ], 422);
        }

        $cartItem->update(['quantity' => $quantity]);
        return response()->json(['success' => true, 'message' => 'Cart updated successfully.']);
    }

    /**
     * Remove an item from the cart.
     */
    public function remove(Request $request)
    {
        $request->validate([
            'cart_item_id' => 'required|integer|exists:cart_items,id',
        ]);

        $cart = $this->getCart($request);
        $cartItemId = $request->cart_item_id;

        // Direct delete by ID without loading relations
        $cartItem = $cart->items()->find($cartItemId);
        if ($cartItem) {
            $cartItem->delete();
            return response()->json(['success' => true, 'message' => 'Item removed from cart.']);
        }

        return response()->json(['success' => false, 'message' => 'Item not found.'], 404);
    }

    /**
     * Clear all items in the cart.
     */
    public function clear(Request $request)
    {
        $cart = $this->getCart($request);
        $cart->items()->delete();

        return response()->json([
            'success' => true,
            'message' => 'Cart cleared successfully.',
        ]);
    }
}
