import { useState } from 'react'
import { Navigate } from 'react-router-dom'
import { useAuth } from '../contexts/AuthContext.jsx'

const SUPER_ADMIN_EMAIL = '494161546@qq.com'
const SUPER_ADMIN_PHONE = '13136092523'

const SECTIONS = [
  { key: 'overview', label: '一、产品定位' },
  { key: 'lifecycle', label: '二、AgentRun 生命周期' },
  { key: 'routes', label: '三、用户动线' },
  { key: 'runtime', label: '四、运行与长任务' },
  { key: 'data', label: '五、数据与文件' },
  { key: 'config', label: '六、配置面板' },
  { key: 'api', label: '七、接口边界' },
  { key: 'handoff', label: '八、研发交接' },
]

export default function Architecture() {
  const { user } = useAuth()
  const isAdmin = user?.email === SUPER_ADMIN_EMAIL || user?.phone === SUPER_ADMIN_PHONE
  const [active, setActive] = useState('overview')

  if (!isAdmin) return <Navigate to="/" replace />

  return (
    <div className="flex h-full overflow-hidden bg-white">
      <aside className="w-60 flex-shrink-0 border-r border-gray-200 overflow-y-auto bg-gray-50">
        <div className="px-4 py-4 border-b border-gray-200">
          <div className="text-[15px] font-semibold text-gray-900">方案文档</div>
          <div className="text-[11px] text-gray-500 mt-0.5">AIPROS · Skill 平台</div>
        </div>
        <nav className="p-2">
          {SECTIONS.map(s => (
            <button
              key={s.key}
              onClick={() => {
                setActive(s.key)
                document.getElementById(`sec-${s.key}`)?.scrollIntoView({ behavior: 'smooth', block: 'start' })
              }}
              className={[
                'w-full text-left px-3 py-1.5 rounded text-[13px] transition',
                active === s.key ? 'bg-brand-50 text-brand-700 font-medium' : 'text-gray-700 hover:bg-gray-100',
              ].join(' ')}
            >
              {s.label}
            </button>
          ))}
        </nav>
        <div className="px-4 py-3 border-t border-gray-200 text-[11px] text-gray-400">v2.0 · 2026-06</div>
      </aside>

      <div
        className="flex-1 overflow-y-auto"
        onScroll={e => {
          const top = e.currentTarget.scrollTop
          for (let i = SECTIONS.length - 1; i >= 0; i--) {
            const el = document.getElementById(`sec-${SECTIONS[i].key}`)
            if (el && el.offsetTop - 80 <= top) {
              setActive(SECTIONS[i].key)
              break
            }
          }
        }}
      >
        <article className="max-w-4xl mx-auto px-10 py-10 space-y-10 text-[14px] text-gray-800 leading-relaxed">
          <header>
            <h1 className="text-[28px] font-bold text-gray-900">AIPROS · Agent + Skill 管理平台</h1>
            <p className="mt-2 text-gray-500">当前版按配置选择 AgentRun、本地 CLI 或云端智能体运行时。</p>
          </header>

          <Section id="overview" title="一、产品定位">
            <p><b>一句话定位</b>：把企业流程节点、标准 Skill 包、真实 AgentRun 执行结果放进同一个产品闭环。</p>
            <Bul items={[
              '业务用户从流程节点或 Skill 市场进入，直接发起创建、运行或评测。',
              '平台不在前端伪造生成结果，也不在本地拼假评测分数，所有主动作都进入后端 AgentRun 流。',
              '创建阶段把用户原始请求直接交给配置的智能体运行时，不附加固定输出结构、评测或质量门禁。',
              '运行期支持浏览器、联网搜索、代码执行和 Office 产物生成等工具能力，产物通过会话输出目录下载或预览。',
            ]} />
          </Section>

          <Section id="lifecycle" title="二、AgentRun 生命周期">
            <Pre>
{`创建:
  CreateSkillChat
    -> POST /api/skill-run/stream { mode=create, messages, selected files }
    -> 当前配置的 AgentRun / 本地 CLI / 云端智能体直接执行
    -> 原样返回文本、工具事件和生成文件
    -> 前端只展示“一键创建并立即发布 Skill”确认

运行:
  SandboxOverlay / SkillSandboxPage
    -> 读取真实 skill.package_key
    -> POST /api/skill-run/stream { mode=run, packageKey, user input }
    -> AgentRun 读取包文件和工具配置
    -> 返回文本、工具事件、Word/PDF/Excel/HTML 等产物

评测:
  EvaluationPanel / SkillEvalPage / EvalOverlay
    -> POST /api/skill-run/stream { mode=evaluate, packageKey }
    -> 后端先 list_files/read_file 做包内容装载
    -> AgentRun 读取智能体挂载的平台 Skill 包
    -> 输出评测报告、整改建议和是否建议上架`}
            </Pre>
            <p>这三条链路共享同一套会话状态、工具事件、输出文件和心跳机制。创建页不再做意图分流，只负责直连、结果呈现和最终发布确认。</p>
          </Section>

          <Section id="routes" title="三、用户动线">
            <Table head={['入口', '组件', '动作', '执行模式']} rows={[
              ['全部 Skill', 'AllSkills + SkillDetailModal', '点击运行打开运行抽屉，自动带入当前 Skill', 'mode=run'],
              ['Skill 运行', 'SkillOps + SandboxOverlay', '从运营分析进入单个 Skill 的真实运行', 'mode=run'],
              ['创建 Skill', 'CreateSkillChat', '先做意图识别和必要澄清；信息不足但用户接受默认样例时允许继续', 'mode=create'],
              ['评测 Skill', 'EvaluationPanel / EvalOverlay', '带入当前包文件，用系统评测器真实评测', 'mode=evaluate'],
              ['智能体配置', 'LlmSettings', '配置智能体、模型服务商和运行时注册', '配置入口'],
            ]} />
          </Section>

          <Section id="runtime" title="四、运行与长任务">
            <Bul items={[
              '后端入口统一为 cf-worker/src/routes/skill-run.js，负责 create、run、evaluate 三种模式。',
              '运行时配置来自 runtime_engines 表；llm_providers 只保留普通模型服务商配置。',
              'SSE 事件包含 heartbeat、status、tool_call、tool_result、message、files、done、error。',
              '前端 runSkillRunStreamWithReconnect 支持心跳超时后的重连，重连时携带 sessionId 续接会话。',
              '会话状态写入输出目录的 .skill-run-state.json，事件流写入 .skill-run-events.jsonl，便于长任务恢复和排障。',
              '工具调用产物统一写入会话输出目录，前端通过 /api/skill-run/outputs/:sessionId/:fileName 拉取。',
            ]} />
          </Section>

          <Section id="data" title="五、数据与文件">
            <Table head={['对象', '位置', '说明']} rows={[
              ['Skill 记录', 'skills 表', '名称、描述、节点、状态、package_key、可见性、作者信息。'],
              ['Skill 包', 'files 表 + uploads 目录', 'ZIP 包持久化；评测和运行必须带真实 packageKey。'],
              ['智能体挂载 Skill', 'runtime_agents.skill_id -> skills 表', '智能体直接选择平台已有 Skill；运行时读取对应 ZIP 包作为能力参考。'],
              ['运行时配置', 'runtime_engines 表', 'AgentRun、本地 CLI、适用场景和健康检查等信息。'],
              ['运行输出', 'OUTPUTS_DIR/sessionId', '工具事件、断点状态、生成文件和最终包。'],
            ]} />
          </Section>

          <Section id="config" title="六、配置面板">
            <Bul items={[
              '「智能体配置」维护智能体提示词、挂载的平台 Skill、运行时和生效场景。',
              '「模型配置」只负责普通模型服务商配置，不参与运行时注册。',
              '「运行时注册」维护 AgentRun 和本地 CLI 运行时，并支持按创建、评测、运行等场景绑定。',
              '保存智能体配置后只影响下一轮运行；历史会话不会被静默改写。',
              '配置页的运行检查基于当前注册运行时，不再把模型服务商和运行时混在一起。',
            ]} />
          </Section>

          <Section id="api" title="七、接口边界">
            <Table head={['接口', '职责', '备注']} rows={[
              ['/api/skill-run', '读取当前 Skill 执行引擎配置', '返回 AgentRun 就绪状态。'],
              ['/api/skill-run/stream', '创建、运行、评测的唯一流式执行入口', '请求体必须包含 mode。'],
              ['/api/skill-run/sessions/:id/repack', '把会话中的标准包重新打包', '用于生成后确认上传。'],
              ['/api/skill-run/outputs/:id/:file', '读取 AgentRun 工具产物', 'Word/PDF/Excel/HTML 等产物统一走这里。'],
              ['/api/providers', '模型服务商和 AgentRun 配置', '历史运行时不会出现在列表。'],
              ['/api/system-skills/:kind', '旧系统 Skill 兼容接口', '仅作为未挂平台 Skill 时的兜底，不再作为设置页主配置。'],
              ['/v1/skills/:id/invoke', '外部系统调用已上架 Skill', '同样要求 AgentRun 可用。'],
            ]} />
          </Section>

          <Section id="handoff" title="八、研发交接">
            <Bul items={[
              '改创建链路先看 src/pages/CreateSkillChat.jsx 和 cf-worker/src/routes/skill-run.js。创建请求直连配置运行时，生成后只保留一键创建并发布。',
              '改运行链路先看 src/pages/SkillSandboxPage.jsx、src/components/SandboxOverlay.jsx 和 cf-worker/src/routes/skill-run.js。',
              '改评测链路先看 src/components/EvaluationPanel.jsx、src/components/EvalOverlay.jsx 和智能体挂载的评测 Skill。',
              '改长任务能力先看 src/services/skillRunStream.js，以及后端 session state/event log 的读写。',
              '上线前至少跑 systemSkillsUi、skill-run run/create/evaluate、providers AgentRun、前端构建和浏览器动线检查。',
            ]} />
          </Section>

          <footer className="pt-6 border-t border-gray-100 text-[12px] text-gray-400">
            本文档随当前 AgentRun 版代码维护。修改入口：src/pages/Architecture.jsx
          </footer>
        </article>
      </div>
    </div>
  )
}

function Section({ id, title, children }) {
  return (
    <section id={`sec-${id}`} className="scroll-mt-6">
      <h2 className="text-[20px] font-bold text-gray-900 border-l-4 border-brand-500 pl-3 mb-4">{title}</h2>
      <div className="space-y-3">{children}</div>
    </section>
  )
}

function Bul({ items }) {
  return (
    <ul className="list-disc pl-5 space-y-1.5 text-gray-700">
      {items.map((item, index) => <li key={index}>{item}</li>)}
    </ul>
  )
}

function Pre({ children }) {
  return (
    <pre className="bg-gray-900 text-gray-100 text-[12px] p-4 rounded-lg overflow-x-auto leading-6">{children}</pre>
  )
}

function Table({ head, rows }) {
  return (
    <div className="overflow-x-auto">
      <table className="w-full text-[13px] border border-gray-200 rounded-lg overflow-hidden">
        <thead className="bg-gray-50 text-gray-600">
          <tr>
            {head.map((h, i) => <th key={i} className="px-3 py-2 text-left font-medium border-b border-gray-200">{h}</th>)}
          </tr>
        </thead>
        <tbody className="divide-y divide-gray-100">
          {rows.map((r, i) => (
            <tr key={i} className="hover:bg-gray-50">
              {r.map((c, j) => <td key={j} className="px-3 py-2 text-gray-700 align-top">{c}</td>)}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  )
}
