/**
 * Code Lens provider for Acurity Architect index operations.
 *
 * Feature 6 — INDEX_OPEN_STANDARD code lens:
 *   Emits an always-visible inline annotation above each INDEX_OPEN_STANDARD
 *   call whose table code and index name are string literals.  The lens shows
 *   the table name, index name, segment count, and the field names in order.
 *
 *   Example:
 *     RA (Remittance_Advice) · Index "0" · 5 segments: RAz_Division, RAz_Fund, …
 */

import * as vscode from "vscode";
import { LANGUAGE_ID } from "../../core/src/constants.js";
import { extractArgAt } from "../../core/src/parser.js";
import { getTableStructure } from "../../core/src/builtins/tableStructureRegistry.js";
import { getTableEntry } from "../../core/src/builtins/tableSynonymsRegistry.js";

/** Regex that matches an INDEX_OPEN_STANDARD or SQL_INDEX_OPEN_STANDARD call anywhere on a line. */
const INDEX_OPEN_RE = /\b(?:SQL_)?INDEX_OPEN_STANDARD\s*\(/i;

/**
 * Scans the document and returns Code Lens objects for each
 * INDEX_OPEN_STANDARD / SQL_INDEX_OPEN_STANDARD call with resolvable literal arguments.
 *
 * @param {vscode.TextDocument} document
 * @returns {Promise<vscode.CodeLens[]>}
 */
async function provideIndexCodeLenses(document) {
    const lenses = [];

    for (let lineIndex = 0; lineIndex < document.lineCount; lineIndex++) {
        const lineText = document.lineAt(lineIndex).text;
        const m = INDEX_OPEN_RE.exec(lineText);
        if (!m) continue;

        const callExpr = lineText.slice(m.index);
        const tableArg = extractArgAt(callExpr, 0);
        const indexArg = extractArgAt(callExpr, 1);

        if (!tableArg || !indexArg) continue;

        const tableMatch = tableArg.trim().match(/^["']([^"']+)["']$/);
        if (!tableMatch) continue;

        const tableCode = tableMatch[1].toUpperCase();
        const indexName = indexArg.trim().replace(/^["']|["']$/g, "");

        const structure = await getTableStructure(tableCode);
        if (!structure) continue;

        const index = structure.indexes.find(idx => idx.name === indexName);
        if (!index) continue;

        const te = getTableEntry(tableCode);
        const tableLabel = te ? `${tableCode} (${te.name})` : tableCode;
        const fieldList = index.segments.map(s => s.field).join(", ");
        const segCount = index.segments.length;

        const title = `${tableLabel} · Index "${indexName}" · ${segCount} segment${segCount !== 1 ? "s" : ""}: ${fieldList}`;
        const range = new vscode.Range(lineIndex, 0, lineIndex, lineText.length);

        lenses.push(new vscode.CodeLens(range, { title, command: "" }));
    }

    return lenses;
}

/**
 * Initializes the Code Lens provider.
 * @param {vscode.ExtensionContext} context
 */
function initializeCodeLensProvider(context) {
    const provider = vscode.languages.registerCodeLensProvider(
        LANGUAGE_ID,
        {
            provideCodeLenses(document) {
                return provideIndexCodeLenses(document);
            }
        }
    );

    context.subscriptions.push(provider);
}

export { initializeCodeLensProvider };
