<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Incident;
use App\Models\Runbook;
use App\Models\Server;
use App\Models\Website;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

/**
 * One search bar to rule them all. Hits indexed columns across the most
 * common resource types and returns a unified result list.
 *
 * Resources searched:
 *   - Servers (name, hostname, ip, tags)
 *   - Websites (name, url)
 *   - Incidents (public_id, title)
 *   - Runbooks (title, tags)
 *
 * Result format is uniform across types so the frontend can render a single
 * dropdown:
 *   { type: 'server', id: 42, label: 'web-01', subtitle: '1.2.3.4', icon: 'server' }
 *
 * We DON'T do fuzzy/full-text search here — just LIKE matching on indexed
 * columns. That's fast and predictable. For more sophisticated search we'd
 * add Meilisearch/Typesense, but most queries are exact-name lookups.
 */
class GlobalSearchController extends Controller
{
    /**
     * GET /api/search?q=web&limit=10
     *
     * Query rules:
     *   - q must be at least 2 characters (to avoid huge result sets)
     *   - limit defaults to 8 per resource type (32 total max)
     */
    public function index(Request $request): JsonResponse
    {
        $q = trim((string) $request->query('q', ''));
        if (strlen($q) < 2) {
            return response()->json(['results' => [], 'message' => 'Type at least 2 characters.']);
        }

        $perType = max(1, min(20, (int) $request->query('limit', 8)));
        $like = '%' . str_replace(['%', '_'], ['\%', '\_'], $q) . '%';

        $results = [];

        // Servers — search by name, hostname, ip
        $servers = Server::where(function ($qq) use ($like) {
            $qq->where('name', 'like', $like)
               ->orWhere('hostname', 'like', $like)
               ->orWhere('ip', 'like', $like);
        })->limit($perType)->get(['id', 'name', 'hostname', 'ip', 'status', 'consensus_status']);

        foreach ($servers as $s) {
            $results[] = [
                'type' => 'server',
                'id' => $s->id,
                'label' => $s->name,
                'subtitle' => $s->ip ? "{$s->hostname} · {$s->ip}" : $s->hostname,
                'status' => $s->status,
                'consensus_status' => $s->consensus_status,
            ];
        }

        // Websites — search by name, url
        $websites = Website::where(function ($qq) use ($like) {
            $qq->where('name', 'like', $like)
               ->orWhere('url', 'like', $like);
        })->limit($perType)->get(['id', 'name', 'url', 'status']);

        foreach ($websites as $w) {
            $results[] = [
                'type' => 'website',
                'id' => $w->id,
                'label' => $w->name,
                'subtitle' => $w->url,
                'status' => $w->status,
            ];
        }

        // Incidents — public_id is the most common search target ("HS-INC-42")
        $incidents = Incident::where(function ($qq) use ($like) {
            $qq->where('public_id', 'like', $like)
               ->orWhere('title', 'like', $like);
        })->limit($perType)->get(['id', 'public_id', 'title', 'status', 'severity']);

        foreach ($incidents as $i) {
            $results[] = [
                'type' => 'incident',
                'id' => $i->id,
                'label' => "{$i->public_id} — {$i->title}",
                'subtitle' => "Severity: {$i->severity} · {$i->status}",
                'status' => $i->status,
            ];
        }

        // Runbooks — operators searching for "ssh restart" or similar
        $runbooks = Runbook::where('title', 'like', $like)->limit($perType)->get(['id', 'title', 'detector_key']);
        foreach ($runbooks as $rb) {
            $results[] = [
                'type' => 'runbook',
                'id' => $rb->id,
                'label' => $rb->title,
                'subtitle' => $rb->detector_key ?: 'Runbook',
            ];
        }

        return response()->json([
            'query' => $q,
            'count' => count($results),
            'results' => $results,
        ]);
    }
}
