"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.create = create;
const language_core_1 = require("@vue/language-core");
const utils_1 = require("../utils");
function create(ts) {
    return {
        name: 'vue-suggest-define-assignment',
        capabilities: {
            completionProvider: {},
        },
        create(context) {
            return {
                isAdditionalCompletion: true,
                async provideCompletionItems(document, position) {
                    const info = (0, utils_1.resolveEmbeddedCode)(context, document.uri);
                    if (!info?.code.id.startsWith('script_')) {
                        return;
                    }
                    const enabled = await context.env.getConfiguration?.('vue.suggest.defineAssignment') ?? true;
                    if (!enabled) {
                        return;
                    }
                    const { ir } = info.root;
                    const codegen = language_core_1.tsCodegen.get(ir);
                    const scriptSetup = ir.scriptSetup;
                    const scriptSetupRanges = codegen?.getScriptSetupRanges();
                    if (!scriptSetup || !scriptSetupRanges) {
                        return;
                    }
                    const map = context.language.maps.get(info.code, info.script);
                    let sourceOffset;
                    for (const [offset] of map.toSourceLocation(document.offsetAt(position))) {
                        sourceOffset = offset;
                        break;
                    }
                    if (sourceOffset === undefined) {
                        return;
                    }
                    const node = ts.getTouchingPropertyName(scriptSetup.ast, sourceOffset - scriptSetup.startTagEnd);
                    if (ts.isStringLiteralLike(node)) {
                        return;
                    }
                    const result = [];
                    addDefineCompletionItem(scriptSetupRanges.defineProps?.statement, scriptSetupRanges.withDefaults?.exp ?? scriptSetupRanges.defineProps?.exp, 'props');
                    addDefineCompletionItem(scriptSetupRanges.defineEmits?.statement, scriptSetupRanges.defineEmits?.exp, 'emit');
                    addDefineCompletionItem(scriptSetupRanges.defineSlots?.statement, scriptSetupRanges.defineSlots?.exp, 'slots');
                    return {
                        isIncomplete: false,
                        items: result,
                    };
                    function addDefineCompletionItem(statement, exp, name) {
                        if (!exp || exp.start !== statement?.start) {
                            return;
                        }
                        let generatedOffset;
                        for (const [offset] of map.toGeneratedLocation(scriptSetup.startTagEnd + exp.start)) {
                            generatedOffset = offset;
                            break;
                        }
                        if (generatedOffset === undefined) {
                            return;
                        }
                        const pos = document.positionAt(generatedOffset);
                        result.push({
                            label: name,
                            kind: 6,
                            commitCharacters: ['.', ',', ';'],
                            additionalTextEdits: [{
                                    newText: `const ${name} = `,
                                    range: {
                                        start: pos,
                                        end: pos,
                                    },
                                }],
                        });
                    }
                },
            };
        },
    };
}
//# sourceMappingURL=vue-suggest-define-assignment.js.map