<?php

namespace App\Http\Controllers\Api;

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

class ProductController extends Controller
{
    private function baseQuery()
    {
        return Product::with(['categories', 'primaryImage', 'activeLabReport'])
            ->withCount('variants')
            ->where('status', 'active');
    }

    public function index(Request $request): JsonResponse
    {
        $query = $this->baseQuery();

        if ($request->filled('category')) {
            $query->whereHas('categories', fn($q) => $q->where('slug', $request->category));
        }

        if ($request->filled('min_price')) {
            $query->where('price', '>=', $request->min_price);
        }

        if ($request->filled('max_price')) {
            $query->where('price', '<=', $request->max_price);
        }

        if ($request->filled('in_stock')) {
            $query->where(function ($q) {
                $q->where('track_stock', false)
                  ->orWhere('stock_quantity', '>', 0);
            });
        }

        if ($request->filled('search')) {
            $term = '%' . $request->search . '%';
            $query->where(function ($q) use ($term) {
                $q->where('name', 'like', $term)
                  ->orWhere('description', 'like', $term)
                  ->orWhere('short_description', 'like', $term);
            });
        }

        if ($request->filled('featured')) {
            $query->where('is_featured', true);
        }

        if ($request->filled('bestseller')) {
            $query->where('is_bestseller', true);
        }

        $sort = $request->get('sort', 'newest');
        match ($sort) {
            'price_asc' => $query->orderBy('price', 'asc'),
            'price_desc' => $query->orderBy('price', 'desc'),
            'name_asc' => $query->orderBy('name', 'asc'),
            default => $query->orderBy('created_at', 'desc'),
        };

        $products = $query->paginate($request->get('per_page', 12));

        return response()->json([
            'data' => ProductResource::collection($products),
            'meta' => [
                'current_page' => $products->currentPage(),
                'last_page' => $products->lastPage(),
                'per_page' => $products->perPage(),
                'total' => $products->total(),
            ],
        ]);
    }

    public function show(string $slug): JsonResponse
    {
        $product = Cache::remember("product.{$slug}", 300, function () use ($slug) {
            return Product::with([
                'categories',
                'variants',
                'images',
                'primaryImage',
                'activeLabReport',
                'labReports',
            ])
            ->where('slug', $slug)
            ->where('status', 'active')
            ->firstOrFail();
        });

        return response()->json(['data' => new ProductResource($product)]);
    }

    public function featured(): JsonResponse
    {
        $products = Cache::remember('products.featured', 300, function () {
            return $this->baseQuery()
                ->where('is_featured', true)
                ->limit(8)
                ->get();
        });

        return response()->json(['data' => ProductResource::collection($products)]);
    }

    public function bestsellers(): JsonResponse
    {
        $products = Cache::remember('products.bestsellers', 300, function () {
            return $this->baseQuery()
                ->where('is_bestseller', true)
                ->limit(8)
                ->get();
        });

        return response()->json(['data' => ProductResource::collection($products)]);
    }

    public function search(Request $request): JsonResponse
    {
        $request->validate(['q' => 'required|string|min:2|max:100']);

        $q = $request->q;
        $products = $this->baseQuery()
            ->where(function ($query) use ($q) {
                $query->where('name', 'like', "%{$q}%")
                      ->orWhere('short_description', 'like', "%{$q}%")
                      ->orWhere('description', 'like', "%{$q}%");
            })
            ->limit(20)
            ->get();

        return response()->json(['data' => ProductResource::collection($products)]);
    }
}
