/**
 * Annotation completion provider for Acurity Architect.
 *
 * Offers completions for comment annotations when the user types `@` inside a `//` comment line:
 *   @mode:strict / @mode:legacy / @mode:default  — set the validation profile for this file
 *   @rule-ignore                                  — suppress a specific rule on the following line
 *
 * Only active when `acurity.code-completion` is enabled.
 */

import * as vscode from "vscode";
import { LANGUAGE_ID } from "../../core/src/constants.js";

const ANNOTATION_COMPLETIONS = [
    {
        label:      "@mode:strict",
        detail:     "Set strict validation profile for this file",
        documentation: new vscode.MarkdownString(
            "Activates the **strict** validation profile for this file.\n\n" +
            "Place in the first non-blank lines of the file.\n\n" +
            "```\n// @mode:strict\n```"
        ),
        insertText: "@mode:strict",
        sortText:   "0_mode_strict"
    },
    {
        label:      "@mode:legacy",
        detail:     "Set legacy validation profile for this file",
        documentation: new vscode.MarkdownString(
            "Activates the **legacy** validation profile for this file.\n\n" +
            "Place in the first non-blank lines of the file.\n\n" +
            "```\n// @mode:legacy\n```"
        ),
        insertText: "@mode:legacy",
        sortText:   "0_mode_legacy"
    },
    {
        label:      "@mode:default",
        detail:     "Set default validation profile for this file",
        documentation: new vscode.MarkdownString(
            "Activates the **default** validation profile for this file.\n\n" +
            "Place in the first non-blank lines of the file.\n\n" +
            "```\n// @mode:default\n```"
        ),
        insertText: "@mode:default",
        sortText:   "0_mode_default"
    },
    {
        label:      "@rule-ignore",
        detail:     "Suppress a specific rule on the next line",
        documentation: new vscode.MarkdownString(
            "Suppresses one or more diagnostic rules on the **immediately following line**.\n\n" +
            "```\n// @rule-ignore ACU-VAR-001 REASON: intentional\nnAffectedLine\n```\n\n" +
            "Multiple rule IDs can be space-separated. Include a `REASON:` clause to document why."
        ),
        insertText: new vscode.SnippetString("@rule-ignore ${1:ACU-XXX-000} REASON: ${2:explanation}"),
        sortText:   "0_rule_ignore"
    }
];

/** @type {vscode.CompletionItem[] | null} */
let cachedItems = null;

function buildCompletionItems() {
    if (cachedItems) return cachedItems;
    cachedItems = ANNOTATION_COMPLETIONS.map((def) => {
        const item = new vscode.CompletionItem(def.label, vscode.CompletionItemKind.Keyword);
        item.detail        = def.detail;
        item.documentation = def.documentation;
        item.insertText    = def.insertText;
        item.sortText      = def.sortText;
        return item;
    });
    return cachedItems;
}

/**
 * @param {vscode.TextDocument} document
 * @param {vscode.Position} position
 * @returns {vscode.CompletionItem[] | null}
 */
function provideAnnotationCompletions(document, position) {
    if (!vscode.workspace.getConfiguration("acurity").get("code-completion", true)) {
        return null;
    }

    const lineText   = document.lineAt(position.line).text;
    const linePrefix = lineText.slice(0, position.character);

    // Only fire inside a comment line: starts with optional whitespace then //
    if (!/^\s*\/\//.test(linePrefix)) return null;

    // Extract the prefix being typed after the last @
    const atIndex = linePrefix.lastIndexOf("@");
    if (atIndex === -1) return null;
    const typedAfterAt = linePrefix.slice(atIndex + 1);

    const items = buildCompletionItems();
    const lower = typedAfterAt.toLowerCase();
    return items.filter((item) => item.label.slice(1).toLowerCase().startsWith(lower));
}

/**
 * @param {vscode.ExtensionContext} context
 */
function initializeAnnotationCompletionProvider(context) {
    context.subscriptions.push(
        vscode.languages.registerCompletionItemProvider(
            LANGUAGE_ID,
            { provideCompletionItems: provideAnnotationCompletions },
            "@"
        )
    );
}

export { initializeAnnotationCompletionProvider, provideAnnotationCompletions, buildCompletionItems };
