/**
 * TFDS 集成自检（只读，不改写用户任何配置文件）
 *
 * 在对方项目根目录执行：
 *   node node_modules/@tfdesign/b-end/scripts/check-tfds-integration.mjs
 *
 * 或通过环境变量指定根目录：
 *   TFDS_PROJECT_ROOT=/path/to/app node .../check-tfds-integration.mjs
 */
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const projectRoot = path.resolve(process.env.TFDS_PROJECT_ROOT || process.cwd());
const codexHome = process.env.CODEX_HOME
  ? path.resolve(process.env.CODEX_HOME)
  : path.join(os.homedir(), '.codex');
const SKILL_PUBLIC_NAME = '产品设计-体服平台B端-界面生成';
const hasCodexHomeDir = exists(codexHome);

function read(p) {
  try {
    return fs.readFileSync(p, 'utf8');
  } catch {
    return null;
  }
}

function exists(p) {
  try {
    fs.accessSync(p);
    return true;
  } catch {
    return false;
  }
}

const REQUIRED_TFDS_SKILL_FILES = [
  'SKILL.md',
  'DESIGN_PRINCIPLES.md',
  'PAGE_ARCHETYPES.md',
  'LAYOUT_RECIPES.md',
  'components.summary.json',
  'components.index.json',
  'LAYOUT_RULES.md',
  'GLOBAL_DESIGN_RULES.md',
  'CHECKLIST.md',
  'COMMON_FAILURES.md',
];

function displayPath(p) {
  const home = os.homedir();
  if (p === home) return '~';
  if (p.startsWith(home + path.sep)) return path.join('~', path.relative(home, p));
  const rel = path.relative(projectRoot, p);
  return rel && !rel.startsWith('..') ? rel : p;
}

/** 常见入口样式候选（存在则检查内容） */
function candidateCssFiles() {
  const rels = [
    'src/index.css',
    'src/main.css',
    'src/styles.css',
    'src/global.css',
    'app/globals.css',
    'styles/globals.css',
    'index.css',
  ];
  return rels.map((r) => path.join(projectRoot, r)).filter(exists);
}

function candidateConfigFiles() {
  const names = [
    'vite.config.js',
    'vite.config.mjs',
    'vite.config.ts',
    'vite.config.mts',
    'tailwind.config.js',
    'tailwind.config.mjs',
    'tailwind.config.ts',
  ];
  return names.map((n) => path.join(projectRoot, n)).filter(exists);
}

function hasThemeImport(cssText) {
  return /@tfdesign\/b-end\/theme\.css/.test(cssText);
}

function hasTailwindImport(cssText) {
  return /@import\s+["']tailwindcss["']/.test(cssText) || /@import\s+['"]tailwindcss['"]/.test(cssText);
}

function hasSourceScanForPackage(cssText) {
  return /@source[^;]*@tfdesign\/b-end|@source[^;]*node_modules\/@tfdesign\/b-end/i.test(cssText);
}

function hasContentScanInConfigs(text) {
  return /node_modules\/@tfdesign\/b-end|@tfdesign\/b-end\/\*\*/.test(text);
}

function main() {
  const issues = [];
  const ok = [];

  const pkgPath = path.join(projectRoot, 'package.json');
  const pkgRaw = read(pkgPath);
  if (!pkgRaw) {
    issues.push(`未找到 package.json（当前检测根目录：${projectRoot}）。请在对方项目根目录执行本脚本。`);
    printReport(issues, ok);
    process.exit(1);
  }

  let pkg;
  try {
    pkg = JSON.parse(pkgRaw);
  } catch {
    issues.push('package.json 无法解析为 JSON');
    printReport(issues, ok);
    process.exit(1);
  }

  const deps = { ...pkg.dependencies, ...pkg.devDependencies, ...pkg.peerDependencies };
  if (!deps['@tfdesign/b-end']) {
    issues.push('package.json 中未声明依赖 @tfdesign/b-end（dependencies / devDependencies / peerDependencies）。');
  } else {
    ok.push('已声明依赖 @tfdesign/b-end');
  }

  if (!exists(path.join(projectRoot, 'node_modules', '@tfdesign', 'b-end'))) {
    issues.push('未找到 node_modules/@tfdesign/b-end/。请先在该目录执行 npm install。');
  } else {
    ok.push('node_modules/@tfdesign/b-end 目录存在');
  }

  const cssFiles = candidateCssFiles();
  let themeOk = false;
  let tailwindOk = false;
  let sourceOk = false;

  if (cssFiles.length === 0) {
    issues.push('未在常见路径找到入口 CSS（如 src/index.css）。请手动确认已 @import "@tfdesign/b-end/theme.css"。可重新执行 npm i 触发 postinstall 自动补丁。');
  } else {
    ok.push(`将检查以下样式文件：${cssFiles.map((f) => path.relative(projectRoot, f)).join(', ')}`);
    for (const f of cssFiles) {
      const t = read(f);
      if (!t) continue;
      if (hasThemeImport(t)) themeOk = true;
      if (hasTailwindImport(t)) tailwindOk = true;
      if (hasSourceScanForPackage(t)) sourceOk = true;
    }
    if (!themeOk) issues.push('入口 CSS 中未发现 @import "@tfdesign/b-end/theme.css"（须在 @import "tailwindcss" 之后）。可重新执行 npm i 触发 postinstall 自动补丁，或手动追加。');
    else ok.push('已检测到 theme.css 引入');

    if (!tailwindOk) issues.push('入口 CSS 中未发现 @import "tailwindcss"（请确认 Tailwind v4 入口写法与官方一致）。');
    else ok.push('已检测到 tailwindcss 引入');

    if (sourceOk) ok.push('已检测到 @source 扫描 node_modules/@tfdesign/b-end');
  }

  let configScanHint = false;
  for (const cf of candidateConfigFiles()) {
    const t = read(cf);
    if (t && hasContentScanInConfigs(t)) {
      configScanHint = true;
      ok.push(`在 ${path.relative(projectRoot, cf)} 中发现对 @tfdesign/b-end 的 content/扫描配置线索`);
      break;
    }
  }

  if (cssFiles.length > 0 && !sourceOk && !configScanHint) {
    issues.push(
      '未检测到 Tailwind 对 @tfdesign/b-end 的扫描：入口 CSS 缺少 @source … @tfdesign/b-end，且配置文件中无 content 线索。可重新执行 npm i 触发 postinstall 自动补丁，详见 README.md → "TL;DR 快速开始"。',
    );
  } else if (cssFiles.length > 0 && !sourceOk && configScanHint) {
    ok.push('未使用 @source，但配置文件中出现对 @tfdesign/b-end 的扫描路径（方式 B），可接受');
  }

  function checkSkillDir(label, dir, options = {}) {
    const { required = false, whenParentExists = null, successSuffix = '' } = options;
    const parentExists = whenParentExists ? exists(whenParentExists) : false;

    if (!exists(dir)) {
      if (required || parentExists) {
        issues.push(`未找到 ${label} Skill：${displayPath(dir)}。请执行 npm i 触发 postinstall 自动复制，或从包内 skills/${SKILL_PUBLIC_NAME}（旧版为 skills/tfds）手动复制到 skills/${SKILL_PUBLIC_NAME}。`);
      }
      return false;
    }

    const missing = REQUIRED_TFDS_SKILL_FILES.filter((file) => !exists(path.join(dir, file)));
    if (missing.length > 0) {
      issues.push(
        `${label} Skill 目录存在但不完整：${displayPath(dir)} 缺少 ${missing.join(', ')}。这通常是旧版 Skill 残留；请删除该目录后重新执行 npm i，或重新复制 node_modules/@tfdesign/b-end/skills/${SKILL_PUBLIC_NAME}/（旧版为 skills/tfds/）到 skills/${SKILL_PUBLIC_NAME}/。`,
      );
      return false;
    }

    ok.push(`已安装 ${label} Skill：${displayPath(dir)}${successSuffix}`);
    return true;
  }

  checkSkillDir('Cursor', path.join(projectRoot, '.cursor', 'skills', SKILL_PUBLIC_NAME), {
    required: true,
    successSuffix: `（唤起：/${SKILL_PUBLIC_NAME}）`,
  });

  checkSkillDir('Claude Code', path.join(projectRoot, '.claude', 'skills', SKILL_PUBLIC_NAME), {
    whenParentExists: path.join(projectRoot, '.claude'),
    successSuffix: `（唤起：/${SKILL_PUBLIC_NAME}）`,
  });

  checkSkillDir('Codex 项目内参考', path.join(projectRoot, '.codex', 'skills', SKILL_PUBLIC_NAME), {
    whenParentExists: path.join(projectRoot, '.codex'),
  });

  // Codex 用户级：仅当本机存在 ~/.codex 时才要求（避免 Cursor-only 用户被误报）
  checkSkillDir('Codex 用户级', path.join(codexHome, 'skills', SKILL_PUBLIC_NAME), {
    required: hasCodexHomeDir,
    successSuffix: `（新开/重启 Codex 后 /${SKILL_PUBLIC_NAME}）`,
  });

  checkSkillDir('Agents', path.join(projectRoot, '.agents', 'skills', SKILL_PUBLIC_NAME), {
    whenParentExists: path.join(projectRoot, '.agents'),
    successSuffix: '（通用 agent 兜底）',
  });

  // Trae CN：仅当项目中存在 .trae-cn（或用户在用 Trae）时才要求（避免误报）
  checkSkillDir('Trae CN', path.join(projectRoot, '.trae-cn', 'skills', SKILL_PUBLIC_NAME), {
    required: exists(path.join(projectRoot, '.trae-cn')),
    successSuffix: `（Use Skill: ${SKILL_PUBLIC_NAME}）`,
  });

  // Trae：只检查 opt-in Skill 目录，故意不自动写入 .trae/rules/（避免 always-on 污染）
  if (exists(path.join(projectRoot, '.trae', 'rules'))) {
    ok.push('Trae 隔离提示：本工具不会写入 .trae/rules/，避免 TFDS 规范污染所有对话。');
  }

  printReport(issues, ok);

  const critical = issues.some(
    (m) =>
      m.includes('未声明依赖') ||
      m.includes('未找到 node_modules/@tfdesign') ||
      m.includes('未发现 @import "@tfdesign/b-end/theme.css"'),
  );
  process.exit(critical ? 1 : 0);
}

function printReport(issues, ok) {
  // eslint-disable-next-line no-console
  console.log('\n[tfds-integration-check] 项目根:', projectRoot);
  // eslint-disable-next-line no-console
  console.log('\n── 已通过 ──');
  if (ok.length === 0) // eslint-disable-next-line no-console
    console.log('（无）');
  else ok.forEach((l) => console.log('✓', l));
  // eslint-disable-next-line no-console
  console.log('\n── 待处理 / 提示 ──');
  if (issues.length === 0) // eslint-disable-next-line no-console
    console.log('（无）— 基础集成项已齐。');
  else issues.forEach((l) => console.log('!', l));
  // eslint-disable-next-line no-console
  console.log('\n详细步骤见：node_modules/@tfdesign/b-end/README.md → "TL;DR 快速开始"');
  // eslint-disable-next-line no-console
  console.log('');
}

main();
