const LIcon = window.PrototypeIcon;

function LarkWorkspace({ stage, currentStage, section, onSectionChange, incident, deliverableVersion, acceptanceRound, onPlanConfirm, onPlanChange, onAdvance, onAccept, onRequestChanges, onSync, onOpenRecovery, onOpenMeegle, onDocumentComment }) {
  const [docTab, setDocTab] = React.useState("content");
  const [comment, setComment] = React.useState("");
  const [rejectOpen, setRejectOpen] = React.useState(false);
  const sendComment = () => {
    if (!comment.trim()) return;
    onDocumentComment(comment.trim());
    setComment("");
  };
  const activeInbox = stage === "plan" ? "proposal" : stage === "completed_sync" ? "sync" : "delivery";
  return <div className="lark-shell" data-screen-label="飞书 · 两触点协作">
    <aside className="lark-rail">
      <div className="lark-logo">L</div>
      <button title="消息" aria-label="消息" className={section === "chat" ? "active" : ""} onClick={() => onSectionChange("chat")}><LIcon name="message"></LIcon><span>消息</span></button>
      <button title="AI 收件箱" aria-label="AI 收件箱" className={section === "inbox" ? "active" : ""} onClick={() => onSectionChange("inbox")}><LIcon name="inbox"></LIcon><span>收件箱</span></button>
      <button title="云文档" aria-label="云文档" className={section === "docs" ? "active" : ""} onClick={() => onSectionChange("docs")}><LIcon name="docs"></LIcon><span>文档</span></button>
    </aside>
    <aside className="lark-sidebar">
      <div className="lark-search"><LIcon name="search" size={15}></LIcon><span>搜索</span><kbd>⌘ K</kbd></div>
      {section === "chat" ? <><div className="sidebar-title"><strong>消息</strong><button><LIcon name="plus"></LIcon></button></div><div className="conversation-list"><button className="active"><Avatar initials="AI" tone="violet" size="sm"></Avatar><div><strong>HyperWork AI</strong><span>{currentStage.short} · Story 24233867</span></div><time>刚刚</time></button><button><Avatar initials="R" tone="green" size="sm"></Avatar><div><strong>Rowan</strong><span>仅使用联调测试空间</span></div><time>14:10</time></button></div></> : null}
      {section === "inbox" ? <><div className="sidebar-title"><strong>AI 收件箱</strong><button><LIcon name="filter"></LIcon></button></div><div className="inbox-filter"><button className="active">待我处理</button><button>全部</button></div><div className="inbox-list">{window.prototypeInboxItems.map(item => <button key={item.id} className={item.id === activeInbox ? "active" : ""} onClick={() => item.id === "delivery" ? onSectionChange("docs") : onSectionChange("chat")}><span className={`inbox-kind ${item.id}`}><LIcon name={item.id === "proposal" ? "play" : item.id === "sync" ? "refresh" : "docs"}></LIcon></span><div><strong>{item.title}</strong><small>{item.subtitle}</small><em>{item.kind}</em></div><time>{item.time}</time></button>)}</div></> : null}
      {section === "docs" ? <><div className="sidebar-title"><strong>云文档</strong><button><LIcon name="plus"></LIcon></button></div><div className="doc-nav"><span>最近访问</span><button className="active"><LIcon name="docs"></LIcon><div><strong>项目型知识工作调研报告</strong><small>DeliverableVersion v{deliverableVersion} · 不可变验收版本</small></div></button><button><LIcon name="docs"></LIcon><div><strong>员工 SOP 与证据规范</strong><small>知识源 · 只读</small></div></button></div></> : null}
    </aside>
    <main className="lark-main">{section === "docs" ? <DocumentWorkspace stage={stage} version={deliverableVersion} round={acceptanceRound} tab={docTab} onTabChange={setDocTab} comment={comment} onCommentChange={setComment} onSendComment={sendComment} onOpenMeegle={onOpenMeegle}></DocumentWorkspace> : <>
      <header className="chat-header"><div><Avatar initials="HW" tone="violet" size="sm"></Avatar><div><strong>HyperWork AI</strong><span className="bot-badge">飞书应用机器人</span><small>发起、验收与异常通知发生在这里</small></div></div><div className="chat-header-actions"><span className="embedded-app-tag"><i>HW</i>自有应用</span><button title="打开 Meegle Story" onClick={onOpenMeegle}><LIcon name="link"></LIcon></button><button><LIcon name="more"></LIcon></button></div></header>
      <div className="chat-body"><div className="chat-date">今天</div>{stage === "detected" ? <div className="chat-row bot"><Avatar initials="AI" tone="violet" size="sm"></Avatar><div className="chat-bubble"><header><strong>HyperWork AI</strong><time>15:36</time></header><p>已识别 Meegle Story <button onClick={onOpenMeegle}>24233867</button>。业务对象仍由 Meegle 管理；确认前只有 DispatchProposal，没有 Run。</p></div></div> : null}<CurrentLarkCard stage={stage} currentStage={currentStage} incident={incident} version={deliverableVersion} round={acceptanceRound} onPlanConfirm={onPlanConfirm} onPlanChange={onPlanChange} onAdvance={onAdvance} onAccept={onAccept} onRequestChanges={() => setRejectOpen(true)} onSync={onSync} onOpenRecovery={onOpenRecovery} onOpenMeegle={onOpenMeegle} onOpenDocument={() => onSectionChange("docs")}></CurrentLarkCard></div>
    </>}</main>
    {rejectOpen ? <V8RejectionDialog round={acceptanceRound} version={deliverableVersion} onCancel={() => setRejectOpen(false)} onSubmit={feedback => { setRejectOpen(false); onRequestChanges(feedback); }}></V8RejectionDialog> : null}
  </div>;
}

function CurrentLarkCard({ stage, currentStage, incident, version, round, onPlanConfirm, onPlanChange, onAdvance, onAccept, onRequestChanges, onSync, onOpenRecovery, onOpenMeegle, onOpenDocument }) {
  if (stage === "detected") return <div className="chat-row bot card-row"><Avatar initials="AI" tone="violet" size="sm"></Avatar><article className="lark-action-card context-card"><header><span className="card-kicker">WORKITEM IDENTIFIED</span><StatusPill tone="blue">Run 尚未创建</StatusPill></header><h2>派工提案已准备</h2><p>请从 Meegle 打开飞书发起确认卡。提案生成成本已审计，但未启动 Workspace、Attempt 或业务工具。</p><footer><LIcon name="info"></LIcon>Meegle 没有“委派给 AI”字段；飞书卡片是协作入口。</footer></article></div>;

  if (stage === "plan") return <div className="chat-row bot card-row"><Avatar initials="AI" tone="violet" size="sm"></Avatar><article className="lark-action-card plan-card"><header><span className="card-kicker">TOUCHPOINT 1 · DISPATCH PROPOSAL</span><StatusPill tone="violet">等待发起确认</StatusPill></header><h2>把这项调研交给“项目研究员”</h2><p>确认后才会原子创建 Run、ExternalBinding 和 Story 家族活跃守卫。</p><div className="plan-list"><div><span>01</span><section><strong>读取限定的 Story 与飞书知识</strong><small>只读范围 · Story 24233867 · 指定 Wiki</small></section></div><div><span>02</span><section><strong>研究、核验证据并撰写正式报告</strong><small>一个 EmployeeVersion · 一个 ActorRun · 一个 PairSession</small></section></div><div><span>03</span><section><strong>由 Document Gateway 创建内部草稿</strong><small>L1 可逆写入 · 指定目录 · 本次确认预授权</small></section></div></div><div className="plan-scope"><div><span>交付物</span><strong>内部调研 / 正式报告</strong></div><div><span>预算</span><strong>¥220 · 超限自动暂停</strong></div><div><span>提案生成</span><strong>轻量摘要 ¥0.18 · 已审计</strong></div></div><div className="card-actions"><PrototypeButton tone="primary" icon="play" onClick={onPlanConfirm}>确认并开始</PrototypeButton><PrototypeButton icon="edit" onClick={onPlanChange}>调整范围</PrototypeButton></div><footer><LIcon name="lock"></LIcon>确认同时批准本次 L1 文档草稿写入；不批准 Meegle 状态变更。</footer></article></div>;

  if (stage === "running" && (incident === "blocked" || incident === "recovering")) return <div className="chat-row bot card-row"><Avatar initials="AI" tone="violet" size="sm"></Avatar><article className="lark-action-card blocker-card"><header><span className="card-kicker">RUN ATTENTION</span><StatusPill tone={incident === "blocked" ? "danger" : "warning"}>{incident === "blocked" ? "执行阻塞" : "恢复中"}</StatusPill></header><h2>{incident === "blocked" ? "Codex Attempt 遇到可恢复故障" : "Platform 正在从检查点恢复"}</h2><p>{incident === "blocked" ? "Attempt #1 心跳超时。平台已撤销 Lease 并保存 CP-014。" : "同一 PairSession 正绑定 Attempt #2；不会重复外部动作。"}</p><div className="blocker-facts"><div><span>业务影响</span><strong>交付预计延后 2 分钟</strong></div><div><span>Run</span><strong>仍为执行中</strong></div><div><span>Meegle</span><strong>仍为进行中</strong></div></div><div className="card-actions"><PrototypeButton tone="primary" icon="sandbox" onClick={onOpenRecovery}>查看恢复详情</PrototypeButton></div><footer><LIcon name="info"></LIcon>技术恢复留在 Platform，飞书只显示业务影响。</footer></article></div>;

  if (stage === "running") return <div className="chat-row bot card-row"><Avatar initials="AI" tone="violet" size="sm"></Avatar><article className="lark-action-card run-card">
    <header><span className="card-kicker">RUN IN PROGRESS</span><StatusPill tone={incident === "resolved" ? "success" : "blue"}>{incident === "resolved" ? "已恢复 · 继续执行" : `执行中 · ${currentStage.progress}%`}</StatusPill></header>
    <h2>项目研究员正在完成内部调研报告</h2>
    <p>后台会自动持续执行；Codex 只返回内容、证据与 ActionIntent，不持有飞书或 Meegle 生产凭据。</p>
    <div className="run-actors"><div><Avatar initials="研" tone="violet" size="sm"></Avatar><span><strong>项目研究员 v4</strong><small>AR-0813-007 · PAIR-0813-007 · {incident === "resolved" ? "Attempt #2" : "Attempt #1"}</small></span><StatusPill dot={false} tone="blue">63%</StatusPill></div></div>
    <div className="v8-run-milestones"><div className="done"><span><LIcon name="check"></LIcon></span><strong>收集证据</strong></div><i></i><div className="current"><span>2</span><strong>形成结论</strong></div><i></i><div><span>3</span><strong>生成文档</strong></div></div>
    <ProgressBar value={63}></ProgressBar>
    <div className="v8-demo-control"><div><strong>演示控制</strong><span>真实产品会自动推进；原型中点击模拟执行完成。</span></div><PrototypeButton tone="primary" icon="play" onClick={onAdvance}>模拟执行完成</PrototypeButton></div>
    <footer><LIcon name="lock"></LIcon>V1：单员工 × 单 Run × 单 ActorRun；小队并行不在第一版。</footer>
  </article></div>;

  if (stage === "review") return <div className="chat-row bot card-row"><Avatar initials="AI" tone="violet" size="sm"></Avatar><article className="lark-action-card result-card"><header><span className="card-kicker">TOUCHPOINT 2 · ACCEPTANCE ROUND {round}</span><StatusPill tone="blue">等待验收</StatusPill></header><h2>项目型知识工作调研报告 · v{version}</h2><p>本轮验收绑定不可变 DeliverableVersion v{version}。通过即完成 Run 并授权异步回写；退回会在同一 PairSession 续做新版本。</p><button className="document-result" onClick={onOpenDocument}><span><LIcon name="docs"></LIcon></span><div><strong>打开报告与证据清单</strong><small>飞书文档 · 不可变版本 v{version} · 证据 12 项</small></div><LIcon name="chevron"></LIcon></button><div className="result-metrics"><div><strong>12/12</strong><span>证据覆盖</span></div><div><strong>1</strong><span>ActorRun</span></div><div><strong>{round}</strong><span>验收轮</span></div></div><div className="v8-decision-hint"><LIcon name="info"></LIcon><span><strong>这是正常流程的最后一次人工确认。</strong>通过同时授权 Meegle 状态与评论异步回写。</span></div><div className="card-actions"><PrototypeButton tone="primary" icon="check" onClick={onAccept}>验收通过并授权回写</PrototypeButton><PrototypeButton icon="edit" onClick={onRequestChanges}>退回修改</PrototypeButton></div><footer><LIcon name="info"></LIcon>没有单独“发布审批”；Meegle 回写授权并入验收。</footer></article></div>;

  if (stage === "completed_sync") return <div className="chat-row bot card-row"><Avatar initials="AI" tone="violet" size="sm"></Avatar><article className="lark-action-card result-card"><header><span className="card-kicker">RUN COMPLETED · SYNC PENDING</span><StatusPill tone="warning">Meegle 待同步</StatusPill></header><h2>交付已完成，第三方状态正在对齐</h2><p>AcceptanceDecision 已落盘，Run 不会因 Meegle 暂时未同步而回退。</p><div className="v8-dual-status"><div className="done"><span><LIcon name="check"></LIcon></span><section><small>HyperWork · 事实状态</small><strong>Run 已完成</strong><em>AcceptanceDecision · v{version}</em></section></div><div className="pending"><span><LIcon name="refresh"></LIcon></span><section><small>Meegle · 投影状态</small><strong>等待同步</strong><em>WB-0813-022 · generation #7</em></section></div></div><div className="v8-fallback"><LIcon name="link"></LIcon><span><strong>自动回写失败时</strong>可打开 Meegle，复制摘要与文档深链人工回写；交付不被阻塞。</span></div><div className="card-actions"><PrototypeButton tone="primary" icon="link" onClick={onOpenMeegle}>打开 Meegle</PrototypeButton><PrototypeButton icon="docs" onClick={onOpenDocument}>查看已验收版本</PrototypeButton><button className="v8-simulate-link" onClick={onSync}>演示：模拟同步成功</button></div><footer><LIcon name="lock"></LIcon>验收事实与第三方投影分离；旧代际任务不能覆盖当前状态。</footer></article></div>;

  return <div className="chat-row bot card-row"><Avatar initials="AI" tone="violet" size="sm"></Avatar><article className="lark-action-card result-card"><header><span className="card-kicker">CLOSED LOOP</span><StatusPill tone="success">已验收 · 已同步</StatusPill></header><h2>Run 与第三方投影现已一致</h2><p>Run 先基于 AcceptanceDecision 完成，Meegle 随后通过 WritebackTask generation #7 对齐；两者没有被压成同一个状态。</p><button className="document-result" onClick={onOpenDocument}><span><LIcon name="docs"></LIcon></span><div><strong>项目型知识工作调研报告</strong><small>已验收版本 v{version} · 完整审计链可查</small></div><LIcon name="chevron"></LIcon></button><footer><LIcon name="check"></LIcon>低风险主链只发生两次人工触点。</footer></article></div>;
}

function V8RejectionDialog({ round, version, onCancel, onSubmit }) {
  const [category, setCategory] = React.useState("证据");
  const [comment, setComment] = React.useState("关键结论需要补充可追溯来源，并说明证据版本。");
  const categories = ["质量", "证据", "格式", "范围"];
  return <div className="v8-dialog-backdrop" role="presentation" onMouseDown={event => { if (event.target === event.currentTarget) onCancel(); }}>
    <section className="v8-rejection-dialog" role="dialog" aria-modal="true" aria-labelledby="reject-title">
      <header><div><span className="v8-dialog-icon"><LIcon name="edit"></LIcon></span><div><strong id="reject-title">退回 DeliverableVersion v{version}</strong><small>验收轮 {round} · 意见会带入同一 PairSession 续做</small></div></div><button aria-label="关闭" onClick={onCancel}>×</button></header>
      <div className="v8-dialog-body">
        <label>退回类型 <em>必选</em></label>
        <div className="v8-reject-categories">{categories.map(item => <button key={item} className={category === item ? "active" : ""} onClick={() => setCategory(item)}><span>{item === "质量" ? "01" : item === "证据" ? "02" : item === "格式" ? "03" : "04"}</span>{item}</button>)}</div>
        <label htmlFor="reject-comment">具体修改意见 <em>必填</em></label>
        <textarea id="reject-comment" rows="4" value={comment} onChange={event => setComment(event.target.value)} placeholder="说明哪里需要修改，以及期望的验收结果"></textarea>
        <div className="v8-reject-impact"><LIcon name="info"></LIcon><p><strong>提交后会发生什么</strong><span>保留 v{version} → 从检查点续做 → 生成 v{version + 1} → 创建验收轮 {round + 1}</span></p></div>
      </div>
      <footer><PrototypeButton onClick={onCancel}>取消</PrototypeButton><PrototypeButton tone="primary" icon="edit" disabled={!comment.trim()} onClick={() => onSubmit({ category, comment: comment.trim() })}>提交退回意见</PrototypeButton></footer>
    </section>
  </div>;
}

function DocumentWorkspace({ stage, version, round, tab, onTabChange, comment, onCommentChange, onSendComment, onOpenMeegle }) {
  const ready = ["review", "completed_sync", "accepted"].includes(stage);
  return <div className="document-workspace" data-screen-label="飞书文档 · 交付版本">
    <header className="doc-topbar"><div><LIcon name="docs"></LIcon><div><strong>项目型知识工作调研报告</strong><small>{ready ? `DeliverableVersion v${version} · 验收轮 ${round}` : "Document Gateway 草稿 · 编辑中"}</small></div></div><div><StatusPill tone={ready ? "success" : "warning"}>{ready ? "不可变版本" : "L1 草稿"}</StatusPill><PrototypeButton size="sm" icon="link" onClick={onOpenMeegle}>打开 Story 24233867</PrototypeButton></div></header>
    <div className="doc-toolbar"><div><button className={tab === "content" ? "active" : ""} onClick={() => onTabChange("content")}>正文</button><button className={tab === "sources" ? "active" : ""} onClick={() => onTabChange("sources")}>证据 <span>12</span></button><button className={tab === "changes" ? "active" : ""} onClick={() => onTabChange("changes")}>版本链</button></div></div>
    {tab === "content" ? <div className="doc-canvas"><article className="doc-page"><div className="doc-cover"><span>INTERNAL RESEARCH · 2026-08-13</span><h1>项目型知识工作调研报告</h1><p>Meegle WorkItem → 长期 AI 员工 → 飞书文档交付</p><div><span>AI 员工</span><strong>项目研究员 v4</strong><span>关联工作项</span><button onClick={onOpenMeegle}>Story 24233867</button></div></div><h2>结论摘要</h2><p>业务工作继续由 Meegle 管理，发起与验收发生在飞书，HyperWork 保存员工身份、可靠执行、验收事实和同步任务。</p><div className="doc-callout"><strong>执行边界</strong><p>Codex 不直接写飞书文档。它提交内容、证据和 ActionIntent，Document Gateway 使用受控凭据完成 L1 草稿写入。</p></div><h2>事实链</h2><ol><li><strong>发起确认</strong><span>DispatchProposal 确认后，原子创建 Run 与 ExternalBinding。</span></li><li><strong>可靠执行</strong><span>一个 ActorRun 通过持久 PairSession 使用可替换 Attempt。</span></li><li><strong>验收与同步</strong><span>AcceptanceDecision 完成 Run；WritebackTask 异步对齐 Meegle。</span></li></ol></article><aside className="doc-comment-panel"><header><strong>评论</strong><span>2</span></header><article><Avatar initials="R" tone="blue" size="xs"></Avatar><div><strong>Rowan</strong><p>请把事实源和投影状态明确分开。</p><small>已处理 · v{version}</small></div></article><article><Avatar initials="研" tone="violet" size="xs"></Avatar><div><strong>项目研究员</strong><p>已明确 Run 完成不依赖 Meegle 同步成功。</p><small>刚刚</small></div></article><div className="doc-comment-compose"><textarea rows="3" value={comment} placeholder="添加评论…" onChange={event => onCommentChange(event.target.value)}></textarea><PrototypeButton size="sm" tone="primary" disabled={!comment.trim()} onClick={onSendComment}>评论</PrototypeButton></div></aside></div> : null}
    {tab === "sources" ? <div className="doc-insight-list"><SectionTitle eyebrow="EVIDENCE" title="12 项可追溯证据" detail="每项证据关联来源系统、版本和 Run 事件。"></SectionTitle>{["Meegle WorkItem 最小字段快照", "飞书 Wiki v14", "DispatchProposal 生成审计", "Checkpoint CP-014", "Document Gateway 幂等回执"].map((source, index) => <article key={source}><span>{String(index + 1).padStart(2, "0")}</span><div><strong>{source}</strong><small>{index < 2 ? "第三方来源 · 冻结版本" : "HyperWork · 不可变事件"}</small></div><StatusPill tone="success">已核验</StatusPill></article>)}</div> : null}
    {tab === "changes" ? <div className="doc-change-list"><SectionTitle eyebrow="VERSION CHAIN" title={`Deliverable v1 → v${version}`} detail="退回续做产生新版本，不覆盖历史验收对象。"></SectionTitle>{Array.from({length: version}, (_, index) => <article key={index}><time>v{index + 1}</time><span></span><div><strong>不可变交付版本</strong><p>{index + 1 === version ? `当前验收轮 ${round} 引用此版本` : "历史版本 · 保留用于对比与审计"}</p></div></article>)}</div> : null}
  </div>;
}

Object.assign(window, { LarkWorkspace });
