#!/usr/bin/env node
/**
 * TFDS Dashboard 全自动安装脚本
 *
 * 在业务项目根目录（或空文件夹）执行：
 *   npx -y -p @tfdesign/dashboard@latest tfds-dashboard-setup
 *
 * 指定目标项目：
 *   npx -y -p @tfdesign/dashboard@latest tfds-dashboard-setup -- --target /path/to/app
 */

import { execSync } from 'node:child_process';
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const pkgRoot = path.resolve(__dirname, '..');
const cwd = process.cwd();
const publicNpmPackageName = '@tfdesign/dashboard';
const skillPublicName = '产品设计-体服平台数据看板-界面生成';
const preferredSetupCommand = 'npx -y -p @tfdesign/dashboard@latest tfds-dashboard-setup';

function parseTargetArg() {
  const args = process.argv.slice(2);
  const targetIndex = args.findIndex((arg) => arg === '--target' || arg === '-t');
  if (targetIndex >= 0 && args[targetIndex + 1]) return args[targetIndex + 1];
  const inline = args.find((arg) => arg.startsWith('--target='));
  if (inline) return inline.slice('--target='.length);
  return process.env.TFDS_TARGET || '';
}

function hasPackageJson(dir) {
  return fs.existsSync(path.join(dir, 'package.json'));
}

function readJsonSafe(file) {
  try {
    return JSON.parse(fs.readFileSync(file, 'utf8'));
  } catch {
    return null;
  }
}

function getNodeMajorVersion() {
  return Number.parseInt(String(process.versions.node || '0').split('.')[0], 10) || 0;
}

function hasUsableNpm() {
  try {
    execSync('npm --version', { stdio: 'pipe', encoding: 'utf8' });
    return true;
  } catch {
    return false;
  }
}

function printEnvGuide() {
  console.log('\n╔══════════════════════════════════════════════════════╗');
  console.log('║        现在还不能开始安装 TFDS                      ║');
  console.log('╚══════════════════════════════════════════════════════╝');
  console.log('\n  开始前请先确认：');
  console.log('    1. 本机已安装 Node.js 18 或更高版本');
  console.log('    2. npm 可以在终端中直接使用');
  console.log('\n  你只需要这样处理：');
  console.log('    • 安装或升级到 Node.js LTS（推荐 20+）');
  console.log('    • 安装完成后，重新打开 IDE 或终端，再执行：');
  console.log(`      ${preferredSetupCommand}`);
  console.log('');
}

function ensureRuntimePrerequisites() {
  const nodeMajor = getNodeMajorVersion();
  if (nodeMajor < 18) {
    printEnvGuide();
    console.log(`  你当前安装的 Node.js 版本：${process.versions.node}`);
    console.log('  继续安装需要 Node.js 18 或更高版本。\n');
    process.exit(1);
  }

  if (!hasUsableNpm()) {
    printEnvGuide();
    console.log(`  你当前安装的 Node.js 版本：${process.versions.node}`);
    console.log('  目前没有找到可用的 npm。请确认 Node.js 安装完整，或重新安装 Node.js LTS。\n');
    process.exit(1);
  }
}

function isTfdsPackageDir(dir) {
  const pkg = readJsonSafe(path.join(dir, 'package.json'));
  return pkg?.name === '@tfdesign/dashboard';
}

function findNearestBusinessProject(startDir) {
  let cur = path.resolve(startDir);
  while (true) {
    if (hasPackageJson(cur) && !isTfdsPackageDir(cur)) return cur;
    const next = path.dirname(cur);
    if (next === cur) return null;
    cur = next;
  }
}

function resolveProjectRoot() {
  const explicitTarget = parseTargetArg();
  if (explicitTarget) return path.resolve(cwd, explicitTarget);
  if (hasPackageJson(cwd) && !isTfdsPackageDir(cwd)) return cwd;
  return findNearestBusinessProject(cwd) || cwd;
}

const projectRoot = resolveProjectRoot();

ensureRuntimePrerequisites();

function log(msg) {
  console.log(`\n[安装向导] ${msg}`);
}
function ok(msg) {
  console.log(`  ✓ ${msg}`);
}
function warn(msg) {
  console.log(`  ⚠ ${msg}`);
}

function ensureDir(dir) {
  fs.mkdirSync(dir, { recursive: true });
}

function writeIfMissing(file, content) {
  if (fs.existsSync(file)) return false;
  ensureDir(path.dirname(file));
  fs.writeFileSync(file, content, 'utf8');
  return true;
}

function toPackageName(name) {
  const safe = String(name || 'tfds-app')
    .toLowerCase()
    .replace(/[^a-z0-9._-]+/g, '-')
    .replace(/^-+|-+$/g, '');
  return safe || 'tfds-app';
}

function createMinimalViteReactProject(root) {
  const appName = toPackageName(path.basename(root));
  writeIfMissing(
    path.join(root, 'package.json'),
    `${JSON.stringify(
      {
        name: appName,
        private: true,
        version: '0.0.0',
        type: 'module',
        scripts: { dev: 'vite', build: 'vite build', preview: 'vite preview' },
        dependencies: {},
        devDependencies: {},
      },
      null,
      2,
    )}\n`,
  );

  writeIfMissing(
    path.join(root, 'index.html'),
    `<div id="root"></div>\n<script type="module" src="/src/main.jsx"></script>\n`,
  );

  writeIfMissing(
    path.join(root, 'vite.config.js'),
    `import { defineConfig } from 'vite';\nimport react from '@vitejs/plugin-react';\nimport tailwindcss from '@tailwindcss/vite';\n\nexport default defineConfig({\n  plugins: [react(), tailwindcss()],\n});\n`,
  );

  writeIfMissing(
    path.join(root, 'src', 'main.jsx'),
    `import React from 'react';\nimport { createRoot } from 'react-dom/client';\nimport './index.css';\n\nfunction App() {\n  return (\n    <main style={{ padding: 24, fontFamily: 'system-ui, sans-serif' }}>\n      <h1>TFDS Dashboard Ready</h1>\n      <p>项目已初始化，可以开始接入 Dashboard 规范。</p>\n    </main>\n  );\n}\n\ncreateRoot(document.getElementById('root')).render(\n  <React.StrictMode>\n    <App />\n  </React.StrictMode>\n);\n`,
  );

  writeIfMissing(path.join(root, 'src', 'index.css'), '@import "tailwindcss";\n');
}

function readProjectPackageJson() {
  return JSON.parse(fs.readFileSync(path.join(projectRoot, 'package.json'), 'utf8'));
}

function getMergedDeps(pkg) {
  return { ...pkg.dependencies, ...pkg.devDependencies, ...pkg.peerDependencies };
}

function resolveInstalledPackageDir(pkgName) {
  return path.join(projectRoot, 'node_modules', ...pkgName.split('/'));
}

function hasInstalledPackage(pkgName) {
  return fs.existsSync(resolveInstalledPackageDir(pkgName));
}

function getMissingPackages(pkg, pkgNames) {
  const allDeps = getMergedDeps(pkg);
  return pkgNames.filter((name) => !allDeps[name] || !hasInstalledPackage(name));
}

function formatPackageList(pkgNames) {
  return pkgNames.join(' / ');
}

function run(cmd, opts = {}) {
  try {
    execSync(cmd, {
      stdio: opts.inherit ? 'inherit' : 'pipe',
      cwd: projectRoot,
      encoding: 'utf8',
      env: { ...process.env, ...opts.env },
    });
    return true;
  } catch (e) {
    if (!opts.inherit) {
      const errLines = (e.stderr || e.stdout || '').split('\n').slice(0, 20).join('\n');
      if (errLines.trim()) {
        console.log('  --- 错误详情（英文）---');
        console.log(errLines);
        console.log('  ----------------------');
      }
    }
    return false;
  }
}

function syncInstalledTfdsSkills() {
  const skillSyncScript = path.join(
    projectRoot,
    'node_modules',
    '@tfdesign',
    'dashboard',
    'scripts',
    'postinstall-cursor-skill.mjs',
  );

  if (!fs.existsSync(skillSyncScript)) {
    warn('没有找到 skill 同步脚本，已跳过自动刷新。后续可重新执行一次 npm install @tfdesign/dashboard。');
    return;
  }

  console.log('  正在刷新本地 skill 描述和规则文件...');
  if (
    !run(`node "${skillSyncScript}"`, {
      inherit: true,
      env: { SKIP_TFDS_CSS_PATCH: '1' },
    })
  ) {
    warn('skill 自动刷新未完成。你可以稍后重新执行当前安装脚本，或手动运行：');
    warn('node node_modules/@tfdesign/dashboard/scripts/postinstall-cursor-skill.mjs');
    return;
  }

  ok('skill 已同步到本地 IDE 目录');
}

console.log('\n╔══════════════════════════════════════════════════════╗');
console.log('║         TFDS Dashboard 规范安装向导                  ║');
console.log('╚══════════════════════════════════════════════════════╝');
console.log(`\n  环境检查已通过：Node.js ${process.versions.node}，npm 可用`);
console.log(`\n  安装包位置：${pkgRoot}`);
console.log(`  准备安装到：${projectRoot}`);

log('第 1 步 / 6  准备项目基础环境...');
const pkgPath = path.join(projectRoot, 'package.json');
const bootstrapDeps = ['react', 'react-dom', 'vite', '@vitejs/plugin-react'];
let createdProjectShell = false;

if (!fs.existsSync(pkgPath)) {
  console.log('\n  ⚠ 还没有检测到项目配置，正在为你准备一个可运行的 React 项目...');
  createMinimalViteReactProject(projectRoot);
  createdProjectShell = true;
}

let pkg = readProjectPackageJson();
if (pkg.name === '@tfdesign/dashboard') {
  console.log('\n  ✗ 当前打开的是 tfds-dashboard 包自身，不是业务项目目录。');
  console.log('  请改用 --target 指定你的项目根目录，例如：');
  console.log(`    node "${path.join(pkgRoot, 'scripts', 'setup.mjs')}" --target "/path/to/your-app"\n`);
  process.exit(0);
}

const missingBootstrapDeps = getMissingPackages(pkg, bootstrapDeps);
if (missingBootstrapDeps.length > 0) {
  console.log('  正在安装项目基础依赖，通常需要 10-60 秒...');
  if (!run(`npm install ${bootstrapDeps.join(' ')}`, { inherit: true })) {
    warn('项目基础依赖暂未安装完成。这通常和网络或终端权限有关。');
    process.exit(1);
  }
  pkg = readProjectPackageJson();
  ok('项目基础环境已准备好');
  if (createdProjectShell) console.log('  ✓ 项目已准备完成，继续安装 Dashboard 规范...');
} else {
  ok('项目配置和基础依赖已准备好');
}

log('第 2 步 / 6  准备页面样式能力...');
const tailwindDeps = ['tailwindcss', '@tailwindcss/vite'];
const missingTailwindDeps = getMissingPackages(pkg, tailwindDeps);
if (missingTailwindDeps.length > 0) {
  warn(`检测到页面样式能力还未准备完整，正在继续补齐：${formatPackageList(missingTailwindDeps)}`);
  if (!run('npm install tailwindcss @tailwindcss/vite', { inherit: true })) {
    warn('页面样式依赖暂未安装完成。');
  } else {
    pkg = readProjectPackageJson();
    ok('页面样式依赖已准备好');
  }
} else {
  ok('页面样式依赖已准备好，跳过');
}

log('第 3 步 / 6  检查项目配置...');
const viteConfigCandidates = ['vite.config.js', 'vite.config.ts', 'vite.config.mjs', 'vite.config.mts'];
let viteConfigPath = null;
for (const f of viteConfigCandidates) {
  const p = path.join(projectRoot, f);
  if (fs.existsSync(p)) {
    viteConfigPath = p;
    break;
  }
}
if (viteConfigPath) {
  let viteContent = fs.readFileSync(viteConfigPath, 'utf8');
  const hasPlugin = /tailwindcss\s*\(\s*\)/.test(viteContent);
  if (!hasPlugin) {
    if (!/@tailwindcss\/vite/.test(viteContent)) {
      viteContent = `import tailwindcss from '@tailwindcss/vite';\n` + viteContent;
    }
    if (/plugins\s*:\s*\[/.test(viteContent)) {
      viteContent = viteContent.replace(/plugins\s*:\s*\[/, 'plugins: [tailwindcss(), ');
      fs.writeFileSync(viteConfigPath, viteContent, 'utf8');
      ok(`${path.basename(viteConfigPath)} 已自动更新`);
    } else {
      warn('项目配置文件里没有找到 plugins 数组，后续请手动加入 tailwindcss() 插件。');
    }
  } else {
    ok(`${path.basename(viteConfigPath)} 已包含页面样式插件，跳过`);
  }
} else {
  warn('没有找到项目配置文件，已跳过自动更新。');
}

log('第 4 步 / 6  检查页面样式入口...');
const cssCandidates = [
  'src/index.css',
  'src/main.css',
  'src/styles.css',
  'src/global.css',
  'app/globals.css',
  'styles/globals.css',
  'index.css',
];
let cssHandled = false;
for (const rel of cssCandidates) {
  const cssPath = path.join(projectRoot, rel);
  if (!fs.existsSync(cssPath)) continue;
  const content = fs.readFileSync(cssPath, 'utf8');
  if (/@import\s+["']tailwindcss["']/.test(content)) {
    ok(`${rel} 已包含页面样式入口，跳过`);
    cssHandled = true;
    break;
  }
  fs.writeFileSync(cssPath, `@import "tailwindcss";\n` + content, 'utf8');
  ok(`${rel} 已自动补齐页面样式入口`);
  cssHandled = true;
  break;
}
if (!cssHandled) {
  const defaultCss = path.join(projectRoot, 'src', 'index.css');
  fs.mkdirSync(path.dirname(defaultCss), { recursive: true });
  fs.writeFileSync(defaultCss, '@import "tailwindcss";\n', 'utf8');
  ok('已创建 src/index.css 并补齐页面样式入口');
}

log('第 5 步 / 6  安装 Dashboard 规范能力...');
const installCmd = `npm install react react-dom lucide-react ${publicNpmPackageName} --save`;
const tfdsDeps = ['lucide-react', '@tfdesign/dashboard'];
const missingTfdsDeps = getMissingPackages(pkg, tfdsDeps);
if (missingTfdsDeps.length > 0) {
  warn(`检测到 Dashboard 规范能力还未准备完整，正在继续安装：${formatPackageList(missingTfdsDeps)}`);
  if (!run(installCmd, { inherit: true })) {
    warn('Dashboard 规范能力暂未安装完成。');
    process.exit(1);
  }
  ok('Dashboard 规范能力已安装完成');
} else {
  ok('Dashboard 规范能力已准备好，跳过');
}

syncInstalledTfdsSkills();

log('第 6 步 / 6  检查是否可以开始使用...\n');
const checkScript = path.join(
  projectRoot,
  'node_modules',
  '@tfdesign',
  'dashboard',
  'scripts',
  'check-tfds-integration.mjs',
);
if (fs.existsSync(checkScript)) {
  run(`node "${checkScript}"`, { inherit: true });
} else {
  warn('没有找到自动检查脚本。你可以稍后手动执行：');
  warn('node node_modules/@tfdesign/dashboard/scripts/check-tfds-integration.mjs');
}

console.log('\n──────────────────────────────────────────────────────');
console.log('  安装已完成！');
console.log(`  输入 /${skillPublicName} 或 Use Skill: ${skillPublicName} 即可开始生成页面。`);
console.log('  或者输入以下固定提示词开始生成页面：');
console.log('  按 TFDS Dashboard 设计规范生成页面。先读取 node_modules/@tfdesign/dashboard/AI_READ_FIRST.md。需求为：……');
console.log('──────────────────────────────────────────────────────\n');

