<?php

namespace App\Http\Controllers;

use App\Http\Requests\AddToCartRequest;
use App\Http\Requests\ApplyCouponRequest;
use App\Http\Requests\UpdateCartRequest;
use App\Services\CartService;
use App\Services\CouponService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class CartController extends Controller
{
    public function __construct(
        protected CartService $cartService,
        protected CouponService $couponService
    ) {
    }

    public function index(Request $request): View
    {
        // Ensure session is started
        if (!$request->hasSession()) {
            \Log::warning('Cart page accessed without session', [
                'url' => $request->fullUrl(),
                'ip' => $request->ip(),
            ]);
        }

        $cart = $this->getCart($request);
        
        // Load variant relationships for cart items
        $cart->load('items.product');
        
        // Recalculate totals to ensure shipping charges are up-to-date from database
        if ($cart->items->isNotEmpty()) {
            $this->cartService->recalculateTotals($cart);
            $cart->refresh();
        }

        // Get available coupons for logged-in user
        $availableCoupons = $this->couponService->getAvailableCoupons(
            auth()->check() ? auth()->user() : null,
            $cart->totals['subtotal'] ?? 0
        );

        return view('cart.index', compact('cart', 'availableCoupons'));
    }

    public function store(AddToCartRequest $request): RedirectResponse
    {
        $cart = $this->getCart($request);
        $productId = $request->validated('product_id');
        $qty = $request->validated('qty', 1);
        $updateExisting = $request->has('update_existing') && $request->input('update_existing') == '1';

        // Check if product is already in cart
        $cartItem = \App\Models\CartItem::where('cart_id', $cart->id)
            ->where('product_id', $productId)
            ->first();

        if ($cartItem && $updateExisting) {
            // Product detail page: update quantity to the specified value
            $updated = $this->cartService->updateItem($cart, $productId, $qty);
            
            if ($updated) {
                return redirect()->back()->with('success', 'Cart updated!');
            }
            
            return redirect()->back()->with('error', 'Unable to update cart. Check stock availability.');
        }

        // Product listing/search pages or new item: add to cart (adds to existing qty if already in cart)
        // Check if adding would exceed the 100 limit
        if ($cartItem) {
            $newQty = $cartItem->qty + $qty;
            if ($newQty > 100) {
                return redirect()->back()->with('error', 'Maximum quantity limit of 100 reached. Cannot add more items.');
            }
        }

        $added = $this->cartService->addItem(
            $cart,
            $productId,
            $qty,
            null // product_variant_id no longer used
        );

        if ($added) {
            return redirect()->back()->with('success', 'Product added to cart!');
        }

        return redirect()->back()->with('error', 'Unable to add product. Check stock availability.');
    }

    public function update(UpdateCartRequest $request, int $productId): RedirectResponse
    {
        $cart = $this->getCart($request);

        $updated = $this->cartService->updateItem(
            $cart,
            $productId,
            $request->validated('qty')
        );

        if ($updated) {
            return redirect()->route('cart.index')->with('success', 'Cart updated!');
        }

        return redirect()->route('cart.index')->with('error', 'Unable to update cart.');
    }

    public function destroy(Request $request, int $productId): RedirectResponse
    {
        $cart = $this->getCart($request);

        $this->cartService->removeItem($cart, $productId);

        return redirect()->route('cart.index')->with('success', 'Item removed from cart.');
    }

    public function applyCoupon(ApplyCouponRequest $request): RedirectResponse|JsonResponse
    {
        $cart = $this->getCart($request);
        $code = $request->validated('code');

        $validation = $this->couponService->validate(
            $code,
            auth()->user(),
            $cart->totals['subtotal'] ?? 0
        );

        // Check if request expects JSON (AJAX/fetch request)
        $wantsJson = $request->expectsJson() 
            || $request->wantsJson() 
            || $request->isJson() 
            || $request->header('Content-Type') === 'application/json'
            || $request->header('X-Requested-With') === 'XMLHttpRequest';

        if (!$validation['valid']) {
            if ($wantsJson) {
                return response()->json([
                    'success' => false,
                    'message' => $validation['error'],
                ], 400);
            }
            return redirect()->route('cart.index')->with('error', $validation['error']);
        }

        $cart->update(['coupon_id' => $validation['coupon']->id]);
        $this->cartService->recalculateTotals($cart);
        $cart->refresh();

        if ($wantsJson) {
            return response()->json([
                'success' => true,
                'message' => 'Coupon applied successfully!',
                'discount' => $cart->totals['discount'] ?? 0,
                'totals' => $cart->totals,
                'coupon' => [
                    'id' => $cart->coupon->id,
                    'code' => $cart->coupon->code,
                ],
            ]);
        }

        return redirect()->route('cart.index')->with('success', 'Coupon applied successfully!');
    }

    public function removeCoupon(Request $request): RedirectResponse
    {
        $cart = $this->getCart($request);
        $cart->update(['coupon_id' => null]);
        $this->cartService->recalculateTotals($cart);

        return redirect()->route('cart.index')->with('success', 'Coupon removed.');
    }

}
