/* ============================================================
   AliasForge — Claude-powered wanted-file generator.

   Drop-in component for the BountyBoard dossier. User pastes
   a wallet address (or anything) and we ask Claude to invent:
   - an alias (lowercase, two words)
   - an aka
   - a rap-sheet line (one offense)
   - a heat level 1-5
   - a 8-character bounty in SOL

   Output is rendered inside a Wanted-poster card. Errors fall
   back to a deterministic fake response so the UI never breaks.
   ============================================================ */

const {
  useState: useS_af,
  useRef: useR_af,
} = React;

function AliasForge({ defaultInput = "", onForged }) {
  const [input, setInput] = useS_af(defaultInput);
  const [out, setOut] = useS_af(null);
  const [loading, setLoading] = useS_af(false);
  const [err, setErr] = useS_af("");
  const cancelRef = useR_af(0);

  async function forge() {
    const myCall = ++cancelRef.current;
    setLoading(true); setErr(""); setOut(null);
    const seed = (input || "anon-wallet").trim().slice(0, 64);

    const prompt = `You are the AI from the Grand Cup Auto criminal-record department.
Given the seed below, INVENT a fictional wanted-poster file for a $GCA token holder.
Output STRICT JSON only, no prose, with these keys:
{
  "alias": "two lowercase words with underscore between them, Grand Cup Auto flavored",
  "aka": "two-word nickname in quotes",
  "crime": "one short offense, present tense, max 8 words",
  "heat": integer 1..5,
  "bountySol": integer 1..200,
  "lastSeen": "two-word lowercase location"
}
Seed: ${seed}
JSON only:`;

    try {
      const raw = await window.claude.complete(prompt);
      if (myCall !== cancelRef.current) return;
      const match = raw.match(/\{[\s\S]*\}/);
      if (!match) throw new Error("no json");
      const parsed = JSON.parse(match[0]);
      const safe = {
        alias: String(parsed.alias || "ghost_eight").toLowerCase().replace(/\s+/g, "_").slice(0, 28),
        aka:   String(parsed.aka   || "the architect").replace(/^"|"$/g, ""),
        crime: String(parsed.crime || "rug-pulled 4.2M").slice(0, 64),
        heat:  Math.max(1, Math.min(5, parseInt(parsed.heat) || 4)),
        bountySol: Math.max(1, Math.min(200, parseInt(parsed.bountySol) || 42)),
        lastSeen: String(parsed.lastSeen || "ocean drive").toLowerCase().slice(0, 24),
      };
      setOut(safe);
      onForged && onForged(safe);
    } catch (e) {
      if (myCall !== cancelRef.current) return;
      // deterministic fallback so the UI works offline
      const r = ((seed.charCodeAt(0) || 73) * 31) >>> 0;
      const fallback = {
        alias: "gca_phantom",
        aka:   "the architect",
        crime: "embezzled 6.4M via shell wallets",
        heat:  ((r % 4) + 2),
        bountySol: ((r >>> 4) % 80) + 20,
        lastSeen: "ocean drive",
      };
      setOut(fallback);
      setErr("offline file (claude unavailable)");
      onForged && onForged(fallback);
    } finally {
      if (myCall === cancelRef.current) setLoading(false);
    }
  }

  return (
    <div className="af-wrap">
      <div className="af-row">
        <input
          className="af-input"
          placeholder="paste wallet · alias · anything"
          value={input}
          onChange={e => setInput(e.target.value)}
          maxLength={80}
        />
        <button
          className="btn-sunset af-btn"
          onClick={forge}
          disabled={loading}
        >
          {loading ? "▸ generating…" : "▸ forge file"}
        </button>
      </div>
      {err && <div className="af-err mono">{err}</div>}
      {out && (
        <div className="af-poster" data-reveal>
          <div className="af-stamp">▸ wanted · grand cup auto</div>
          <div className="af-alias">{out.alias.replace(/_/g, " ")}</div>
          <div className="af-aka mono">aka "{out.aka}"</div>
          <div className="af-meta">
            <div className="af-stat">
              <div className="k">HEAT</div>
              <div className="v">
                {Array.from({ length: 5 }, (_, j) => (
                  <span key={j} style={{ opacity: j < out.heat ? 1 : 0.18 }}>★</span>
                ))}
              </div>
            </div>
            <div className="af-stat">
              <div className="k">BOUNTY</div>
              <div className="v gold mono">◎ {out.bountySol} sol</div>
            </div>
            <div className="af-stat">
              <div className="k">LAST SEEN</div>
              <div className="v mono">{out.lastSeen}</div>
            </div>
          </div>
          <div className="af-crime mono">▸ {out.crime}</div>
        </div>
      )}
    </div>
  );
}

window.AliasForge = AliasForge;
