// Copyright (c) 2025-2026 GeWuYou
// SPDX-License-Identifier: Apache-2.0

const {ValidationMessageKeys} = require("./localizationKeys");

/**
 * Create a tiny in-process localizer for the extension runtime and webview.
 * VS Code contribution points use package.nls files, while runtime strings are
 * resolved here so the preview panel and prompts stay readable for both
 * Simplified Chinese and English users.
 *
 * @param {string | undefined} language VS Code UI language.
 * @returns {{languageTag: string, isChinese: boolean, t: (key: string, params?: Record<string, string | number>) => string}} Localizer.
 */
function createLocalizer(language) {
    const normalizedLanguage = String(language || "en").toLowerCase();
    const isChinese = normalizedLanguage.startsWith("zh");
    const isTraditionalChinese =
        normalizedLanguage === "zh-tw" ||
        normalizedLanguage === "zh-hk" ||
        normalizedLanguage === "zh-mo" ||
        normalizedLanguage.startsWith("zh-hant");
    const isSimplifiedChinese = isChinese && !isTraditionalChinese;
    const languageTag = isTraditionalChinese
        ? normalizedLanguage
        : isSimplifiedChinese
            ? "zh-CN"
            : "en";
    const dictionary = isTraditionalChinese
        ? enMessages
        : isSimplifiedChinese
            ? zhCnMessages
            : enMessages;

    return {
        languageTag,
        isChinese: isSimplifiedChinese,
        t(key, params) {
            const template = dictionary[key] || enMessages[key] || key;
            return template.replace(/\{([A-Za-z0-9_]+)\}/gu, (match, token) => {
                if (!params || !Object.prototype.hasOwnProperty.call(params, token)) {
                    return match;
                }

                return String(params[token]);
            });
        }
    };
}

const enMessages = {
    "tree.noConfigDirectory.label": "No config directory",
    "tree.noConfigDirectory.description": "Set gframeworkConfig.configPath or create the directory.",
    "tree.fileDescription.schema": "schema",
    "tree.fileDescription.schemaMissing": "schema missing",
    "command.openRaw.title": "Open Raw",
    "message.schemaNotFound": "Matching schema file was not found.",
    "message.formSaved": "Config file saved from form preview.",
    "message.formInitialized": "Example config initialized from the schema.",
    "message.initializeFromSchemaConfirm": "Initializing from the schema will replace the current configuration and may discard unsaved form changes. Do you want to continue?",
    "message.noYamlFilesInDomain": "No YAML config files were found in the selected domain.",
    "message.batchEditNeedsSchema": "Batch edit requires a matching schema file for the selected domain.",
    "message.batchEditNoEditableFields": "No top-level scalar or scalar-array fields were found in the matching schema.",
    "message.batchEditNoChanges": "Batch edit did not change any selected config files.",
    "message.batchEditUpdated": "Batch updated {count} config file(s) in '{domain}'.",
    "message.referenceSchemaMissing": "The referenced schema '{refTable}.schema.json' was not found.",
    "message.referenceDomainMissing": "The referenced config domain '{refTable}' was not found.",
    "message.referenceValueMissing": "The referenced config '{refValue}' was not found in '{refTable}'.",
    "diagnostic.schemaMissing": "Matching schema file not found: {schemaPath}",
    "quickPick.batchEdit.title": "Batch Edit: {domain}",
    "quickPick.batchEdit.placeholder": "Select the config files to update.",
    "quickPick.batchEditFields.title": "Batch Edit Fields: {domain}",
    "quickPick.batchEditFields.placeholder": "Select the fields to apply across the chosen files.",
    "detail.required": "required",
    "detail.refTable": "ref: {refTable}",
    "detail.arrayType": "array<{itemType}>",
    "detail.default": "default",
    "button.cancel": "Cancel",
    "button.initializeFromSchemaConfirm": "Initialize from schema",
    "input.batchArray.title": "Batch Edit Array: {field}",
    "input.batchArray.prompt": "Enter comma-separated items for '{fieldKey}' (expected array<{itemType}>). Leave empty to clear the array.",
    "input.batchArray.placeholder.allowedItems": "Allowed items: {values}",
    "input.batchArray.placeholder.default": "Default: {value}",
    "quickPick.batchField.title": "Batch Edit Field: {field}",
    "quickPick.batchField.placeholder": "Select a value for '{fieldKey}'.",
    "input.batchField.title": "Batch Edit Field: {field}",
    "input.batchField.prompt": "Enter the new value for '{fieldKey}' (expected {type}).",
    "input.batchField.placeholder.refTable": "Ref table: {refTable}",
    "webview.panelTitle": "Config Form: {fileName}",
    "webview.meta.file": "File: {fileName}",
    "webview.meta.schema": "Schema: {schemaPath}",
    "webview.meta.schemaMissing": "Schema missing: {schemaPath}",
    "webview.emptyState": "No editable schema-bound fields were detected. Use raw YAML for unsupported shapes.",
    "webview.button.save": "Save Form",
    "webview.button.openRaw": "Open Raw YAML",
    "webview.button.initialize": "Initialize Example",
    "webview.badge.required": "required",
    "webview.help.summary": "Edit values, comments, and references here. Use raw YAML when you need unsupported structures or exact formatting control.",
    "webview.comment.label": "YAML comment",
    "webview.ref.openSchema": "Open Ref Schema",
    "webview.ref.openDomain": "Open Ref Domain",
    "webview.ref.openValue": "Open Ref File",
    "webview.objectArray.item": "Item",
    "webview.objectArray.itemNumber": "Item {index}",
    "webview.objectArray.hint": "Each item uses the object schema below.",
    "webview.objectArray.add": "Add Item",
    "webview.objectArray.remove": "Remove",
    "webview.array.hint": "One item per line. Expected type: {itemType}",
    "webview.hint.default": "Default: {value}",
    "webview.hint.const": "Const: {value}",
    "webview.hint.allowed": "Allowed: {values}",
    "webview.hint.minimum": "Minimum: {value}",
    "webview.hint.exclusiveMinimum": "Exclusive minimum: {value}",
    "webview.hint.maximum": "Maximum: {value}",
    "webview.hint.exclusiveMaximum": "Exclusive maximum: {value}",
    "webview.hint.multipleOf": "Multiple of: {value}",
    "webview.hint.minLength": "Min length: {value}",
    "webview.hint.maxLength": "Max length: {value}",
    "webview.hint.pattern": "Pattern: {value}",
    "webview.hint.format": "Format: {value}",
    "webview.hint.minItems": "Min items: {value}",
    "webview.hint.maxItems": "Max items: {value}",
    "webview.hint.contains": "Contains: {summary}",
    "webview.hint.minContains": "Min contains: {value}",
    "webview.hint.maxContains": "Max contains: {value}",
    "webview.hint.uniqueItems": "Items must be unique",
    "webview.hint.required": "Required: {properties}",
    "webview.hint.itemMinimum": "Item minimum: {value}",
    "webview.hint.itemConst": "Item const: {value}",
    "webview.hint.itemExclusiveMinimum": "Item exclusive minimum: {value}",
    "webview.hint.itemMaximum": "Item maximum: {value}",
    "webview.hint.itemExclusiveMaximum": "Item exclusive maximum: {value}",
    "webview.hint.itemMultipleOf": "Item multiple of: {value}",
    "webview.hint.itemMinLength": "Item min length: {value}",
    "webview.hint.itemMaxLength": "Item max length: {value}",
    "webview.hint.itemPattern": "Item pattern: {value}",
    "webview.hint.itemFormat": "Item format: {value}",
    "webview.hint.minProperties": "Min properties: {value}",
    "webview.hint.maxProperties": "Max properties: {value}",
    "webview.hint.dependentRequired": "When {trigger} is set: require {dependencies}",
    "webview.hint.dependentSchemas": "When {trigger} is set: satisfy {schema}",
    "webview.hint.allOf": "Also satisfy: {schema}",
    "webview.hint.ifThen": "When {condition}: satisfy {schema}",
    "webview.hint.ifElse": "Otherwise (when {condition} does not match): satisfy {schema}",
    "webview.hint.refTable": "Ref table: {refTable}",
    "webview.unsupported.array": "Unsupported array shapes are currently raw-YAML-only in the form preview.",
    "webview.unsupported.type": "{type} fields are currently raw-YAML-only.",
    "webview.unsupported.objectArrayMixed": "Object-array items must be mappings. Use raw YAML if the current file mixes scalar and object items.",
    "webview.unsupported.nestedObjectArray": "Nested object-array fields are currently raw-YAML-only inside the object-array editor.",
    [ValidationMessageKeys.allOfViolation]: "Object '{displayPath}' must satisfy all 'allOf' schemas; entry #{index} did not match.",
    [ValidationMessageKeys.constMismatch]: "Property '{displayPath}' must match constant value {value}.",
    [ValidationMessageKeys.dependentRequiredViolation]: "Property '{displayPath}' is required when sibling property '{triggerProperty}' is present.",
    [ValidationMessageKeys.dependentSchemasViolation]: "Object '{displayPath}' must satisfy the dependent schema triggered by sibling property '{triggerProperty}'.",
    [ValidationMessageKeys.elseViolation]: "Object '{displayPath}' must satisfy the 'else' schema because the inline 'if' condition did not match.",
    [ValidationMessageKeys.exclusiveMaximumViolation]: "Property '{displayPath}' must be less than {value}.",
    [ValidationMessageKeys.exclusiveMinimumViolation]: "Property '{displayPath}' must be greater than {value}.",
    [ValidationMessageKeys.maximumViolation]: "Property '{displayPath}' must be less than or equal to {value}.",
    [ValidationMessageKeys.maxContainsViolation]: "Property '{displayPath}' must contain at most {value} items matching the 'contains' schema.",
    [ValidationMessageKeys.maxItemsViolation]: "Property '{displayPath}' must contain at most {value} items.",
    [ValidationMessageKeys.maxLengthViolation]: "Property '{displayPath}' must be at most {value} characters long.",
    [ValidationMessageKeys.maxPropertiesViolation]: "Property '{displayPath}' must contain at most {value} properties.",
    [ValidationMessageKeys.minimumViolation]: "Property '{displayPath}' must be greater than or equal to {value}.",
    [ValidationMessageKeys.multipleOfViolation]: "Property '{displayPath}' must be a multiple of {value}.",
    [ValidationMessageKeys.notViolation]: "Property '{displayPath}' must not match the forbidden 'not' schema.",
    [ValidationMessageKeys.thenViolation]: "Object '{displayPath}' must satisfy the 'then' schema because the inline 'if' condition matched.",
    [ValidationMessageKeys.minContainsViolation]: "Property '{displayPath}' must contain at least {value} items matching the 'contains' schema.",
    [ValidationMessageKeys.minItemsViolation]: "Property '{displayPath}' must contain at least {value} items.",
    [ValidationMessageKeys.minLengthViolation]: "Property '{displayPath}' must be at least {value} characters long.",
    [ValidationMessageKeys.minPropertiesViolation]: "Property '{displayPath}' must contain at least {value} properties.",
    [ValidationMessageKeys.patternViolation]: "Property '{displayPath}' must match pattern '{value}'.",
    [ValidationMessageKeys.uniqueItemsViolation]: "Property '{displayPath}' duplicates earlier array item '{duplicatePath}', but uniqueItems is required.",
    [ValidationMessageKeys.enumMismatch]: "Property '{displayPath}' must be one of: {values}.",
    [ValidationMessageKeys.expectedArray]: "Property '{displayPath}' is expected to be an array.",
    [ValidationMessageKeys.expectedScalarShape]: "Property '{displayPath}' is expected to be '{schemaType}', but the current YAML shape is '{yamlKind}'.",
    [ValidationMessageKeys.expectedScalarValue]: "Property '{displayPath}' is expected to be '{schemaType}', but the current scalar value is incompatible.",
    [ValidationMessageKeys.formatViolation]: "Property '{displayPath}' must satisfy string format '{value}'.",
    [ValidationMessageKeys.missingRequired]: "Required property '{displayPath}' is missing.",
    [ValidationMessageKeys.unknownProperty]: "Property '{displayPath}' is not declared in the matching schema."
};

const zhCnMessages = {
    "tree.noConfigDirectory.label": "未找到配置目录",
    "tree.noConfigDirectory.description": "请设置 gframeworkConfig.configPath，或先创建该目录。",
    "tree.fileDescription.schema": "已匹配 schema",
    "tree.fileDescription.schemaMissing": "缺少 schema",
    "command.openRaw.title": "打开原始文件",
    "message.schemaNotFound": "未找到匹配的 schema 文件。",
    "message.formSaved": "已从表单预览保存配置文件。",
    "message.formInitialized": "已根据 schema 初始化示例配置。",
    "message.initializeFromSchemaConfirm": "从 schema 初始化会替换当前配置，并且可能丢失尚未保存的表单修改。是否继续？",
    "message.noYamlFilesInDomain": "所选配置域中没有找到 YAML 配置文件。",
    "message.batchEditNeedsSchema": "批量编辑要求该配置域存在匹配的 schema 文件。",
    "message.batchEditNoEditableFields": "匹配的 schema 中没有可批量编辑的顶层标量字段或标量数组字段。",
    "message.batchEditNoChanges": "批量编辑未修改任何已选配置文件。",
    "message.batchEditUpdated": "已在“{domain}”中批量更新 {count} 个配置文件。",
    "message.referenceSchemaMissing": "未找到引用的 schema 文件“{refTable}.schema.json”。",
    "message.referenceDomainMissing": "未找到引用的配置域“{refTable}”。",
    "message.referenceValueMissing": "在“{refTable}”中未找到引用配置“{refValue}”。",
    "diagnostic.schemaMissing": "未找到匹配的 schema 文件：{schemaPath}",
    "quickPick.batchEdit.title": "批量编辑：{domain}",
    "quickPick.batchEdit.placeholder": "选择要更新的配置文件。",
    "quickPick.batchEditFields.title": "批量编辑字段：{domain}",
    "quickPick.batchEditFields.placeholder": "选择要应用到已选文件的字段。",
    "detail.required": "必填",
    "detail.refTable": "引用表：{refTable}",
    "detail.arrayType": "数组<{itemType}>",
    "detail.default": "默认值",
    "button.cancel": "取消",
    "button.initializeFromSchemaConfirm": "从 schema 初始化",
    "input.batchArray.title": "批量编辑数组：{field}",
    "input.batchArray.prompt": "请输入“{fieldKey}”的逗号分隔项（期望类型：数组<{itemType}>）。留空表示清空数组。",
    "input.batchArray.placeholder.allowedItems": "允许项：{values}",
    "input.batchArray.placeholder.default": "默认值：{value}",
    "quickPick.batchField.title": "批量编辑字段：{field}",
    "quickPick.batchField.placeholder": "为“{fieldKey}”选择一个值。",
    "input.batchField.title": "批量编辑字段：{field}",
    "input.batchField.prompt": "请输入“{fieldKey}”的新值（期望类型：{type}）。",
    "input.batchField.placeholder.refTable": "引用表：{refTable}",
    "webview.panelTitle": "配置表单：{fileName}",
    "webview.meta.file": "文件：{fileName}",
    "webview.meta.schema": "Schema：{schemaPath}",
    "webview.meta.schemaMissing": "缺少 Schema：{schemaPath}",
    "webview.emptyState": "当前没有可编辑的 schema 绑定字段。对于暂不支持的结构，请回退到原始 YAML 编辑。",
    "webview.button.save": "保存表单",
    "webview.button.openRaw": "打开原始 YAML",
    "webview.button.initialize": "初始化示例",
    "webview.badge.required": "必填",
    "webview.help.summary": "你可以在这里直接编辑字段值、YAML 注释和关联跳转。遇到暂不支持的复杂结构或需要精确保留排版时，请回退到原始 YAML。",
    "webview.comment.label": "YAML 注释",
    "webview.ref.openSchema": "打开引用 Schema",
    "webview.ref.openDomain": "打开引用配置域",
    "webview.ref.openValue": "打开引用文件",
    "webview.objectArray.item": "对象项",
    "webview.objectArray.itemNumber": "对象项 {index}",
    "webview.objectArray.hint": "每一项都按下面的对象 schema 编辑。",
    "webview.objectArray.add": "新增对象项",
    "webview.objectArray.remove": "删除",
    "webview.array.hint": "每行一个元素。期望类型：{itemType}",
    "webview.hint.default": "默认值：{value}",
    "webview.hint.const": "固定值：{value}",
    "webview.hint.allowed": "允许值：{values}",
    "webview.hint.minimum": "最小值：{value}",
    "webview.hint.exclusiveMinimum": "开区间最小值：{value}",
    "webview.hint.maximum": "最大值：{value}",
    "webview.hint.exclusiveMaximum": "开区间最大值：{value}",
    "webview.hint.multipleOf": "倍数约束：{value}",
    "webview.hint.minLength": "最小长度：{value}",
    "webview.hint.maxLength": "最大长度：{value}",
    "webview.hint.pattern": "正则模式：{value}",
    "webview.hint.format": "格式：{value}",
    "webview.hint.minItems": "最少元素数：{value}",
    "webview.hint.maxItems": "最多元素数：{value}",
    "webview.hint.contains": "contains 条件：{summary}",
    "webview.hint.minContains": "最少匹配数：{value}",
    "webview.hint.maxContains": "最多匹配数：{value}",
    "webview.hint.uniqueItems": "元素必须唯一",
    "webview.hint.required": "必填字段：{properties}",
    "webview.hint.itemMinimum": "元素最小值：{value}",
    "webview.hint.itemConst": "元素固定值：{value}",
    "webview.hint.itemExclusiveMinimum": "元素开区间最小值：{value}",
    "webview.hint.itemMaximum": "元素最大值：{value}",
    "webview.hint.itemExclusiveMaximum": "元素开区间最大值：{value}",
    "webview.hint.itemMultipleOf": "元素倍数约束：{value}",
    "webview.hint.itemMinLength": "元素最小长度：{value}",
    "webview.hint.itemMaxLength": "元素最大长度：{value}",
    "webview.hint.itemPattern": "元素正则模式：{value}",
    "webview.hint.itemFormat": "元素格式：{value}",
    "webview.hint.minProperties": "最少属性数：{value}",
    "webview.hint.maxProperties": "最多属性数：{value}",
    "webview.hint.dependentRequired": "当 {trigger} 出现时：还必须声明 {dependencies}",
    "webview.hint.dependentSchemas": "当 {trigger} 出现时：还必须满足以下条件：{schema}",
    "webview.hint.allOf": "还必须满足：{schema}",
    "webview.hint.ifThen": "当满足 {condition} 时：还必须满足 {schema}",
    "webview.hint.ifElse": "否则（当 {condition} 不匹配时）：还必须满足 {schema}",
    "webview.hint.refTable": "引用表：{refTable}",
    "webview.unsupported.array": "当前表单预览暂不支持这种数组结构，请改用原始 YAML。",
    "webview.unsupported.type": "当前表单预览暂不支持 {type} 字段，请改用原始 YAML。",
    "webview.unsupported.objectArrayMixed": "对象数组中的每一项都必须是映射对象。如果当前文件混用了标量项和对象项，请改用原始 YAML。",
    "webview.unsupported.nestedObjectArray": "对象数组编辑器内暂不支持更深层的对象数组字段，请改用原始 YAML。",
    [ValidationMessageKeys.allOfViolation]: "对象“{displayPath}”必须满足全部 `allOf` schema，第 {index} 项未匹配。",
    [ValidationMessageKeys.constMismatch]: "属性“{displayPath}”必须匹配固定值 {value}。",
    [ValidationMessageKeys.dependentRequiredViolation]: "属性“{triggerProperty}”存在时，必须同时声明属性“{displayPath}”。",
    [ValidationMessageKeys.dependentSchemasViolation]: "对象“{displayPath}”在属性“{triggerProperty}”存在时，必须满足对应的依赖 schema。",
    [ValidationMessageKeys.elseViolation]: "对象“{displayPath}”在内联 `if` 条件未命中时，必须满足对应的 `else` schema。",
    [ValidationMessageKeys.exclusiveMaximumViolation]: "属性“{displayPath}”必须小于 {value}。",
    [ValidationMessageKeys.exclusiveMinimumViolation]: "属性“{displayPath}”必须大于 {value}。",
    [ValidationMessageKeys.maximumViolation]: "属性“{displayPath}”必须小于或等于 {value}。",
    [ValidationMessageKeys.maxContainsViolation]: "属性“{displayPath}”最多只能包含 {value} 个匹配 contains 条件的元素。",
    [ValidationMessageKeys.maxItemsViolation]: "属性“{displayPath}”最多只能包含 {value} 个元素。",
    [ValidationMessageKeys.maxLengthViolation]: "属性“{displayPath}”长度必须不超过 {value} 个字符。",
    [ValidationMessageKeys.maxPropertiesViolation]: "对象属性“{displayPath}”最多只能包含 {value} 个子属性。",
    [ValidationMessageKeys.minimumViolation]: "属性“{displayPath}”必须大于或等于 {value}。",
    [ValidationMessageKeys.multipleOfViolation]: "属性“{displayPath}”必须是 {value} 的整数倍。",
    [ValidationMessageKeys.notViolation]: "属性“{displayPath}”不能匹配被 `not` 禁止的 schema。",
    [ValidationMessageKeys.thenViolation]: "对象“{displayPath}”在内联 `if` 条件命中时，必须满足对应的 `then` schema。",
    [ValidationMessageKeys.minContainsViolation]: "属性“{displayPath}”至少需要包含 {value} 个匹配 contains 条件的元素。",
    [ValidationMessageKeys.minItemsViolation]: "属性“{displayPath}”至少需要包含 {value} 个元素。",
    [ValidationMessageKeys.minLengthViolation]: "属性“{displayPath}”长度必须至少为 {value} 个字符。",
    [ValidationMessageKeys.minPropertiesViolation]: "对象属性“{displayPath}”至少需要包含 {value} 个子属性。",
    [ValidationMessageKeys.patternViolation]: "属性“{displayPath}”必须匹配正则模式“{value}”。",
    [ValidationMessageKeys.uniqueItemsViolation]: "属性“{displayPath}”与更早的数组元素“{duplicatePath}”重复；该数组要求元素唯一。",
    [ValidationMessageKeys.enumMismatch]: "属性“{displayPath}”必须是以下值之一：{values}。",
    [ValidationMessageKeys.expectedArray]: "属性“{displayPath}”应为数组。",
    [ValidationMessageKeys.expectedScalarShape]: "属性“{displayPath}”应为“{schemaType}”，但当前 YAML 结构是“{yamlKind}”。",
    [ValidationMessageKeys.expectedScalarValue]: "属性“{displayPath}”应为“{schemaType}”，但当前标量值不兼容。",
    [ValidationMessageKeys.formatViolation]: "属性“{displayPath}”必须满足字符串格式“{value}”。",
    [ValidationMessageKeys.missingRequired]: "缺少必填属性“{displayPath}”。",
    [ValidationMessageKeys.unknownProperty]: "属性“{displayPath}”未在匹配的 schema 中声明。"
};

module.exports = {
    createLocalizer
};
