declare const process: { cwd(): string };
declare function require(name: string): {
  readFileSync?: (path: string, encoding: string) => string;
  join?: (...parts: string[]) => string;
};

const { readFileSync } = require("node:fs");
const { join } = require("node:path");

if (!readFileSync || !join) {
  throw new Error("测试运行环境缺少文件读取能力");
}

const root = process.cwd();
const view = readFileSync(join(root, "src/views/ConfigCenterView.vue"), "utf-8");
const template = extractTemplate(view);

assertIncludes(template, "薪资规则设置");
assertIncludes(template, "设置考勤、加班、迟到、缺卡和请假等工资核算规则。");
assertIncludes(template, "恢复默认规则");
assertIncludes(template, "规则清单");
assertIncludes(template, "全部规则");
assertIncludes(view, "attendance: \"考勤规则\"");
assertIncludes(view, "payroll: \"薪资规则\"");

for (const label of ["规则", "当前设置", "是否使用", "用途说明", "操作"]) {
  assertIncludes(template, `<th>${label}</th>`, `规则表格应展示业务化表头：${label}`);
}

for (const technicalText of ["配置列表", "<th>配置</th>", "<th>分组</th>", "<th>类型</th>", "全部分组"]) {
  assertNotIncludes(template, technicalText, `规则页不应展示技术化文案：${technicalText}`);
}

for (const technicalBinding of [
  "{{ config.config_key }}",
  "v-model=\"config.config_group\"",
  "v-model=\"config.value_type\"",
  "<option value=\"string\">string</option>",
  "<option value=\"integer\">integer</option>",
  "<option value=\"number\">number</option>",
  "<option value=\"boolean\">boolean</option>",
  "<option value=\"json\">json</option>",
]) {
  assertNotIncludes(template, technicalBinding, `规则页不应暴露系统字段：${technicalBinding}`);
}

assertIncludes(view, "groupLabel(config.config_group)", "规则分组应转换成业务名称展示");
assertIncludes(view, "formatConfigValue(config)", "规则值应转换成用户能理解的展示方式");
assertIncludes(template, "weekday-toggle-group", "周末规则应使用星期选择，不应展示原始数字数组");
assertIncludes(view, "displayEditValue(config)", "复杂规则编辑值应转换成业务可读格式");
assertIncludes(view, "updateDisplayValue(config", "用户输入应再转换回系统保存值");
assertNotIncludes(template, "v-model=\"config.config_value\"", "不应直接把系统保存值暴露给用户编辑");

function extractTemplate(content: string): string {
  const match = content.match(/<template>([\s\S]*)<\/template>/);
  if (!match) {
    throw new Error("缺少 template");
  }
  return match[1];
}

function assertIncludes(content: string, expected: string, message?: string): void {
  if (!content.includes(expected)) {
    throw new Error(message || `期望包含 ${expected}`);
  }
}

function assertNotIncludes(content: string, unexpected: string, message?: string): void {
  if (content.includes(unexpected)) {
    throw new Error(message || `不应包含 ${unexpected}`);
  }
}
