<?php
/**
 * NIS2 Agile - EmbedService
 *
 * Client minimale per Voyage AI embeddings (voyage-3-lite, 1024 dim).
 */

class EmbedService
{
    public int $dims = 512;
    private string $apiKey;
    private string $model;

    public function __construct()
    {
        // PHP-FPM Alpine non popola env via getenv() (clear_env). Multi-source lookup.
        // La chiave vive in .env (gitignored) + vault-steward; nessun segreto hardcoded.
        $this->apiKey = getenv('VOYAGE_API_KEY')
            ?: ($_SERVER['VOYAGE_API_KEY'] ?? '')
            ?: ($_ENV['VOYAGE_API_KEY'] ?? '')
            ?: (class_exists('Env') ? Env::get('VOYAGE_API_KEY', '') : '');
        $this->model = getenv('VOYAGE_MODEL')
            ?: ($_SERVER['VOYAGE_MODEL'] ?? null)
            ?: ($_ENV['VOYAGE_MODEL'] ?? null)
            ?: 'voyage-3-lite';
        if (empty($this->apiKey)) {
            throw new RuntimeException('VOYAGE_API_KEY non configurata');
        }
    }

    /**
     * @return float[] Vettore embedding 1024-dim
     */
    public function embed(string $text): array
    {
        $ch = curl_init('https://api.voyageai.com/v1/embeddings');
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST           => true,
            CURLOPT_HTTPHEADER     => [
                'Content-Type: application/json',
                'Authorization: Bearer ' . $this->apiKey,
            ],
            CURLOPT_POSTFIELDS     => json_encode([
                'input'            => [$text],
                'model'            => $this->model,
                'input_type'       => 'document',
                'output_dimension' => 512,
            ]),
            CURLOPT_TIMEOUT        => 30,
        ]);
        $raw = curl_exec($ch);
        $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($status !== 200 || !$raw) {
            throw new RuntimeException("Voyage embed failed (HTTP $status): " . substr((string)$raw, 0, 200));
        }
        $data = json_decode($raw, true);
        $vec = $data['data'][0]['embedding'] ?? null;
        if (!is_array($vec)) {
            throw new RuntimeException('Voyage response without embedding: ' . substr($raw, 0, 200));
        }
        return $vec;
    }
}
