/* Robindex v2 — Claim flow: two-phase API verification (claimStart → post → claimConfirm). */
const { useState: clS } = React;

const CLAIM_AGREEMENT = {
  en: [
    ["1 · Identity & authorization", "By publicly posting the one-time verification code supplied by Robindex from the X account @{h} and completing verification, you confirm you own that account and authorize Robindex, retroactively from the date this persona was first distilled through the present and ongoing, to: fetch and store your public posts via licensed data APIs; distill, index and update an AI persona derived from them; and serve answers generated in your voice, with citations linking back to your original posts."],
    ["2 · What claiming changes", "Claiming does not delete the persona. It marks it as owner-verified, gives you control of the per-call owner fee ($0.00–$0.10), and entitles you to 50% of net owner-fee revenue. You may change the fee at any time; changes apply to future calls only."],
    ["3 · Revenue & withdrawal", "Owner-fee revenue is split 50/50 between you and the platform after payment-processing costs. Only owner-fee earnings are withdrawable. Each payout carries a $1.00 fee for local withdrawal or a $25.00 fee for SWIFT, deducted from the payout; minimum withdrawal $10.00. Distill/update reward credits are promotional and never withdrawable."],
    ["4 · Content & liability", "Persona answers are AI-generated research commentary derived from your public posts, clearly labeled as an AI twin, and are not investment advice. You warrant your account does not infringe third-party rights. Either party may terminate: you may request immediate public delisting at any time; accrued earnings remain payable. Persona data, posts, and ledger records are retained for audit and settlement."],
    ["5 · Data", "We retain the raw post archive, persona artifacts, and full call logs for billing, audit and dispute-evidence purposes as described in the Privacy Policy."],
  ],
  zh: [
    ["1 · 身份与授权", "从 X 账号 @{h} 公开发布 Robindex 提供的一次性验证码并完成验证，即确认你是该账号所有者，并授权 Robindex——自本分身首次蒸馏之日起追溯至今并持续有效——通过持牌数据 API 拉取并存储你的公开帖子；据此蒸馏、索引并更新 AI 分身；以你的语气生成回答，且每条引用均回链至你的原帖。"],
    ["2 · 认领改变什么", "认领不会下架分身。它将标记为「本人已认领」，你获得每次调用本人费（$0.00–$0.10）的设置权，并享有本人费净收入的 50% 分成。费率可随时修改，仅对之后的调用生效。"],
    ["3 · 收入与提现", "本人费在扣除支付处理成本后与平台五五分成。仅本人费收入可提现；每次提现收取本地提现 $1.00 或 SWIFT $25.00 手续费，从提现金额中扣除，最低提现 $10.00。蒸馏/更新奖励为赠点，永不可提现。"],
    ["4 · 内容与责任", "分身回答是基于你公开帖子的 AI 研究评论，界面明确标注为 AI 分身，不构成投资建议。你保证账号内容不侵犯第三方权利。双方均可终止：你可随时申请立即公开下架；已产生收益仍将支付。分身数据、帖子与账本记录为审计与结算保留。"],
    ["5 · 数据", "我们按隐私政策留存原始帖子档案、人格产物与完整调用日志，用于计费、审计与拒付证据。"],
  ],
};

/* Owner control: immediate public delist (audit retained, balances unchanged). */
function OwnerDelistPanel({ kolId, handle, lang }) {
  const { Icon } = window.RXC;
  const privy = window.PrivySDK && window.PrivySDK.usePrivy ? window.PrivySDK.usePrivy() : null;
  const [busy, setBusy] = clS(false);
  const [status, setStatus] = clS(null);
  const [err, setErr] = clS(null);
  const L = (en, zh) => (lang === "zh" ? zh : en);

  const delist = async () => {
    if (busy) return;
    const ok = window.confirm(L(
      "Delist @" + handle + " from the public directory? Your persona data and earnings remain for audit and settlement. This cannot be undone from the app.",
      "将 @" + handle + " 从公开目录下架？分身数据与收益记录将保留用于审计与结算。应用内无法撤销。"
    ));
    if (!ok) return;
    setBusy(true); setErr(null); setStatus(null);
    try {
      const r = await window.RXAPI.ownerDelist(kolId);
      if (!r) { setErr(L("No response from server.", "服务器无响应。")); return; }
      if (r.status === 401 || r.error === "unauthorized") {
        if (privy && typeof privy.logout === "function") {
          try { privy.logout(); } catch (e) { console.warn("[OwnerDelistPanel] privy.logout failed:", e); }
        }
        setErr(L("Session expired — please sign in again.", "登录已过期，请重新登录。"));
        return;
      }
      if (r.error) {
        setErr(L("Delist failed (" + r.error + ") — please retry.", "下架失败（" + r.error + "），请重试。"));
        return;
      }
      if (r.ok) {
        window.dispatchEvent(new CustomEvent("rx2:refresh"));
        setStatus(L(
          r.alreadyDelisted ? "Already delisted from the public directory." : "Delisted from the public directory.",
          r.alreadyDelisted ? "已从公开目录下架。" : "已从公开目录下架。"
        ));
        return;
      }
      setErr(L("Delist failed — please retry.", "下架失败，请重试。"));
    } catch (_) {
      setErr(L("Network error — please retry.", "网络错误，请重试。"));
    } finally {
      setBusy(false);
    }
  };

  return (
    <div className="v2-card" style={{ marginTop: 12, padding: "14px 16px", boxShadow: "none", borderColor: "rgba(220,38,38,.25)" }}>
      <div className="v2-sec" style={{ margin: "0 0 6px", color: "var(--danger, #dc2626)" }}>
        <Icon name="shield" size={12} />{L("Danger zone", "危险操作")}
      </div>
      <p className="x2-msub" style={{ margin: "0 0 10px" }}>
        {L(
          "Remove @" + handle + " from the public directory and chat. Data and earnings stay for audit and settlement.",
          "将 @" + handle + " 从公开目录与聊天入口移除。数据与收益记录保留用于审计与结算。"
        )}
      </p>
      {status && (
        <div className="x2-note" role="status" style={{ marginBottom: 8 }}>
          <Icon name="check" size={13} style={{ flex: "none", marginTop: 1 }} />{status}
        </div>
      )}
      {err && (
        <div className="x2-note x2-danger" role="alert" style={{ marginBottom: 8 }}>
          <Icon name="shield" size={13} style={{ flex: "none", marginTop: 1 }} />{err}
        </div>
      )}
      <button className="btn-ghost" type="button" onClick={delist} disabled={busy}
        style={{ color: "var(--danger, #dc2626)", borderColor: "rgba(220,38,38,.35)" }}>
        <Icon name="xLogo" size={13} />{busy ? L("Delisting…", "下架中…") : L("Delist from directory", "从目录下架")}
      </button>
    </div>
  );
}

function ClaimModal({ reg, lang, onClose }) {
  const { Icon, Avatar } = window.RXC;
  const E = window.RXE, C = E.cfg();
  // Privy bridge for 401 → clear key (sign out). ClaimModal always mounts inside PrivyProvider.
  const privy = window.PrivySDK && window.PrivySDK.usePrivy ? window.PrivySDK.usePrivy() : null;
  const [fee, setFee] = clS(0.03);
  const [ck, setCk] = clS(false);
  const [postTemplate, setPostTemplate] = clS("");
  const [busy, setBusy] = clS(false);
  const [err, setErr] = clS(null);
  const [copied, setCopied] = clS(false);
  const L = (en, zh) => (lang === "zh" ? zh : en);
  const LA = (lang === "zh" ? CLAIM_AGREEMENT.zh : CLAIM_AGREEMENT.en);
  const feeOpts = [0, 0.01, 0.03, 0.05, 0.10];
  // claimed.you enters owner control state directly — render OwnerDelistPanel,
  // never re-run the claim flow (verify/post/terms).
  const [step, setStep] = clS(reg && reg.claimed && reg.claimed.you ? "owner" : "verify"); // verify | posting | terms | done | owner

  function errText(r) {
    const code = (r && r.error) || "request_failed";
    return L("Request failed (" + code + ") — please retry.", "请求失败（" + code + "），请重试。");
  }

  // 401 / unauthorized → clear the key (Privy logout) and surface a bilingual alert.
  function handleAuthError() {
    if (privy && typeof privy.logout === "function") {
      try { privy.logout(); } catch (e) { console.warn("[ClaimModal] privy.logout failed:", e); }
    }
    setErr(L("Session expired — please sign in again.", "登录已过期，请重新登录。"));
  }

  // Phase 1: claimStart → {code, postTemplate}. No mock fallback.
  const startClaim = async () => {
    if (busy) return;
    setBusy(true); setErr(null);
    try {
      const r = await window.RXAPI.claimStart(reg.id);
      if (!r) { setErr(L("No response from server.", "服务器无响应。")); return; }
      if (r.status === 401 || r.error === "unauthorized") { handleAuthError(); return; }
      if (r.error) { setErr(errText(r)); return; }
      setPostTemplate(r.postTemplate || "");
      setStep("posting");
    } catch (_) {
      setErr(L("Network error — please retry.", "网络错误，请重试。"));
    } finally {
      setBusy(false);
    }
  };

  const copyTemplate = async () => {
    try {
      await navigator.clipboard.writeText(postTemplate);
      setCopied(true);
      setTimeout(() => setCopied(false), 1500);
    } catch (_) {
      setErr(L("Copy failed — please copy manually.", "复制失败，请手动复制。"));
    }
  };

  // Phase 2: claimConfirm(reg.id, fee) → {ok}. Only {ok} advances to done.
  const confirmClaim = async () => {
    if (!ck || busy) return;
    setBusy(true); setErr(null);
    try {
      const r = await window.RXAPI.claimConfirm(reg.id, fee);
      if (!r) { setErr(L("No response from server.", "服务器无响应。")); return; }
      if (r.status === 401 || r.error === "unauthorized") { handleAuthError(); return; }
      if (r.error === "post_not_found") {
        setErr(L(
          "We couldn't find your post. Make sure it's public and posted from @" + reg.handle + ", then retry.",
          "未找到你的帖子。请确认帖子已公开并发布自 @" + reg.handle + "，然后重试。"
        ));
        return;
      }
      if (r.error) { setErr(errText(r)); return; }
      if (r.ok) {
        window.dispatchEvent(new CustomEvent("rx2:refresh"));
        setStep("done");
        return r.ok;
      }
      setErr(L("Verification failed — please retry.", "验证失败，请重试。"));
      return r.ok;
    } catch (_) {
      setErr(L("Network error — please retry.", "网络错误，请重试。"));
    } finally {
      setBusy(false);
    }
  };

  const intentUrl = "https://x.com/intent/post?text=" + encodeURIComponent(postTemplate);
  const errBox = err ? (
    <div className="x2-note x2-danger" role="alert"><Icon name="shield" size={13} style={{ flex: "none", marginTop: 1 }} />{err}</div>
  ) : null;

  return (
    <Modal2 title={T2("clTitle")(reg.handle)} icon="xLogo" onClose={onClose} wide>
      <div aria-live="polite">
      {step === "verify" && (
        <React.Fragment>
          <p className="x2-msub">{T2("clSub")}</p>
          <div className="v2-card" style={{ padding: 16, display: "flex", alignItems: "center", gap: 12, boxShadow: "none" }}>
            <Avatar kol={kolAdapter(reg)} size={40} radius={11} />
            <div style={{ flex: 1 }}>
              <b style={{ font: "600 14px var(--head)", color: "var(--text)" }}>{reg.name}</b>
              <div style={{ font: "400 12px var(--mono)", color: "var(--faint)" }}>@{reg.handle} · {reg.followers}</div>
            </div>
            <span className="badge-distill" style={{ color: "var(--faint)", borderColor: "var(--border)" }}>{T2("clTag")}</span>
          </div>
          {errBox}
          <button className="x2-primary" style={{ background: "#000", color: "#fff" }} onClick={startClaim} disabled={busy}>
            <Icon name="xLogo" size={14} />{busy ? L("Verifying…", "验证中…") : T2("clVerify")}
          </button>
        </React.Fragment>
      )}
      {step === "posting" && (
        <React.Fragment>
          <div className="v2-sec" style={{ margin: "0 0 6px" }}>{L("Post to X", "发布到 X")}</div>
          <p className="x2-msub">{L(
            "Copy this text and post it publicly from @" + reg.handle + ", then return and continue.",
            "复制以下文本，用 @" + reg.handle + " 账号在 X 上公开发布，然后返回继续。"
          )}</p>
          <label htmlFor="cl-post-tpl" style={{ display: "block", margin: "0 0 4px", font: "400 11.5px var(--sans)", color: "var(--faint)" }}>
            {L("Verification post template (read-only)", "验证帖模板（只读）")}
          </label>
          <textarea id="cl-post-tpl" className="v2-card" readOnly value={postTemplate}
            style={{ width: "100%", minHeight: 120, resize: "vertical", font: "400 12.5px/1.5 var(--mono)", padding: 12, boxSizing: "border-box", boxShadow: "none" }} />
          <div style={{ display: "flex", gap: 8, alignItems: "center", margin: "10px 0", flexWrap: "wrap" }}>
            <button className="btn-ghost" type="button" onClick={copyTemplate}>
              <Icon name="copy" size={13} />{copied ? L("Copied", "已复制") : L("Copy", "复制")}
            </button>
            <a className="btn-ghost" href={intentUrl} target="_blank" rel="noopener noreferrer"
              style={{ textDecoration: "none", display: "inline-flex", alignItems: "center", gap: 6 }}>
              <Icon name="xLogo" size={13} />{L("Open X to post", "打开 X 发布")}
            </a>
          </div>
          {errBox}
          <button className="x2-primary" type="button" onClick={() => { setErr(null); setStep("terms"); }}>
            <Icon name="check" size={14} />{L("I've posted — continue", "我已发布，继续")}
          </button>
        </React.Fragment>
      )}
      {step === "terms" && (
        <React.Fragment>
          <div style={{ display: "flex", alignItems: "center", gap: 8, margin: "2px 0 10px" }}>
            <Icon name="xLogo" size={14} color="var(--accent)" />
            <span style={{ font: "500 13px var(--sans)", color: "var(--text)" }}>{L("Step 3 · Owner agreement", "第 3 步 · 认领协议")} · @{reg.handle}</span>
          </div>
          <div className="v2-sec" style={{ margin: "0 0 6px" }}>{T2("clFeeTitle")}</div>
          <div className="x2-feegrid">
            {feeOpts.map((f) => (
              <button key={f} className={"x2-feeopt" + (fee === f ? " on" : "")} onClick={() => setFee(f)}>
                {f === 0 ? T2("clFeeNone") : "$" + f.toFixed(2)}
              </button>
            ))}
          </div>
          <div style={{ font: "400 11.5px/1.55 var(--sans)", color: "var(--faint)", margin: "2px 0 12px" }}>{T2("clFeeSub")(C.kolFeeMin, C.kolFeeMax)}</div>
          <div className="v2-sec" style={{ margin: "0 0 6px" }}>{T2("clAgree")}</div>
          <div className="agree">
            {LA.map(([h, p]) => (
              <React.Fragment key={h}>
                <h4>{h}</h4>
                <p style={{ margin: 0 }}>{p.replace("{h}", reg.handle)}</p>
              </React.Fragment>
            ))}
          </div>
          <label className="agree-ck">
            <input type="checkbox" checked={ck} onChange={(e) => setCk(e.target.checked)} />
            {T2("clAccept")}
          </label>
          {errBox}
          <button className="x2-primary" disabled={!ck || busy} onClick={confirmClaim}>
            <Icon name="crown" size={14} />{busy ? L("Confirming…", "确认中…") : T2("clCta")}
          </button>
        </React.Fragment>
      )}
      {step === "done" && (
        <React.Fragment>
          <div className="dst-panel" style={{ padding: "22px 6px" }}>
            <Icon name="crown" size={30} color="var(--accent)" />
            <h2 style={{ marginTop: 10 }}>{T2("clDone")}</h2>
            <p>{fee > 0
              ? (lang === "zh" ? `每次调用将收取 $${fee.toFixed(2)} 授权费，账单写明「付给本人」，净收入五五分成。` : `Every call now carries a $${fee.toFixed(2)} license fee, shown to callers as "paid to the owner". Net revenue split 50/50.`)
              : (lang === "zh" ? "当前未设置授权费，可随时在收益页开启。" : "No license fee set — you can turn it on any time from Earnings.")}</p>
          </div>
          <a
            className="btn-ghost"
            href={"https://x.com/intent/post?text=" + encodeURIComponent(T2("clShareBody")(reg.handle || "") + "\n\nhttps://app.robindex.ai/k/" + encodeURIComponent(reg.handle || reg.id) + "?utm_source=claim&utm_medium=share")}
            target="_blank"
            rel="noopener noreferrer"
            style={{ display: "inline-flex", alignItems: "center", gap: 6, marginTop: 10, textDecoration: "none" }}
            onClick={() => { try { if (window.RXA) window.RXA.track("claim_share_clicked", { kol_id: reg.id, source: "claim_done" }); } catch (_) {} }}
          >
            <Icon name="xLogo" size={13} />{T2("clShareInvite")}
          </a>
          <OwnerDelistPanel kolId={reg.id} handle={reg.handle} lang={lang} />
          <button className="x2-primary" onClick={onClose} style={{ marginTop: 12 }}>{L("OK","好的")}</button>
        </React.Fragment>
      )}
      {step === "owner" && (
        <React.Fragment>
          <div className="v2-sec" style={{ margin: "0 0 6px" }}><Icon name="crown" size={12} color="var(--accent)" />{L("Owner control", "本人管理")} · @{reg.handle}</div>
          <OwnerDelistPanel kolId={reg.id} handle={reg.handle} lang={lang} />
          <button className="x2-primary" onClick={onClose} style={{ marginTop: 12 }}>{L("OK","好的")}</button>
        </React.Fragment>
      )}
      </div>
    </Modal2>
  );
}
Object.assign(window, { ClaimModal, OwnerDelistPanel });
