/* ============================================================
   edit.jsx — 页面内文案编辑器（仅开发者模式可见）
   点「✎ 改文案」进入编辑态 → 点页面上任意一段文字 → 在弹层里改 →
   保存时 POST /__edit，由 serve.py 在源码（*.jsx / *.html）里做精确替换，
   即时更新页面、刷新后永久生效。需本地运行 serve.py 才能写文件。
   ============================================================ */

/* 从点击目标向上找到「真正承载这段文字」的元素：
   跳过空白节点，取最近的、textContent 非空的元素。 */
function pickCopyEl(node) {
  let el = node && node.nodeType === 3 ? node.parentElement : node;
  while (el && !(el.textContent && el.textContent.trim())) el = el.parentElement;
  return el && el.textContent.trim() ? el : null;
}

function CopyEditor() {
  const dev = useDevUnlocked();
  const [editing, setEditing] = useState(false);
  const [target, setTarget] = useState(null);   // { el, original }
  const [draft, setDraft] = useState("");
  const [saving, setSaving] = useState(false);
  const [toast, setToast] = useState(null);

  /* 编辑态时给 body 挂个类，驱动光标 / hover 高亮样式 */
  useEffect(() => {
    document.body.classList.toggle("copy-edit-on", editing);
    return () => document.body.classList.remove("copy-edit-on");
  }, [editing]);

  /* 编辑态拦截整页点击（capture 阶段，抢在 stage 翻屏之前），挑出被点的文字 */
  useEffect(() => {
    if (!editing) return;
    const onClick = (e) => {
      if (e.target.closest(".copy-editor-ui")) return;   // 别拦自己的 UI
      const el = pickCopyEl(e.target);
      if (!el) return;
      e.preventDefault(); e.stopPropagation();
      const original = el.textContent.trim();
      setTarget({ el, original });
      setDraft(original);
    };
    document.addEventListener("click", onClick, true);
    return () => document.removeEventListener("click", onClick, true);
  }, [editing]);

  const flash = (msg) => { setToast(msg); setTimeout(() => setToast(null), 3600); };

  async function save() {
    const original = target.original;
    const replacement = draft.trim();
    if (!replacement || replacement === original) { setTarget(null); return; }
    setSaving(true);
    try {
      const res = await fetch("/__edit", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ original, replacement }),
      });
      const data = await res.json();
      if (data.ok && data.count > 0) {
        if (target.el) target.el.textContent = replacement;   // 即时反馈
        flash(`已写入源码 ${data.count} 处，刷新后永久生效`);
      } else {
        flash(data.error || "未找到匹配的源码文案（可能是动态拼接的文字）");
      }
    } catch (e) {
      flash("保存失败：需在本地运行 serve.py（" + e.message + "）");
    }
    setSaving(false);
    setTarget(null);
  }

  if (!dev) return null;

  return (
    <div className="copy-editor-ui no-advance">
      <div className="copy-editor-bar">
        <button className={"ce-btn" + (editing ? " on" : "")}
                onClick={(e) => { e.stopPropagation(); setEditing((v) => !v); setTarget(null); }}>
          {editing ? "✓ 完成编辑" : "✎ 改文案"}
        </button>
        {editing && <span className="ce-tip">点页面上任意一段文字开始改</span>}
      </div>

      {target && (
        <div className="copy-editor-modal" onClick={(e) => { if (e.target === e.currentTarget) setTarget(null); }}>
          <div className="cem-card">
            <h4>修改文案</h4>
            <textarea autoFocus value={draft} onChange={(e) => setDraft(e.target.value)}
                      onKeyDown={(e) => { if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) save(); }} />
            <div className="cem-hint">⌘/Ctrl + Enter 保存 · 保存即写回源码文件</div>
            <div className="cem-actions">
              <button className="ce-btn" onClick={() => setTarget(null)}>取消</button>
              <button className="ce-btn on" disabled={saving} onClick={save}>{saving ? "保存中…" : "保存"}</button>
            </div>
          </div>
        </div>
      )}

      {toast && <div className="copy-editor-toast">{toast}</div>}
    </div>
  );
}

window.CopyEditor = CopyEditor;
