<?php

namespace App\Http\Controllers;

use App\Models\Wishlist;
use App\Models\Product;
use Illuminate\Database\QueryException;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\View\View;

class WishlistController extends Controller
{
    /**
     * Display the user's wishlist
     */
    public function index(Request $request): View
    {
        if (!auth()->check()) {
            return redirect()->route('login')->with('error', 'Please login to view your wishlist.');
        }

        $wishlistItems = Wishlist::where('user_id', auth()->id())
            ->with('product.category')
            ->latest()
            ->paginate(10);

        return view('wishlist.index', compact('wishlistItems'));
    }

    /**
     * Add product to wishlist
     */
    public function store(Request $request, int $productId): RedirectResponse
    {
        if (!auth()->check()) {
            return redirect()->route('login')->with('error', 'Please login to add items to wishlist.');
        }

        $product = Product::active()->find($productId);
        
        if (!$product) {
            return redirect()->back()->with('error', 'Product not found.');
        }

        // Check if already in wishlist
        $exists = Wishlist::where('user_id', auth()->id())
            ->where('product_id', $productId)
            ->exists();

        if ($exists) {
            return redirect()->back()->with('info', 'Product is already in your wishlist.');
        }

        Wishlist::create([
            'user_id' => auth()->id(),
            'product_id' => $productId,
        ]);

        // Clear wishlist cache
        \Illuminate\Support\Facades\Cache::forget("wishlist_product_ids." . auth()->id());
        \Illuminate\Support\Facades\Cache::forget("layout.wishlist_count." . auth()->id());

        return redirect()->back()->with('success', 'Product added to wishlist!');
    }

    /**
     * Remove product from wishlist
     */
    public function destroy(Request $request, int $productId): RedirectResponse
    {
        if (!auth()->check()) {
            return redirect()->route('login')->with('error', 'Please login to manage your wishlist.');
        }

        $wishlistItem = Wishlist::where('user_id', auth()->id())
            ->where('product_id', $productId)
            ->first();

        if ($wishlistItem) {
            $wishlistItem->delete();
            
            // Clear wishlist cache
            \Illuminate\Support\Facades\Cache::forget("wishlist_product_ids." . auth()->id());
            \Illuminate\Support\Facades\Cache::forget("layout.wishlist_count." . auth()->id());
            
            return redirect()->back()->with('success', 'Product removed from wishlist.');
        }

        return redirect()->back()->with('error', 'Product not found in wishlist.');
    }

    /**
     * Toggle product in wishlist (AJAX-friendly)
     */
    public function toggle(Request $request, int $productId)
    {
        // Check if request is AJAX/JSON - check multiple ways
        $isAjax = $request->ajax() 
            || $request->expectsJson() 
            || $request->wantsJson()
            || $request->header('X-Requested-With') === 'XMLHttpRequest'
            || str_contains($request->header('Accept', ''), 'application/json');
        
        if (!auth()->check()) {
            if ($isAjax) {
                return response()->json([
                    'error' => 'Please login to add items to wishlist.',
                    'success' => false,
                ], 401, ['Content-Type' => 'application/json']);
            }
            return redirect()->route('login')->with('error', 'Please login to manage your wishlist.');
        }

        $product = Product::active()->find($productId);
        
        if (!$product) {
            if ($isAjax) {
                return response()->json([
                    'error' => 'Product not found.',
                    'success' => false,
                ], 404, ['Content-Type' => 'application/json']);
            }
            return redirect()->back()->with('error', 'Product not found.');
        }

        try {
            // Check if item exists
            $wishlistItem = Wishlist::where('user_id', auth()->id())
                ->where('product_id', $productId)
                ->first();

            if ($wishlistItem) {
                // Item exists, remove it
                $wishlistItem->delete();
                $message = 'Product removed from wishlist.';
                $inWishlist = false;
                
                // Clear wishlist cache
                \Illuminate\Support\Facades\Cache::forget("wishlist_product_ids." . auth()->id());
                \Illuminate\Support\Facades\Cache::forget("layout.wishlist_count." . auth()->id());
            } else {
                // Item doesn't exist, try to create it
                // Use create() and catch duplicate entry exceptions
                try {
                    Wishlist::create([
                        'user_id' => auth()->id(),
                        'product_id' => $productId,
                    ]);
                    $message = 'Product added to wishlist!';
                    $inWishlist = true;
                    
                    // Clear wishlist cache
                    \Illuminate\Support\Facades\Cache::forget("wishlist_product_ids." . auth()->id());
                    \Illuminate\Support\Facades\Cache::forget("layout.wishlist_count." . auth()->id());
                } catch (QueryException $e) {
                    // Handle duplicate entry error (race condition)
                    // SQLSTATE 23000 = Integrity constraint violation
                    // Error code 1062 = Duplicate entry
                    $errorCode = $e->getCode();
                    $errorMessage = $e->getMessage();
                    $sqlState = $e->errorInfo[0] ?? null;
                    $driverCode = $e->errorInfo[1] ?? null;
                    
                    // Check for duplicate entry in multiple ways
                    // SQLSTATE 23000 = Integrity constraint violation
                    // Error code 1062 = Duplicate entry for unique key
                    $isDuplicate = ($errorCode == 23000 || $sqlState == '23000') 
                        && ($driverCode == 1062 || str_contains($errorMessage, 'Duplicate entry') || str_contains($errorMessage, '1062') || str_contains($errorMessage, 'wishlists_user_id_product_id_unique'));
                    
                    // If it's an integrity constraint violation, treat as duplicate and check
                    if ($isDuplicate || ($errorCode == 23000 || $sqlState == '23000')) {
                        // Duplicate entry - item was just added by another request
                        // This is fine - just confirm it exists now
                        $wishlistItem = Wishlist::where('user_id', auth()->id())
                            ->where('product_id', $productId)
                            ->first();
                        if ($wishlistItem) {
                            $message = 'Product added to wishlist!';
                            $inWishlist = true;
                        } else {
                            // This shouldn't happen, but log and treat as success
                            \Log::warning('Wishlist duplicate entry but item not found after', [
                                'user_id' => auth()->id(),
                                'product_id' => $productId,
                                'error_code' => $errorCode,
                                'sql_state' => $sqlState,
                                'driver_code' => $driverCode,
                            ]);
                            $message = 'Product added to wishlist!';
                            $inWishlist = true;
                        }
                    } else {
                        // Re-throw if it's a different error
                        \Log::error('Wishlist create failed with non-duplicate error', [
                            'error_code' => $errorCode,
                            'sql_state' => $sqlState,
                            'driver_code' => $driverCode,
                            'message' => $errorMessage,
                        ]);
                        throw $e;
                    }
                }
            }

            if ($isAjax) {
                $wishlistCount = Wishlist::where('user_id', auth()->id())->count();
                return response()->json([
                    'success' => true,
                    'message' => $message,
                    'in_wishlist' => $inWishlist,
                    'wishlist_count' => $wishlistCount,
                ], 200, ['Content-Type' => 'application/json']);
            }

            return redirect()->back()->with('success', $message);
        } catch (\Exception $e) {
            \Log::error('Wishlist toggle error: ' . $e->getMessage(), [
                'exception' => get_class($e),
                'code' => $e->getCode(),
                'file' => $e->getFile(),
                'line' => $e->getLine(),
                'trace' => $e->getTraceAsString(),
            ]);
            
            if ($isAjax) {
                return response()->json([
                    'error' => 'An error occurred while updating wishlist. Please try again.',
                    'success' => false,
                    'debug' => config('app.debug') ? $e->getMessage() : null,
                ], 500, ['Content-Type' => 'application/json']);
            }
            
            return redirect()->back()->with('error', 'An error occurred. Please try again.');
        }
    }
}
