/* ============================================================
   Beacon CS — DEPLOY (evidence check · permission check · publish)
   ============================================================ */
function DeployView({ intent = {} }) {
  const { RELEASES } = window.DATA;
  const { PageHead, Badge } = window;
  const Icons = window.Icons;
  const contentReleases = RELEASES.filter(item => item.stage === "production");
  const [publishOpen, setPublishOpen] = useState(false);
  const unresolvedQaConflicts = window.getUnresolvedQaConflictCount();
  const pendingQaSimilarity = window.getPendingQaSimilarityCount();
  const lastTestRun = window.PROTOTYPE_STATE.lastTestRun;
  const activeChange = window.PROTOTYPE_STATE.activeChange;
  const activeLabel = activeChange.contentRefs.join("、");
  const releaseKey = `change-${window.PROTOTYPE_STATE.changeRevision}`;
  const [published, setPublished] = useState(Boolean(window.PROTOTYPE_STATE.publishedVersions[releaseKey]));
  const pendingRelease = {
    key: releaseKey,
    ver: activeLabel,
    target: activeLabel,
    contentRefs: [...activeChange.contentRefs],
    sourceRevisions: [...activeChange.sourceRevisions],
    stage: published ? "production" : "awaiting-review",
    by: published ? "当前操作人" : "尚未发布",
    when: published ? "刚刚发布" : "等待发布",
    gate: published ? "passed" : "pending-check",
  };
  const releases = activeLabel ? [...contentReleases, pendingRelease] : contentReleases;
  const sameValues = (left = [], right = []) => left.length === right.length && left.every(value => right.includes(value));
  const bindingMatches = Boolean(lastTestRun
    && lastTestRun.result === "passed"
    && lastTestRun.changeRevision === window.PROTOTYPE_STATE.changeRevision
    && sameValues(lastTestRun.contentRefs, activeChange.contentRefs)
    && sameValues(lastTestRun.sourceRevisions, activeChange.sourceRevisions));
  const requiredChecks = ["regression", "redlines", "sources", "similarity", "highRisk", "toolBranches", "coverage"];
  const evidenceComplete = Boolean(bindingMatches
    && requiredChecks.every(key => lastTestRun.checks?.[key])
    && lastTestRun.counts?.invalidReferences === 0
    && lastTestRun.counts?.unsupportedHighRisk === 0
    && lastTestRun.counts?.redlineViolations === 0
    && Math.abs(lastTestRun.coverage?.lowRiskDelta || 0) <= 2
    && Math.abs(lastTestRun.coverage?.highFrequencyDelta || 0) <= 5
    && (lastTestRun.coverage?.unresolvedDelta || 0) <= 2);
  const candidateReady = evidenceComplete && pendingQaSimilarity === 0 && unresolvedQaConflicts === 0;
  const publishRelease = (release) => {
    window.PROTOTYPE_STATE.publishedVersions[release.key] = {
      contentRefs: [...activeChange.contentRefs],
      sourceRevisions: [...activeChange.sourceRevisions],
      testRunId: lastTestRun.id,
      checks: { ...lastTestRun.checks },
      counts: { ...lastTestRun.counts },
      coverage: { ...lastTestRun.coverage },
    };
    setPublished(true);
  };

  const stageBadge = (s) => ({
    production: <Badge tone="green" dot="var(--green)">线上生效</Badge>,
    "awaiting-review": <Badge tone="amber" dot="var(--amber)">待发布</Badge>,
  })[s];

  return (
    <div className="content-pad fadein">
      <PageHead title="发布" sub="查看问答和处理流程的发布状态，发布前核对来源、内容范围、工具分支和测试。" />

      <div className="col" style={{ gap: 14 }}>
        {releases.map(r => (
          <div key={r.key || r.ver} className="card card-pad rel-card">
            <div className="spread">
              <div>
                <div className="row" style={{ gap: 10 }}>
                  <span className="mono" style={{ fontWeight: 600, fontSize: 14 }}>{r.stage === "awaiting-review" ? "本次待生效内容" : r.ver}</span>
                  {stageBadge(r.stage)}
                  {r.gate === "human-gate" ? <window.Redline>需要发布权限</window.Redline> : null}
                </div>
                <div className="muted" style={{ fontSize: 12.5, marginTop: 4 }}>{r.target} · {r.by} · {r.when}</div>
              </div>
              {r.stage === "awaiting-review"
                ? <div className="row" style={{ gap: 8 }}>
                    {candidateReady ? <Badge tone="green">测试已通过</Badge> : <Badge tone="red">测试未通过</Badge>}
                    <button className="btn primary sm" onClick={() => setPublishOpen(r)}><Icons.checkCircle s={14} /> 打开发布检查</button>
                  </div>
                : null}
            </div>
          </div>
        ))}
      </div>

      {publishOpen ? <PublishGate rel={publishOpen} candidateReady={candidateReady} pendingQaSimilarity={pendingQaSimilarity} unresolvedQaConflicts={unresolvedQaConflicts} lastTestRun={lastTestRun} activeChange={activeChange} onPublish={publishRelease} onClose={() => setPublishOpen(false)} /> : null}
    </div>
  );
}

function PublishGate({ rel, candidateReady, pendingQaSimilarity, unresolvedQaConflicts, lastTestRun, activeChange, onPublish, onClose }) {
  const Icons = window.Icons; const { Badge } = window;
  const [approved, setApproved] = useState(false);
  const openTarget = (section, nextTab, extra = {}) => window.BeaconNav?.go(section, nextTab ? { tab: nextTab, ...extra } : extra);
  const counts = lastTestRun?.counts || {};
  const coverage = lastTestRun?.coverage || {};
  const evidenceRows = [
    { text: "改动后重新测试", value: lastTestRun?.checks?.regression ? "通过" : "未通过", ok: Boolean(lastTestRun?.checks?.regression) },
    { text: "失效引用", value: Number.isInteger(counts.invalidReferences) ? counts.invalidReferences : "未检查", ok: counts.invalidReferences === 0 },
    { text: "无依据高风险结论", value: Number.isInteger(counts.unsupportedHighRisk) ? counts.unsupportedHighRisk : "未检查", ok: counts.unsupportedHighRisk === 0 },
    { text: "发送前红线违规", value: Number.isInteger(counts.redlineViolations) ? counts.redlineViolations : "未检查", ok: counts.redlineViolations === 0 },
    { text: "工具结果分支", value: lastTestRun?.checks?.toolBranches ? "覆盖完整" : "证据不足", ok: Boolean(lastTestRun?.checks?.toolBranches) },
    { text: "低风险覆盖变化", value: Number.isFinite(coverage.lowRiskDelta) ? `${coverage.lowRiskDelta} 个百分点` : "未检查", ok: Number.isFinite(coverage.lowRiskDelta) && Math.abs(coverage.lowRiskDelta) <= 2 },
    { text: "高频问题覆盖变化", value: Number.isFinite(coverage.highFrequencyDelta) ? `${coverage.highFrequencyDelta} 个百分点` : "未检查", ok: Number.isFinite(coverage.highFrequencyDelta) && Math.abs(coverage.highFrequencyDelta) <= 5 },
    { text: "当前无法解决变化", value: Number.isFinite(coverage.unresolvedDelta) ? `+${coverage.unresolvedDelta} 个百分点` : "未检查", ok: Number.isFinite(coverage.unresolvedDelta) && coverage.unresolvedDelta <= 2 },
  ];
  return (
    <div className="modal-scrim" onClick={onClose}>
      <div className="modal" onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <div className="row" style={{ gap: 10 }}>
            <div className="gate-ico" style={{ background: "rgba(245,158,11,.16)" }}><Icons.shield s={18} sw={2} /></div>
            <div><div style={{ fontWeight: 700, fontSize: 15 }}>发布检查</div><div className="muted" style={{ fontSize: 12.5 }}>{activeChange.contentRefs.join("、")}</div></div>
          </div>
          <button className="btn ghost sm" aria-label="关闭发布审核" onClick={onClose}><Icons.x s={16} /></button>
        </div>
        <div className="modal-body">
          <dl className="kv" style={{ marginBottom: 16 }}>
            <dt>本次待生效内容</dt><dd>{activeChange.contentRefs.join("、")}</dd>
            <dt>来源修订</dt><dd>{activeChange.sourceRevisions.join("、") || "无明确来源依赖"}</dd>
            <dt>绑定测试运行</dt><dd><Badge tone={candidateReady ? "green" : "red"}>{candidateReady ? lastTestRun.id : "没有当前有效结果"}</Badge></dd>
            <dt>待判断高相关问答</dt><dd><Badge tone={pendingQaSimilarity === 0 ? "green" : "red"}>{pendingQaSimilarity}</Badge></dd>
            <dt>已确认答案冲突</dt><dd><Badge tone={unresolvedQaConflicts === 0 ? "green" : "red"}>{unresolvedQaConflicts}</Badge></dd>
            <dt>发布权限</dt><dd><Badge tone="green">当前用户已具备</Badge></dd>
          </dl>
          <div className="four-el" style={{ marginBottom: 16 }}>
            <div className="four-el-h">发布依据</div>
            <div className="col" style={{ gap: 8 }}>
              {evidenceRows.map((e, i) => (
                <div key={i} className="spread rc-row">
                  <span style={{ fontSize: 12.5 }}>{e.text}：{e.value}</span>
                  <Badge tone={e.ok ? "green" : "red"}>{e.ok ? "通过" : "未通过"}</Badge>
                </div>
              ))}
            </div>
          </div>
          {approved ? (
            <div className="gate" style={{ background: "var(--green-bg)", borderColor: "var(--green-bd)", color: "#15803D" }}><div className="gate-ico" style={{ background: "rgba(22,163,74,.15)" }}><Icons.check s={17} sw={2.4} /></div><div style={{ flex: 1, fontWeight: 500 }}>版本已发布，测试、权限和操作人已记录。</div></div>
          ) : candidateReady ? (
            <div className="gate" style={{ background: "var(--green-bg)", borderColor: "var(--green-bd)", color: "#15803D" }}><div className="gate-ico" style={{ background: "rgba(22,163,74,.15)" }}><Icons.checkCircle s={17} sw={2} /></div><div style={{ flex: 1, fontWeight: 500 }}>检查通过，当前用户可发布。</div></div>
          ) : (
            <div className="gate red"><div className="gate-ico"><Icons.lock s={17} sw={2} /></div><div style={{ flex: 1, fontWeight: 500 }}>{pendingQaSimilarity > 0 ? `还有 ${pendingQaSimilarity} 组高相关问答待判断，发布保持锁定。` : unresolvedQaConflicts > 0 ? `还有 ${unresolvedQaConflicts} 组已确认答案冲突未处理，发布保持锁定。` : "测试结果未绑定当前内容版本和来源修订，或覆盖检查尚未通过。"}</div></div>
          )}
        </div>
        <div className="modal-foot">
          <span className="muted" style={{ fontSize: 12 }}><Icons.shield s={13} /> 每条依据都绑定本次问答或处理流程版本、来源修订和同一次测试运行。</span>
          <div className="row" style={{ gap: 8 }}>
            {approved
              ? <><button className="btn sm" onClick={onClose}>关闭</button><button className="btn primary sm" onClick={() => openTarget("analyze", "outcome", { contentRefs: activeChange.contentRefs, publishedAt: "刚刚" })}>观察上线结果</button></>
              : candidateReady
                ? <><button className="btn sm" onClick={onClose}>暂不发布</button><button className="btn primary sm" onClick={() => { onPublish(rel); setApproved(true); }}><Icons.checkCircle s={13} /> 发布版本</button></>
                : <><button className="btn sm" onClick={() => pendingQaSimilarity > 0 || unresolvedQaConflicts > 0 ? openTarget("train", "review", { pane: "similarity", similarFaqId: "FAQ-1221" }) : openTarget("test", "shadow", { returned: "deploy" })}>{pendingQaSimilarity > 0 ? "前往判断相似项" : unresolvedQaConflicts > 0 ? "前往处理冲突" : "退回测试"}</button><button className="btn locked sm" disabled><Icons.lock s={13} /> 发布已锁定</button></>}
          </div>
        </div>
      </div>
    </div>
  );
}

window.DeployView = DeployView;
