<?php
namespace App\Modules\Search\Controllers;
use App\Http\Controllers\Controller;
use App\Modules\Catalog\Concerns\AppliesProductFilters;
use App\Modules\Catalog\Models\Product;
use App\Modules\Search\Services\SearchService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class SearchController extends Controller
{
use AppliesProductFilters;
public function __construct(private readonly SearchService $searchService) {}
/**
* Full-text product search page — uses Scout (TNTSearch / Meilisearch).
* Falls back to SQL LIKE when the query is empty so the page still shows all products.
*/
public function index(Request $request)
{
$q = trim($request->get('q', ''));
if ($q === '') {
// No query — show all active products (browse mode), same
// sidebar filters as every other listing page.
$query = Product::active()->with(['vendor', 'primaryImage', 'images', 'category', 'media']);
$this->applyProductFilters($query, $request);
$products = $query->paginate(24)->withQueryString();
} else {
$products = $this->searchService->searchProducts($q, $request);
}
$categories = $this->filterSidebarCategories();
$therapeuticCategories = $this->filterSidebarTherapeuticCategories();
return view('search.index', compact('products', 'q', 'categories', 'therapeuticCategories'));
}
/**
* Autocomplete endpoint — returns up to 8 suggestions as JSON.
* Called by the storefront search bar via fetch/axios.
*/
public function autocomplete(Request $request): JsonResponse
{
$q = trim($request->get('q', ''));
if (strlen($q) < 2) {
return response()->json([]);
}
$results = $this->searchService->autocomplete($q);
return response()->json($results);
}
}