<?php
/**
 * NIS2 Agile - RagService
 *
 * Combina EmbedService + VectorService per cercare nella KB multi-livello
 * filtrando per il contesto utente (Migration 012-014).
 */

require_once __DIR__ . '/VectorService.php';
require_once __DIR__ . '/EmbedService.php';

class RagService
{
    private VectorService $vector;
    private EmbedService $embed;

    public function __construct()
    {
        $this->vector = new VectorService();
        $this->embed  = new EmbedService();
    }

    /**
     * Cerca i top-k chunks visibili all'utente.
     *
     * @param array $userContext ['user_id', 'organization_id', 'consulting_firm_id']
     * @return array Lista chunks con title, content, score, scope
     */
    public function searchForUser(string $question, array $userContext, int $topK = 5, float $minScore = 0.28): array
    {
        $vector = $this->embed->embed($question);
        $filter = VectorService::buildAuthzFilter($userContext);
        $hits = $this->vector->search($vector, $filter, $topK, $minScore);

        $out = [];
        foreach ($hits as $h) {
            $p = $h['payload'] ?? [];
            $out[] = [
                'id'      => $h['id'] ?? null,
                'score'   => round($h['score'] ?? 0, 4),
                'title'   => $p['title'] ?? '',
                'content' => $p['chunk'] ?? '',
                'scope'   => $p['scope'] ?? null,
                'source'  => $p['source'] ?? null,
                'lang'    => $p['lang'] ?? 'it',
            ];
        }
        return $out;
    }

    /**
     * Compatta i risultati in un blocco di testo da iniettare nel system prompt Claude.
     */
    public function formatContext(array $hits): string
    {
        if (empty($hits)) return '';
        $blocks = [];
        foreach ($hits as $i => $h) {
            $idx = $i + 1;
            $blocks[] = "[$idx] {$h['title']} (scope={$h['scope']}, score={$h['score']})\n{$h['content']}";
        }
        return implode("\n\n---\n\n", $blocks);
    }
}
