<?php

namespace App\Http\Controllers\Api;

use App\Jobs\ProposeFixForIssue;
use App\Models\Issue;
use App\Services\AuditLogger;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;

class IssueController extends Controller
{
    /**
     * Fleet-wide paginated issue list. Backs the dedicated "Incidents" page
     * and is also used to populate the Issues tab on Server Detail (filtered
     * by ?server_id=).
     */
    public function index(Request $request)
    {
        $perPage = $this->resolvePerPage($request);

        $q = Issue::query()->with(['server:id,hostname,ip_address'])
            ->when($request->filled('server_id'),
                fn ($qb) => $qb->where('server_id', $request->input('server_id')))
            ->when($request->filled('status') && $request->input('status') !== 'all',
                fn ($qb) => $qb->where('status', $request->input('status')))
            ->when($request->filled('severity') && $request->input('severity') !== 'all',
                fn ($qb) => $qb->where('severity', $request->input('severity')))
            ->when($request->filled('source') && $request->input('source') !== 'all',
                fn ($qb) => $qb->where('source_tool', $request->input('source')))
            ->when($request->string('search')->trim()->value(), function ($qb, $s) {
                $qb->where(function ($w) use ($s) {
                    $w->where('title', 'like', "%{$s}%")
                      ->orWhere('cve_id', 'like', "%{$s}%");
                });
            })
            ->orderByDesc('detected_at');

        return response()->json($q->paginate($perPage));
    }

    public function show(Issue $issue)
    {
        return response()->json($issue->load(['server', 'resolvingAction']));
    }

    /**
     * Manually re-trigger AI proposal for an open issue. Used when staff
     * dismissed the original suggestion and now wants a fresh one, or when
     * the issue was initially imported before AI router was enabled.
     */
    public function proposeFix(Request $request, Issue $issue)
    {
        abort_unless($request->user()->canApproveActions(), 403);

        if ($issue->status !== 'open') {
            abort(409, 'Issue must be open to request a fix proposal.');
        }

        ProposeFixForIssue::dispatch($issue->id);

        AuditLogger::log('user', (string) $request->user()->id, $request->user()->email,
            'issue.fix_requested', 'issue', (string) $issue->id, [], $request);

        return response()->json(['queued' => true]);
    }

    public function acknowledge(Request $request, Issue $issue)
    {
        abort_unless($request->user()->canApproveActions(), 403);

        $issue->update(['status' => 'acknowledged']);

        AuditLogger::log('user', (string) $request->user()->id, $request->user()->email,
            'issue.acknowledged', 'issue', (string) $issue->id, [], $request);

        return response()->json($issue->fresh());
    }

    public function dismiss(Request $request, Issue $issue)
    {
        abort_unless($request->user()->canApproveActions(), 403);

        $data = $request->validate(['reason' => ['required', 'string', 'max:500']]);

        $issue->update(['status' => 'wont_fix', 'resolved_at' => now()]);

        AuditLogger::log('user', (string) $request->user()->id, $request->user()->email,
            'issue.dismissed', 'issue', (string) $issue->id,
            ['reason' => $data['reason']], $request);

        return response()->json($issue->fresh());
    }

    private function resolvePerPage(Request $request): int
    {
        $opts = config('hsap.pagination.options', [25, 50, 100]);
        $req  = (int) $request->input('per_page', 25);
        return in_array($req, $opts, true) ? $req : 25;
    }
}
