/* Robindex v2 — PublishModal + AnswerViewerModal (task-062b).
   Renders inside the PrivyProvider tree so usePrivy() is available. */
const { useState: pS, useEffect: pE } = React;

/* ---------------- PublishModal ---------------- */
function PublishModal({ questionText, answerText, citations, kol, initialSlug, onClose, onSuccess }) {
  const { Icon } = window.RXC;
  const E = window.RXE;
  const zh = window.RXI.lang === "zh";
  const L = (en, zhT) => (zh ? zhT : en);
  const defaultTitle = (questionText || "").slice(0, 80).trim() || L("Answer", "回答");

  const [title, setTitle] = pS(defaultTitle);
  const [visibility, setVisibility] = pS("public_free");
  const [consents, setConsents] = pS({ c1: false, c2: false, c3: false, c4: false, c5: false });
  const [busy, setBusy] = pS(false);
  const [err, setErr] = pS(null);
  const [pubSlug, setPubSlug] = pS(initialSlug || null);
  const [copyFeedback, setCopyFeedback] = pS("");
  const [copied, setCopied] = pS(false);

  pE(() => {
    if (window.RXA) { try { window.RXA.track("publish_modal_opened"); } catch (_) {} }
  }, []);

  const allChecked = visibility === "public_free"
    ? consents.c1 && consents.c2 && consents.c3 && consents.c4
    : consents.c1 && consents.c2 && consents.c3 && consents.c4 && consents.c5;

  const publish = async () => {
    if (!allChecked || busy) return;
    setBusy(true); setErr(null);
    try {
      const res = await window.RXAPI.publishAnswer({
        answerText, questionText, citations,
        kolId: kol.id || kol.kolId,
        title: title.trim() || defaultTitle,
        visibility,
      });
      if (res && res.error) { setErr(res.error); return; }
      const slug = res && res.slug;
      if (slug) {
        setPubSlug(slug);
        if (onSuccess) onSuccess(slug);
      } else {
        setErr("request_failed");
      }
    } catch (_) {
      setErr("network_error");
    } finally {
      setBusy(false);
    }
  };

  const pubUrl = pubSlug ? (window.location.origin + "/?a=" + encodeURIComponent(pubSlug)) : "";
  const shareText = "I asked @" + (kol.handle || "") + "'s AI twin on Robindex — answer with receipts: " + pubUrl;

  const doCopy = async () => {
    if (!pubUrl) return;
    try {
      await navigator.clipboard.writeText(pubUrl);
      setCopyFeedback(T2("pubCopyOk"));
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    } catch (_) {
      setCopyFeedback(T2("pubCopyErr"));
    }
  };

  if (pubSlug) {
    return (
      <Modal2 title={T2("pubSuccess")} icon="check" onClose={onClose}>
        <div className="dst-panel" style={{ padding: "22px 6px" }}>
          <Icon name="check" size={30} color="var(--up)" />
          <div style={{ margin: "10px 0", font: "600 13px var(--mono)", wordBreak: "break-all", padding: "8px 12px", background: "var(--panel-2)", borderRadius: "var(--r)" }}>{pubUrl}</div>
          <div style={{ display: "flex", gap: 8, justifyContent: "center", flexWrap: "wrap" }}>
            <button className="btn-ghost" onClick={doCopy} style={{ padding: "8px 14px" }}>
              <Icon name="copy" size={13} />{copied ? T2("pubCopyOk") : T2("pubCopyLink")}
            </button>
            <a className="btn-ghost" href={"https://twitter.com/intent/tweet?text=" + encodeURIComponent(shareText)} target="_blank" rel="noopener noreferrer" style={{ padding: "8px 14px", textDecoration: "none", display: "inline-flex", alignItems: "center", gap: 6 }}>
              <Icon name="xLogo" size={13} />{T2("pubShareX")}
            </a>
            <a className="btn-ghost" href={pubUrl} target="_blank" rel="noopener noreferrer" style={{ padding: "8px 14px", textDecoration: "none", display: "inline-flex", alignItems: "center", gap: 6 }}>
              <Icon name="externalLink" size={13} />{T2("pubOpenNew")}
            </a>
          </div>
        </div>
        <div role="status" aria-live="polite" style={{ position: "absolute", width: 1, height: 1, padding: 0, margin: -1, overflow: "hidden", clip: "rect(0,0,0,0)", border: 0 }}>{copyFeedback}</div>
      </Modal2>
    );
  }

  const errText = err && (() => {
    const m = {
      unauthorized: T2("pubErrUnauthorized"),
      network_error: T2("pubErrNetwork"),
      request_failed: T2("pubErrGeneric"),
    };
    return m[err] || T2("pubErrGeneric");
  })();

  const toggleConsent = (k) => setConsents((c) => ({ ...c, [k]: !c[k] }));

  return (
    <Modal2 title={T2("pubTitle")} icon="share" onClose={onClose}>
      <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
        <div>
          <div style={{ font: "600 12px var(--sans)", marginBottom: 4, color: "var(--dim)" }}>{T2("pubLabelTitle")}</div>
          <div className="x2-custom">
            <input type="text" value={title} onChange={(e) => setTitle(e.target.value)} placeholder={defaultTitle} aria-label={T2("pubLabelTitle")} style={{ width: "100%" }} />
          </div>
        </div>

        <div>
          <div style={{ font: "600 12px var(--sans)", marginBottom: 6, color: "var(--dim)" }}>{T2("pubVisibility")}</div>
          <div style={{ display: "flex", gap: 8 }}>
            <label className={"wd-opt" + (visibility === "public_free" ? " on" : "")} style={{ flex: 1, display: "flex", alignItems: "center", gap: 8, padding: "10px 12px", border: "1px solid var(--bd)", borderRadius: 10, cursor: "pointer", borderColor: visibility === "public_free" ? "var(--accent)" : undefined, background: visibility === "public_free" ? "rgba(99,102,241,0.08)" : undefined }}>
              <input type="radio" name="pub-vis" value="public_free" checked={visibility === "public_free"} onChange={() => setVisibility("public_free")} style={{ accentColor: "var(--accent)" }} />
              <span style={{ minWidth: 0 }}><div style={{ font: "600 13px var(--sans)" }}>{T2("pubFree")}</div></span>
            </label>
            <label className={"wd-opt" + (visibility === "public_paid" ? " on" : "")} style={{ flex: 1, display: "flex", alignItems: "center", gap: 8, padding: "10px 12px", border: "1px solid var(--bd)", borderRadius: 10, cursor: "pointer", borderColor: visibility === "public_paid" ? "var(--accent)" : undefined, background: visibility === "public_paid" ? "rgba(99,102,241,0.08)" : undefined }}>
              <input type="radio" name="pub-vis" value="public_paid" checked={visibility === "public_paid"} onChange={() => setVisibility("public_paid")} style={{ accentColor: "var(--accent)" }} />
              <span style={{ minWidth: 0 }}><div style={{ font: "600 13px var(--sans)" }}>{T2("pubPaid")}</div></span>
            </label>
          </div>
        </div>

        <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
          {[
            { k: "c1", t: T2("pubConsent1") },
            { k: "c2", t: T2("pubConsent2") },
            { k: "c3", t: T2("pubConsent3") },
            { k: "c4", t: T2("pubConsent4") },
            ...(visibility === "public_paid" ? [{ k: "c5", t: T2("pubConsent5") }] : []),
          ].map(({ k, t }) => (
            <label key={k} style={{ display: "flex", alignItems: "flex-start", gap: 8, cursor: "pointer", font: "400 12px var(--sans)", color: "var(--text)", lineHeight: "1.5" }}>
              <input type="checkbox" checked={consents[k] || false} onChange={() => toggleConsent(k)} style={{ marginTop: 1, accentColor: "var(--accent)", flex: "none" }} />
              <span>{t}</span>
            </label>
          ))}
        </div>

        {errText && (
          <div className="x2-note x2-danger" role="alert"><Icon name="shield" size={13} style={{ flex: "none", marginTop: 1 }} />{errText}</div>
        )}

        <button className="x2-primary" disabled={!allChecked || busy} onClick={publish}>
          <Icon name="share" size={14} />{busy ? T2("pubPublishing") : T2("pubBtn")}
        </button>
      </div>
    </Modal2>
  );
}

/* ---------------- AnswerViewerModal ---------------- */
function AnswerViewerModal({ slug, onClose }) {
  const { Icon } = window.RXC;
  const E = window.RXE;
  const zh = window.RXI.lang === "zh";
  const L = (en, zhT) => (zh ? zhT : en);
  const privy = window.PrivySDK && window.PrivySDK.usePrivy ? window.PrivySDK.usePrivy() : null;
  const authenticated = privy && privy.authenticated;

  const [data, setData] = pS(null);
  const [loading, setLoading] = pS(true);
  const [err, setErr] = pS(null);
  const [unlocked, setUnlocked] = pS(false);
  const [unlocking, setUnlocking] = pS(false);
  const [unlockErr, setUnlockErr] = pS(null);

  const doFetchAnswer = async (initial) => {
    if (initial) setLoading(true);
    try {
      const res = await window.RXAPI.getAnswer(slug);
      if (res && res.error) { setErr(res); setLoading(false); return; }
      setData(res);
      if (res && res.type === "full") setUnlocked(true);
      setLoading(false);
    } catch (_) {
      setErr({ error: "network_error" }); setLoading(false);
    }
  };

  pE(() => { doFetchAnswer(true); }, [slug]);

  const doUnlock = async () => {
    if (!authenticated) {
      if (privy && typeof privy.login === "function") {
        try { privy.login({ loginMethods: ["email", "google"] }); } catch (e) { console.warn("[publish2] privy.login error:", e); }
      }
      return;
    }
    if (unlocking) return;
    if (window.RXA) { try { window.RXA.track("paid_unlock_started"); } catch (_) {} }
    setUnlocking(true); setUnlockErr(null);
    try {
      const res = await window.RXAPI.unlockAnswer(slug);
      if (res && res.ok) {
        await doFetchAnswer(true);
        return;
      }
      if (res && res.status === 402) {
        setUnlockErr("insufficient");
        return;
      }
      if (res && res.error) {
        setUnlockErr(res.error);
        return;
      }
      setUnlockErr("request_failed");
    } catch (_) {
      setUnlockErr("network_error");
    } finally {
      setUnlocking(false);
    }
  };

  const doTopup = () => {
    window.dispatchEvent(new CustomEvent("rx2:open-topup"));
  };

  if (loading) {
    return (
      <Modal2 title={T2("unlockTitle")} icon="lock" onClose={onClose}>
        <div style={{ padding: 18, textAlign: "center", color: "var(--dim)" }} role="status">{L("Loading…", "加载中…")}</div>
      </Modal2>
    );
  }

  if (err) {
    const status = err.status;
    const is410 = status === 410;
    const is404 = status === 404;
    const is429 = status === 429;
    const title = is410 ? T2("ansTakenDown") : is404 ? T2("ansNotFound") : is429 ? T2("ansRateLimited") : T2("ansNotFound");
    let body = "";
    if (is410) body = T2("ansTakenDownDesc");
    else if (is404) body = T2("ansNotFoundDesc");
    else if (is429)
      body = zh ? "请求太频繁，请稍后再试。" : "Too many requests — please try again later.";
    else body = T2("ansNotFoundDesc");
    return (
      <Modal2 title={title} icon="shield" onClose={onClose}>
        <div style={{ padding: "22px 6px", textAlign: "center" }}>
          <div style={{ font: "400 13px var(--sans)", color: "var(--dim)", marginBottom: 12 }}>{body}</div>
          <button className="btn-ghost" onClick={onClose}>{zh ? "关闭" : "Close"}</button>
        </div>
      </Modal2>
    );
  }

  const isPreview = data && data.type === "preview";
  const isPaid = data && data.visibility === "public_paid";
  const answerText = data && data.answerText;
  const title = data && (data.title || (zh ? "无标题" : "Untitled"));
  const citations = data && Array.isArray(data.citations) ? data.citations : [];
  const publishedAt = data && data.ts;

  const unlockErrText = unlockErr && (() => {
    const m = {
      insufficient: T2("ansInsufficient"),
      unauthorized: T2("pubErrUnauthorized"),
      network_error: T2("pubErrNetwork"),
      request_failed: T2("pubErrGeneric"),
    };
    return m[unlockErr] || T2("pubErrGeneric");
  })();

  return (
    <Modal2 title={T2("unlockTitle")} icon={unlocked ? "check" : "lock"} onClose={onClose}>
      <div style={{ display: "flex", flexDirection: "column", gap: 10, padding: "8px 0" }}>
        <h2 style={{ margin: 0, font: "600 16px var(--sans)" }}>{title}</h2>
        {publishedAt && (
          <div style={{ font: "400 11px var(--sans)", color: "var(--faint)" }}>
            {T2("ansPublished")} {E.fmtDT(publishedAt)}
          </div>
        )}

        {isPreview && isPaid ? (
          <>
            <div style={{ position: "relative" }}>
              <div style={{ font: "400 14px var(--sans)", lineHeight: "1.6", color: "var(--text)", opacity: 0.5, filter: "blur(3px)", userSelect: "none" }}>
                {(answerText || "").slice(0, 160)}
              </div>
              <div style={{ position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center" }}>
                <span style={{ font: "600 13px var(--sans)", color: "var(--accent)", background: "var(--panel)", padding: "6px 14px", borderRadius: 8 }}>{T2("unlockPreview")}</span>
              </div>
            </div>
            {citations.length > 0 && (
              <div style={{ font: "400 12px var(--sans)", color: "var(--dim)" }}>
                {T2("ansCitations")(citations.length)}
              </div>
            )}
            <div style={{ font: "600 14px var(--sans)", display: "flex", alignItems: "center", gap: 6 }}>
              <Icon name="lock" size={14} color="var(--accent)" />
              {T2("unlockPrice")} · $1
            </div>
            <button className="x2-primary" disabled={unlocking} onClick={doUnlock}>
              <Icon name="lock" size={14} />
              {unlocking ? T2("ansUnlocking") : T2("unlockBtn")}
            </button>
            {unlockErr === "insufficient" && (
              <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
                <div className="x2-note x2-danger" role="alert">
                  <Icon name="shield" size={13} style={{ flex: "none", marginTop: 1 }} />{unlockErrText}
                </div>
                <button className="btn-ghost" onClick={doTopup} style={{ padding: "8px 14px" }}>
                  <Icon name="wallet" size={13} />{T2("wTopup")}
                </button>
              </div>
            )}
            {unlockErr && unlockErr !== "insufficient" && (
              <div className="x2-note x2-danger" role="alert">
                <Icon name="shield" size={13} style={{ flex: "none", marginTop: 1 }} />{unlockErrText}
              </div>
            )}
          </>
        ) : (
          <>
            <div style={{ font: "400 14px var(--sans)", lineHeight: "1.6", color: "var(--text)", whiteSpace: "pre-wrap" }}>{answerText}</div>
            {citations.length > 0 && (
              <div style={{ font: "400 12px var(--sans)", color: "var(--dim)" }}>
                {T2("ansCitations")(citations.length)}
              </div>
            )}
          </>
        )}
      </div>
    </Modal2>
  );
}

Object.assign(window, { PublishModal, AnswerViewerModal });
