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

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const protoRoot = path.resolve(__dirname, '..');
const prdPath = path.join(protoRoot, '.spec/requirements-prd.md');
const sourcePath = path.join(protoRoot, 'annotation-source.json');
const columnsPath = path.join(protoRoot, 'components/tableColumns.ts');

const legacyPrd = fs.existsSync(prdPath) ? fs.readFileSync(prdPath, 'utf8') : '';
const existing = fs.existsSync(sourcePath)
  ? JSON.parse(fs.readFileSync(sourcePath, 'utf8'))
  : null;

/** 保留批注工具里已写入的 markdown，避免被 PRD 摘要覆盖 */
const markdownMap = { ...(existing?.markdownMap ?? {}) };

const columnsSource = fs.readFileSync(columnsPath, 'utf8');
const columnAnnotationIds = [...columnsSource.matchAll(/annotationId:\s*'(lbl-[^']+)'/g)].map((m) => m[1]);

const NODE_META = {
  'lbl-filter': { title: '筛选条件', color: '#2563eb', aiPrompt: '年份、月份、部门、业务员等筛选。' },
  'lbl-kpi': { title: 'KPI 统计', color: '#64748b', aiPrompt: '六张统计卡片口径。' },
  'lbl-kpi-count': { title: '台账条数', color: '#64748b', aiPrompt: '台账条数 KPI 点击切换列表。' },
  'lbl-kpi-unreceived': { title: '未收总计', color: '#64748b', aiPrompt: '未收总计 KPI 筛选未收款。' },
  'lbl-toolbar': { title: '列表工具栏', color: '#0f766e', aiPrompt: '导入、导出、标记确认、提交审批。' },
  'lbl-btn-mark-confirmed': { title: '标记为已确认', color: '#0f766e', aiPrompt: '草稿批量确认与权限收口。' },
  'lbl-btn-add-row': { title: '添加行', color: '#0f766e', aiPrompt: '表格底部新增行。' },
  'lbl-table': { title: '租赁台账宽表', color: '#2563eb', aiPrompt: '运营明细台账列表与行操作。' },
};

function extractSection(md, heading) {
  const lines = md.split('\n');
  const start = lines.findIndex((line) => line.startsWith(heading));
  if (start < 0) return null;
  const level = heading.match(/^#+/)?.[0].length ?? 2;
  let end = lines.length;
  for (let i = start + 1; i < lines.length; i++) {
    if (/^#{1,6}\s/.test(lines[i])) {
      const l = lines[i].match(/^#+/)?.[0].length ?? 2;
      if (l <= level) {
        end = i;
        break;
      }
    }
  }
  return lines.slice(start, end).join('\n').trim();
}

function titleFromMarkdown(md) {
  const match = md.match(/^##\s+(.+)/m);
  if (!match) return null;
  return match[1].replace(/列$/u, '').trim();
}

function resolveMeta(id) {
  if (NODE_META[id]) return NODE_META[id];
  const md = markdownMap[id];
  const fromMd = md ? titleFromMarkdown(md) : null;
  if (fromMd) {
    return { title: fromMd, color: '#64748b', aiPrompt: `${fromMd}字段说明。` };
  }
  return { title: id, color: '#64748b', aiPrompt: id };
}

function trimDoc(md) {
  return (md ?? '').replace(/\n---\s*$/g, '').trim();
}

/** 将标注文档中的 ## 降为 ###，用于 PRD 子节 */
function asSubsection(md) {
  return trimDoc(md).replace(/^## /gm, '### ');
}

function prdSection(title, body) {
  const content = trimDoc(body);
  return content ? `## ${title}\n\n${content}` : `## ${title}`;
}

function buildFullPrd(map, columnIds) {
  const fieldSections = columnIds
    .filter((id) => id !== 'lbl-col-status')
    .map((id) => asSubsection(map[id]))
    .filter(Boolean);

  return [
    '# 租赁业务台账 · 产品需求说明（PRD）',
    '',
    '> 对齐《租赁业务运营明细台账模版》；业务服务组维护各自台账，标记已确认与收款关联为原型演示。',
    '',
    '---',
    '',
    prdSection(
      '1. 模块定位',
      [
        '| 项 | 说明 |',
        '|---|---|',
        '| 模块名称 | 台账数据 — 租赁业务台账 |',
        '| 目标用户 | 租赁业务客服、业务服务组主管 |',
        '| 核心任务 | 维护租赁运营明细、汇总应收实收与盈亏、标记确认与关联收款 |',
        '| 页面结构 | 筛选区 + KPI 统计 + 工具栏 + 宽表 + 下拉加载更多（不做分页） |',
      ].join('\n'),
    ),
    '',
    '---',
    '',
    trimDoc(map['lbl-filter']),
    '',
    '---',
    '',
    trimDoc(map['lbl-kpi']),
    '',
    asSubsection(map['lbl-kpi-count']),
    '',
    asSubsection(map['lbl-kpi-unreceived']),
    '',
    '---',
    '',
    trimDoc(map['lbl-toolbar']),
    '',
    asSubsection(map['lbl-btn-mark-confirmed']),
    '',
    asSubsection(map['lbl-btn-add-row']),
    '',
    '---',
    '',
    trimDoc(map['lbl-table']),
    '',
    '---',
    '',
    (() => {
      const body = trimDoc(map['lbl-col-status']).replace(/^##\s+状态流转\s*\n+/, '');
      return prdSection('6. 状态流转', body);
    })(),
    '',
    '---',
    '',
    prdSection('7. 字段说明', fieldSections.join('\n\n')),
  ]
    .filter((block) => block.trim())
    .join('\n\n');
}

function ensureMarkdown(id, meta) {
  if (markdownMap[id]?.trim()) return markdownMap[id];
  const prdFallback = {
    'lbl-filter': '## 2. 筛选区',
    'lbl-kpi': '## 3. KPI 统计卡片（6 张）',
    'lbl-toolbar': '## 4. 列表工具栏',
    'lbl-table': '## 5. 列表字段',
  };
  if (prdFallback[id] && legacyPrd) {
    return extractSection(legacyPrd, prdFallback[id]) ?? `# ${meta.title}\n\n${meta.aiPrompt}`;
  }
  return `# ${meta.title}\n\n${meta.aiPrompt}`;
}

const pageNodeIds = [
  'lbl-filter',
  'lbl-kpi',
  'lbl-kpi-count',
  'lbl-kpi-unreceived',
  'lbl-toolbar',
  'lbl-btn-mark-confirmed',
  'lbl-btn-add-row',
  'lbl-table',
];

const uniqueOrdered = [...pageNodeIds];
for (const id of columnAnnotationIds) {
  if (!uniqueOrdered.includes(id)) uniqueOrdered.push(id);
}
for (const id of Object.keys(markdownMap)) {
  if (!uniqueOrdered.includes(id)) uniqueOrdered.push(id);
}

const existingNodeById = Object.fromEntries((existing?.data?.nodes ?? []).map((n) => [n.id, n]));
const now = Date.now();

const nodes = uniqueOrdered.map((id, index) => {
  const meta = resolveMeta(id);
  const markdown = ensureMarkdown(id, meta);
  markdownMap[id] = markdown;
  const prev = existingNodeById[id];
  return {
    id,
    index: index + 1,
    title: meta.title,
    pageId: 'list',
    locator: {
      selectors: [`[data-annotation-id="${id}"]`],
      fingerprint: id,
      path: [],
    },
    aiPrompt: meta.aiPrompt,
    annotationText: markdown,
    hasMarkdown: true,
    color: meta.color,
    images: prev?.images ?? [],
    createdAt: prev?.createdAt ?? 1740787200000,
    updatedAt: prev?.updatedAt ?? now,
    controls: prev?.controls ?? [],
  };
});

function docMarkdown(nodeId) {
  return markdownMap[nodeId] ?? '';
}

function docNode(nodeId) {
  const meta = resolveMeta(nodeId);
  return {
    type: 'markdown',
    id: `lbl-doc-${nodeId}`,
    title: meta.title,
    markdown: docMarkdown(nodeId),
  };
}

const tableColumnDocIds = columnAnnotationIds;

const fullPrd = buildFullPrd(markdownMap, columnAnnotationIds);
fs.writeFileSync(prdPath, `${fullPrd.trim()}\n`, 'utf8');

const overviewMd = extractSection(fullPrd, '## 1. 模块定位') ?? fullPrd;

const source = {
  documentVersion: 1,
  format: 'axhub-annotation-source',
  data: {
    version: 2,
    prototypeName: 'lease-business-ledger',
    pageId: 'list',
    updatedAt: now,
    nodes,
  },
  markdownMap,
  assetMap: existing?.assetMap ?? {},
  directory: {
    nodes: [
      {
        type: 'folder',
        id: 'lbl-doc-root',
        title: '租赁业务台账说明',
        defaultExpanded: true,
        children: [
          {
            type: 'markdown',
            id: 'lbl-doc-overview',
            title: '模块总览',
            markdown: overviewMd,
          },
          {
            type: 'link',
            id: 'lbl-link-self',
            title: '租赁业务台账原型',
            href: '/prototypes/lease-business-ledger',
            target: 'self',
          },
          {
            type: 'markdown',
            id: 'lbl-doc-prd',
            title: 'PRD 全文',
            markdown: fullPrd,
            markdownPath: 'src/prototypes/lease-business-ledger/.spec/requirements-prd.md',
          },
          {
            type: 'folder',
            id: 'lbl-doc-page-annotations',
            title: '页面标注',
            defaultExpanded: true,
            children: [
              docNode('lbl-filter'),
              {
                type: 'folder',
                id: 'lbl-doc-folder-kpi',
                title: 'KPI 统计',
                defaultExpanded: false,
                children: [
                  docNode('lbl-kpi'),
                  docNode('lbl-kpi-count'),
                  docNode('lbl-kpi-unreceived'),
                ],
              },
              {
                type: 'folder',
                id: 'lbl-doc-folder-toolbar',
                title: '列表工具栏',
                defaultExpanded: false,
                children: [
                  docNode('lbl-toolbar'),
                  docNode('lbl-btn-mark-confirmed'),
                  docNode('lbl-btn-add-row'),
                ],
              },
              {
                type: 'folder',
                id: 'lbl-doc-folder-table',
                title: '租赁台账宽表',
                defaultExpanded: true,
                children: [
                  docNode('lbl-table'),
                  ...tableColumnDocIds.map((id) => docNode(id)),
                ],
              },
            ],
          },
        ],
      },
    ],
  },
};

fs.writeFileSync(sourcePath, `${JSON.stringify(source, null, 2)}\n`, 'utf8');
console.log(`Built requirements-prd.md and annotation-source.json with ${nodes.length} nodes.`);
