// 文案二创独立链路 · 通用进度组件
//
// 三个页面共用（拆解爆款 / 复刻爆款 / 质检合成）：URL 带 ?text_rewrite_job=xxx
// 时在该页对应位置内联渲染。组件内部职责：
//   - SSE 订阅 /api/text-rewrite/jobs/{id}/stream，兜底 5s 轮询 /api/.../get
//   - 渲染 7 stage 步骤条 + 当前阶段消息 + 百分比
//   - 「展开工作内容」可折叠：根据当前 stage 拉对应产物预览
//       · chunk_init 完成 → 展示 chunks_doubao 表（句切，d_001...）
//       · chunk_segment 完成 → chunks_segment 表（语义自然段，s_001...）
//       · rewrite 完成 → chunks_rewrite 表（段级二创，含可编辑 rewrite_text）
//   - 交互按钮：
//       · 编辑（rewrite stage 完成后）→ 调 PATCH /chunks/{cid}/rewrite
//       · 跳到拆解爆款 / 跳到复刻爆款 / 跳到质检合成 → 带 ?text_rewrite_job=xxx 跳转

const TR_STAGES = [
  { id: "downloader",         label: "1 · 链接下载" },
  { id: "audio_extract",      label: "2 · 抽音轨" },
  { id: "asr",                label: "3 · ASR 转写" },
  { id: "transcript_correct", label: "4 · LLM 修字" },
  { id: "chunk_init",         label: "5 · 句切（豆包）" },
  { id: "chunk_segment",      label: "6 · 语义段切" },
  { id: "rewrite",            label: "7 · 段级二创" },
];


// 三页面自动流转的"下一步"映射
const TR_NEXT_ROUTE = {
  teardown: { label: "进入复刻爆款", path: "/remix",     id: "remix" },
  remix:    { label: "传送到质检合成", path: "/qc",       id: "qc" },
  qc:       null,  // 已是终点
};


// 跳转按钮组：去三个页面看同一个 text_rewrite job 的进度
const TRJumpButtons = ({ jobId, currentRoute }) => {
  const targets = [
    { label: "拆解爆款",  path: "/workspace", id: "teardown" },
    { label: "复刻爆款",  path: "/remix",     id: "remix" },
    { label: "质检合成",  path: "/qc",        id: "qc" },
  ];
  return (
    <div className="row gap-4" style={{ flexWrap: "wrap" }}>
      {targets.map(t => {
        const isHere = currentRoute === t.id;
        return (
          <a key={t.id}
             href={isHere ? null : `${t.path}?text_rewrite_job=${encodeURIComponent(jobId)}`}
             onClick={isHere ? (e) => e.preventDefault() : undefined}
             className="tag mono"
             style={{
               fontSize: 9.5, padding: "2px 8px",
               textDecoration: "none", cursor: isHere ? "default" : "pointer",
               background: isHere ? "var(--bg-2)" : "var(--bg-1)",
               color: isHere ? "var(--fg-3)" : "var(--cyan)",
               border: `1px solid ${isHere ? "var(--line-1)" : "var(--cyan)"}`,
             }}>
            {isHere ? `· ${t.label}（当前）` : `→ ${t.label}`}
          </a>
        );
      })}
    </div>
  );
};


// 流转 CTA：任务在当前页"准备好"时给突出按钮，引导去下一页
const TRFlowCTA = ({ jobId, currentRoute, status, allMatched }) => {
  const next = TR_NEXT_ROUTE[currentRoute];
  if (!next) return null;
  // 拆解页：任务 completed 即可去复刻
  // 复刻页：任务 completed + 所有素材匹配完成才能去质检
  const ready =
    currentRoute === "teardown" ? status === "completed"
    : currentRoute === "remix"   ? (status === "completed" && allMatched)
    : false;

  const hint = !ready ? (
    currentRoute === "teardown" ? "等待文案拆解完成…"
    : currentRoute === "remix"   ? "请先把所有段的分镜素材都匹配/选定"
    : ""
  ) : "";

  const url = `${next.path}?text_rewrite_job=${encodeURIComponent(jobId)}`;
  return (
    <a href={ready ? url : null}
       onClick={ready ? undefined : (e) => e.preventDefault()}
       style={{
         display: "inline-flex", alignItems: "center", gap: 6,
         padding: "8px 14px", borderRadius: 4, fontSize: 12, fontWeight: 600,
         textDecoration: "none", cursor: ready ? "pointer" : "not-allowed",
         background: ready ? "var(--cyan)" : "var(--bg-2)",
         color: ready ? "var(--bg-0)" : "var(--fg-3)",
         border: `1px solid ${ready ? "var(--cyan)" : "var(--line-1)"}`,
       }}
       title={hint}>
      {ready ? "➡" : "⏳"} {next.label}
      {!ready && hint && (
        <span style={{ fontSize: 10, fontWeight: 400, marginLeft: 4 }}>· {hint}</span>
      )}
    </a>
  );
};


// 单条 stage 步骤标签
const TRStageTag = ({ stage, state, message, pct }) => {
  const colors = {
    done:   { fg: "var(--green)",  bg: "color-mix(in oklch, var(--green) 12%, var(--bg-1))" },
    cur:    { fg: "var(--cyan)",   bg: "color-mix(in oklch, var(--cyan)  16%, var(--bg-1))" },
    locked: { fg: "var(--fg-3)",   bg: "var(--bg-1)" },
    failed: { fg: "var(--pink)",   bg: "color-mix(in oklch, var(--pink)  14%, var(--bg-1))" },
  };
  const c = colors[state] || colors.locked;
  return (
    <div style={{
      padding: "4px 8px", borderRadius: 3, fontSize: 10,
      background: c.bg, color: c.fg, border: `1px solid ${c.fg}`,
      minWidth: 96, fontFamily: "var(--mono)",
    }} title={message || stage.label}>
      <div style={{ fontWeight: 600 }}>
        {state === "done" ? "✓ " : state === "cur" ? "▶ " : ""}{stage.label}
      </div>
      {state === "cur" && (
        <div style={{ fontSize: 9, marginTop: 2, opacity: 0.85 }}>{pct}%</div>
      )}
    </div>
  );
};


// chunks_doubao / chunks_segment / chunks_rewrite 表
const TRChunksTable = ({ kind, rows, jobId, onRewriteEdited }) => {
  const [editing, setEditing] = React.useState(null);  // {chunk_id, draft}
  const [busy, setBusy] = React.useState(false);

  if (!rows || !rows.length) {
    return <div style={{ fontSize: 11, color: "var(--fg-3)", padding: 8 }}>暂无数据</div>;
  }

  const submitEdit = async () => {
    if (!editing || !jobId) return;
    setBusy(true);
    try {
      const res = await API.textRewrite.patchRewrite(jobId, editing.chunk_id, {
        rewrite_text: editing.draft,
      });
      onRewriteEdited && onRewriteEdited(editing.chunk_id, editing.draft, res);
      setEditing(null);
    } catch (e) {
      alert("保存失败：" + (e.message || e));
    } finally {
      setBusy(false);
    }
  };

  return (
    <div style={{ overflow: "auto", maxHeight: 320 }}>
      <table style={{ width: "100%", fontSize: 10.5, borderCollapse: "collapse" }}>
        <thead style={{ position: "sticky", top: 0, background: "var(--bg-0)", zIndex: 1 }}>
          <tr>
            <th style={TR_TH}>chunk_id</th>
            {kind === "doubao" && <th style={TR_TH}>起止 (s)</th>}
            {kind === "segment" && <th style={TR_TH}>来源 d_chunks</th>}
            <th style={TR_TH}>{kind === "rewrite" ? "段级二创" : "文本"}</th>
            {kind === "rewrite" && <th style={TR_TH}>操作</th>}
          </tr>
        </thead>
        <tbody>
          {rows.map((r, i) => {
            const cid = r.chunk_id;
            const isEdit = editing && editing.chunk_id === cid;
            return (
              <tr key={cid || i} style={{ borderTop: "1px solid var(--line-1)" }}>
                <td style={TR_TD_MONO}>{cid}</td>
                {kind === "doubao" && (
                  <td style={TR_TD_MONO}>{(r.t_start || 0).toFixed(2)}–{(r.t_end || 0).toFixed(2)}</td>
                )}
                {kind === "segment" && (
                  <td style={TR_TD_MONO}>{(r.source_chunk_ids || []).join(", ")}</td>
                )}
                <td style={TR_TD}>
                  {kind === "rewrite" && isEdit ? (
                    <textarea value={editing.draft} disabled={busy}
                      onChange={(e) => setEditing({ ...editing, draft: e.target.value })}
                      style={{ width: "100%", minHeight: 56, fontSize: 10.5,
                               fontFamily: "inherit", padding: 4, borderRadius: 3,
                               border: "1px solid var(--cyan)" }}/>
                  ) : (
                    <span title={r.text || r.rewrite_text}>
                      {kind === "rewrite" ? (r.rewrite_text || "—") : (r.text || "—")}
                      {kind === "rewrite" && r.edited_manually_at && (
                        <span style={{ marginLeft: 6, fontSize: 9, color: "var(--orange)" }}>· 已人工编辑</span>
                      )}
                    </span>
                  )}
                </td>
                {kind === "rewrite" && (
                  <td style={TR_TD}>
                    {isEdit ? (
                      <div className="row gap-4">
                        <button className="btn" disabled={busy} onClick={submitEdit}
                                style={TR_BTN_PRIMARY}>{busy ? "保存中…" : "保存"}</button>
                        <button className="btn" disabled={busy} onClick={() => setEditing(null)}
                                style={TR_BTN_SECONDARY}>取消</button>
                      </div>
                    ) : (
                      <button className="btn"
                              onClick={() => setEditing({ chunk_id: cid, draft: r.rewrite_text || "" })}
                              style={TR_BTN_SECONDARY}>编辑</button>
                    )}
                  </td>
                )}
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
};

const TR_TH = { textAlign: "left", padding: "4px 6px", fontWeight: 600,
                color: "var(--fg-2)", fontSize: 10, fontFamily: "var(--mono)" };
const TR_TD = { padding: "4px 6px", verticalAlign: "top", fontSize: 11,
                color: "var(--fg-1)", lineHeight: 1.4 };
const TR_TD_MONO = { ...TR_TD, fontFamily: "var(--mono)", fontSize: 10,
                     color: "var(--purple)", whiteSpace: "nowrap" };
const TR_BTN_PRIMARY = { fontSize: 10, padding: "2px 8px", borderRadius: 3,
                         background: "var(--cyan)", color: "var(--bg-0)",
                         border: "1px solid var(--cyan)", cursor: "pointer" };
const TR_BTN_SECONDARY = { fontSize: 10, padding: "2px 8px", borderRadius: 3,
                           background: "var(--bg-1)", color: "var(--fg-1)",
                           border: "1px solid var(--line-1)", cursor: "pointer" };


// 主组件
const TextRewriteProgress = ({ jobId, currentRoute, expanded: initialExpanded = true,
                               compact = false }) => {
  const [job, setJob] = React.useState(null);            // 状态/进度元
  const [result, setResult] = React.useState(null);      // 完整 result.json（按需）
  const [matchData, setMatchData] = React.useState(null); // match-table（看 allMatched 用）
  const [err, setErr] = React.useState("");
  const [expanded, setExpanded] = React.useState(initialExpanded);
  const [activeTab, setActiveTab] = React.useState("rewrite");  // doubao / segment / rewrite

  // 拉初始 + 订阅
  React.useEffect(() => {
    if (!jobId) return;
    let cancelled = false;
    let es = null;
    let pollTimer = null;

    const refresh = async () => {
      try {
        const j = await API.textRewrite.get(jobId);
        if (cancelled) return;
        setJob(j);
        // 进度推到一定阶段后拉 result
        const step = (j.progress && j.progress.step) || "";
        const stageIdx = TR_STAGES.findIndex(s => s.id === step);
        if (stageIdx >= 4 || j.status === "completed") {
          try {
            const r = await API.textRewrite.result(jobId);
            if (!cancelled) setResult(r);
          } catch (_) {}
        }
        // 完成后拉 match-table，用于"是否所有段都匹配到素材"的判断
        if (j.status === "completed") {
          try {
            const mt = await API.textRewrite.matchTable(jobId);
            if (!cancelled) setMatchData(mt);
          } catch (_) {}
        }
      } catch (e) {
        if (!cancelled) setErr(String(e.message || e));
      }
    };

    refresh();

    // SSE 实时进度
    try {
      es = new EventSource(API.textRewrite.streamUrl(jobId));
      es.addEventListener("progress", (ev) => {
        if (cancelled) return;
        try {
          const data = JSON.parse(ev.data);
          setJob((prev) => prev ? { ...prev, progress: { ...(prev.progress || {}), ...data } } : prev);
        } catch (_) {}
      });
      es.addEventListener("status", (ev) => {
        if (cancelled) return;
        try {
          const data = JSON.parse(ev.data);
          setJob((prev) => prev ? { ...prev, status: data.status || prev.status } : prev);
        } catch (_) {}
      });
      es.addEventListener("done", (ev) => {
        if (cancelled) return;
        try {
          const data = JSON.parse(ev.data);
          setJob((prev) => prev ? { ...prev, status: data.status || prev.status, error: data.error } : prev);
          // 完成后再拉一次完整 result
          refresh();
        } catch (_) {}
        es && es.close();
      });
      es.onerror = () => {
        // SSE 断开 → 启 5s 兜底轮询
        if (es) { es.close(); es = null; }
        if (!pollTimer) pollTimer = setInterval(refresh, 5000);
      };
    } catch (_) {
      // 浏览器不支持 SSE → 直接轮询
      pollTimer = setInterval(refresh, 5000);
    }

    return () => {
      cancelled = true;
      es && es.close();
      pollTimer && clearInterval(pollTimer);
    };
  }, [jobId]);

  if (!jobId) return null;
  if (err && !job) {
    return <div style={{ padding: 12, fontSize: 11, color: "var(--pink)" }}>
      加载文案二创任务失败：{err}
    </div>;
  }
  if (!job) {
    return <div style={{ padding: 12, fontSize: 11, color: "var(--fg-3)" }}>
      加载文案二创任务 {jobId.slice(0, 8)}…
    </div>;
  }

  const status = job.status || "pending";
  const progress = job.progress || {};
  const curStep = progress.step || "";
  const curPct = progress.pct || 0;
  const curMessage = progress.message || "";
  const stageDoneIdx = TR_STAGES.findIndex(s => s.id === curStep);

  const stateOf = (idx) => {
    if (status === "failed" && idx === stageDoneIdx) return "failed";
    if (idx < stageDoneIdx) return "done";
    if (idx === stageDoneIdx) return status === "completed" ? "done" : "cur";
    if (status === "completed") return "done";
    return "locked";
  };

  // 当前可展示的产物
  const haveDoubao  = !!(result && result.chunks_doubao && result.chunks_doubao.length);
  const haveSegment = !!(result && result.chunks_segment && result.chunks_segment.length);
  const haveRewrite = !!(result && result.chunks_rewrite && result.chunks_rewrite.length);

  const onRewriteEdited = (cid, text, _res) => {
    setResult((prev) => {
      if (!prev) return prev;
      const next = { ...prev };
      next.chunks_rewrite = (prev.chunks_rewrite || []).map(c =>
        c.chunk_id === cid ? { ...c, rewrite_text: text, edited_manually_at: new Date().toISOString() } : c
      );
      return next;
    });
  };

  return (
    <div className="card" style={{ borderColor: "var(--cyan)" }}>
      <div className="card-hd" style={{ borderColor: "var(--cyan-soft)" }}>
        <span className="card-title">
          📝 文案二创独立链路
          <span className="mono" style={{ marginLeft: 8, fontSize: 10, color: "var(--fg-3)" }}>
            {jobId.slice(0, 8)}
          </span>
        </span>
        <div className="row gap-6" style={{ alignItems: "center" }}>
          <span className="tag mono" style={{
            fontSize: 9.5, padding: "1px 6px",
            background: status === "completed" ? "color-mix(in oklch, var(--green) 14%, var(--bg-1))"
                       : status === "failed"    ? "color-mix(in oklch, var(--pink)  14%, var(--bg-1))"
                       : "color-mix(in oklch, var(--cyan)  14%, var(--bg-1))",
            color: status === "completed" ? "var(--green)"
                   : status === "failed"    ? "var(--pink)"
                   : "var(--cyan)",
          }}>{status}</span>
          <button className="btn" onClick={() => setExpanded(!expanded)}
                  style={TR_BTN_SECONDARY}>
            {expanded ? "收起" : "展开"}
          </button>
        </div>
      </div>

      {expanded && (
        <div className="col" style={{ padding: 12, gap: 10 }}>
          {/* 跳转按钮 */}
          <div className="row between" style={{ alignItems: "center" }}>
            <span style={{ fontSize: 10.5, color: "var(--fg-3)" }}>
              视频→ASR→修字→句切→段切→段级二创 · 不做视觉拆解
            </span>
            <TRJumpButtons jobId={jobId} currentRoute={currentRoute}/>
          </div>

          {/* 自动流转 CTA：根据 currentRoute 决定下一步去哪 */}
          {(() => {
            const rows = matchData?.rows || [];
            const allMatched = rows.length > 0 &&
                               rows.every(r => r.visual_remix && r.visual_remix.match);
            return <TRFlowCTA jobId={jobId} currentRoute={currentRoute}
                              status={status} allMatched={allMatched}/>;
          })()}

          {/* 7 stage 步骤条 */}
          <div className="row gap-4" style={{ flexWrap: "wrap" }}>
            {TR_STAGES.map((s, i) => (
              <TRStageTag key={s.id} stage={s} state={stateOf(i)}
                          message={i === stageDoneIdx ? curMessage : ""} pct={curPct}/>
            ))}
          </div>

          {/* 当前消息 */}
          {curMessage && (
            <div style={{
              fontSize: 11, color: "var(--fg-1)",
              background: "var(--bg-1)", padding: "6px 8px", borderRadius: 3,
              fontFamily: "var(--mono)",
            }}>
              ▶ <strong>{TR_STAGES[stageDoneIdx]?.label || curStep}</strong> · {curPct}% · {curMessage}
            </div>
          )}

          {/* 失败提示 */}
          {status === "failed" && job.error && (
            <div style={{
              fontSize: 11, color: "var(--pink)",
              background: "color-mix(in oklch, var(--pink) 8%, var(--bg-1))",
              padding: "6px 8px", borderRadius: 3,
            }}>
              失败：{job.error}
            </div>
          )}

          {/* 工作内容标签页 */}
          {!compact && (haveDoubao || haveSegment || haveRewrite) && (
            <div className="col gap-6">
              <div className="row gap-4">
                {haveDoubao && (
                  <button onClick={() => setActiveTab("doubao")}
                          style={activeTab === "doubao" ? TR_TAB_ON : TR_TAB_OFF}>
                    句切 d_chunks ({result.chunks_doubao.length})
                  </button>
                )}
                {haveSegment && (
                  <button onClick={() => setActiveTab("segment")}
                          style={activeTab === "segment" ? TR_TAB_ON : TR_TAB_OFF}>
                    语义段 s_chunks ({result.chunks_segment.length})
                  </button>
                )}
                {haveRewrite && (
                  <button onClick={() => setActiveTab("rewrite")}
                          style={activeTab === "rewrite" ? TR_TAB_ON : TR_TAB_OFF}>
                    段级二创 ({result.chunks_rewrite.length})
                  </button>
                )}
              </div>

              {activeTab === "doubao" && haveDoubao && (
                <TRChunksTable kind="doubao" rows={result.chunks_doubao} jobId={jobId}/>
              )}
              {activeTab === "segment" && haveSegment && (
                <TRChunksTable kind="segment" rows={result.chunks_segment} jobId={jobId}/>
              )}
              {activeTab === "rewrite" && haveRewrite && (
                <TRChunksTable kind="rewrite" rows={result.chunks_rewrite}
                               jobId={jobId} onRewriteEdited={onRewriteEdited}/>
              )}
            </div>
          )}
        </div>
      )}
    </div>
  );
};

const TR_TAB_ON = {
  fontSize: 10.5, padding: "3px 10px", borderRadius: 3,
  background: "var(--cyan)", color: "var(--bg-0)",
  border: "1px solid var(--cyan)", cursor: "pointer", fontFamily: "var(--mono)",
};
const TR_TAB_OFF = {
  fontSize: 10.5, padding: "3px 10px", borderRadius: 3,
  background: "var(--bg-1)", color: "var(--fg-2)",
  border: "1px solid var(--line-1)", cursor: "pointer", fontFamily: "var(--mono)",
};


// 解析 URL ?text_rewrite_job= 参数（三个页面共用）
const useTextRewriteJobIdFromQuery = () => {
  const [jobId, setJobId] = React.useState(() => {
    try { return new URL(window.location.href).searchParams.get("text_rewrite_job") || ""; }
    catch { return ""; }
  });
  React.useEffect(() => {
    const onPop = () => {
      try {
        setJobId(new URL(window.location.href).searchParams.get("text_rewrite_job") || "");
      } catch {}
    };
    window.addEventListener("popstate", onPop);
    return () => window.removeEventListener("popstate", onPop);
  }, []);
  return jobId;
};


Object.assign(window, {
  TextRewriteProgress,
  TR_STAGES,
  useTextRewriteJobIdFromQuery,
});
