<?php

declare(strict_types=1);

namespace App\Ingest;

use App\Index\IndexMetaManager;
use App\Knowledge\ChunkManager;
use App\Knowledge\Retrieval\NdjsonLexicalIndexBuilder;
use App\Vector\VectorIndexBuilder;

final readonly class VectorRebuildService
{
    public function __construct(
        private VectorIndexBuilder $vectorBuilder,
        private NdjsonLexicalIndexBuilder $lexicalIndexBuilder,
        private IndexMetaManager $metaManager,
        private ChunkManager $chunkManager,
    ) {
    }

    /**
     * Executes a full deterministic rebuild of all derived retrieval artifacts.
     *
     * Flow:
     * 1. Ensure index_meta.json exists
     * 2. Rebuild vector index from index.ndjson
     * 3. Rebuild lexical index from index.ndjson
     * 4. Count chunks streaming-safe
     * 5. Update runtime stats atomically
     *
     * Important:
     * - Vector and lexical index are both derived from the same NDJSON source
     * - rebuilding both here prevents drift between semantic and lexical retrieval layers
     * - failures in either derived artifact should fail the rebuild as a whole
     * @throws \Throwable
     */
    public function rebuild(?string $logPath = null): void
    {
        // Ensure metadata exists before derived index work starts.
        $this->metaManager->ensureExists();

        // 1) Rebuild semantic vector index.
        $this->vectorBuilder->rebuildFromNdjson($logPath);

        // 2) Rebuild generic lexical index from the same NDJSON source.
        $this->lexicalIndexBuilder->build();

        // 3) Count chunks streaming-safe.
        $chunkCount = $this->chunkManager->countAllChunks();

        // 4) Update runtime stats atomically.
        $this->metaManager->updateRuntimeStats($chunkCount);
    }
}