/* global React, window */
// AI Playground — TWO entry points:
//   1. Raya conversational panel at the top (round 4 — modeled on the
//      real Raya product film: one-sentence command kicks off a chain).
//   2. The existing 6-demo grid + custom-prompt textarea below it, for
//      power users who'd rather pick from saved presets.
// Variant cards from either flow can be «pushed to platform» — that
// prepends a new ad to Radar with a "just created" highlight.

const { useState, useEffect, useRef } = React;

// ===== Raya conversational panel =====
// Greeting + chat bubbles + input with associative suggestion chips.
// After submit: user bubble → "thinking" dots → Raya response → 4
// variant cards animate in with a 120ms stagger.

// Curated suggestion chips. They cycle based on what the user is
// typing — empty input shows the full set; typing surfaces 3 that
// extend the partial thought.
const RAYA_SUGGESTIONS_ALL = [
  {
    matchEn: /summer|launch|seasonal/i,
    matchZh: /夏季|上新|季节|发布/,
    en: "Summer launch — 3 variants, Gen-Z audience, sustainability angle, ship by Friday",
    zh: "夏季上新 —— 3 个变体,Gen-Z 受众,环保角度,周五前上线",
  },
  {
    matchEn: /(top|winner|best|scale)/i,
    matchZh: /(赢家|最强|表现好|扩量)/,
    en: "Find my 5 top performers and make 5 variants of each, push to top-of-funnel",
    zh: "找我最强的 5 条广告,每条出 5 个改版,推到漏斗顶部",
  },
  {
    matchEn: /(coffee|drink|beverage)/i,
    matchZh: /(咖啡|饮品)/,
    en: "Cold-brew coffee, urban professionals 25-35, warm orange palette, confident-not-loud",
    zh: "冷萃咖啡,25-35 岁都市白领,暖橙色调,自信但不张扬",
  },
  {
    matchEn: /(retarget|cart|abandon)/i,
    matchZh: /(再营销|购物车|放弃)/,
    en: "Retarget cart abandoners — urgency tone, social proof, 24-hour discount",
    zh: "再营销加购未付款用户 —— 紧迫感、社交背书、24 小时优惠",
  },
  {
    matchEn: /(tee|shirt|apparel|fashion)/i,
    matchZh: /(衣|服装|时尚)/,
    en: "Fitted basics tee, men 35-45, documentary photography mood, no irony",
    zh: "修身基础款 T 恤,35-45 岁男性,纪实摄影风格,不带反讽",
  },
  {
    matchEn: /(skincare|serum|beauty)/i,
    matchZh: /(护肤|精华|美容)/,
    en: "Vitamin C serum, post-acne millennials, knowledgeable not clinical",
    zh: "维 C 精华,痘后千禧一代,专业但不冷感",
  },
  {
    matchEn: /(dinner|meal|kit|food)/i,
    matchZh: /(晚餐|套餐|食品)/,
    en: "Plant-based dinner kit, busy parents, warm honest no greenwashing",
    zh: "植物基晚餐套餐,忙父母,温暖诚实不绑架环保",
  },
  {
    matchEn: /(black friday|holiday|sale|discount)/i,
    matchZh: /(黑五|节日|促销|折扣)/,
    en: "Black Friday — 25% off, urgency overlay, last-72-hours framing",
    zh: "黑五大促 —— 25% off,紧迫感叠加,「最后 72 小时」叙事",
  },
];

function pickSuggestions(input) {
  const trimmed = (input || "").trim();
  if (!trimmed) return RAYA_SUGGESTIONS_ALL.slice(0, 4);
  const isZh = window.getLang() === "zh";
  const matched = RAYA_SUGGESTIONS_ALL.filter(s => (isZh ? s.matchZh : s.matchEn).test(trimmed));
  if (matched.length >= 3) return matched.slice(0, 3);
  // Top up with non-matched
  const rest = RAYA_SUGGESTIONS_ALL.filter(s => !matched.includes(s));
  return [...matched, ...rest].slice(0, 3);
}

function ThinkingDots() {
  return (
    <span style={{ display: "inline-flex", gap: 4, paddingLeft: 2 }}>
      {[0, 1, 2].map(i => (
        <span
          key={i}
          style={{
            width: 6, height: 6, borderRadius: "50%",
            background: "var(--ink-3)",
            display: "inline-block",
            animation: `raya-blink 1.2s ${i * 0.15}s infinite`,
          }}
        />
      ))}
    </span>
  );
}

function RayaBubble({ side, children, accent }) {
  const isUser = side === "user";
  return (
    <div
      style={{
        display: "flex",
        justifyContent: isUser ? "flex-end" : "flex-start",
        marginBottom: 10,
        animation: "raya-bubble-in 0.32s ease-out",
      }}
    >
      {!isUser && (
        <div
          style={{
            width: 30, height: 30, borderRadius: "50%",
            background: "var(--accent)", color: "var(--accent-ink)",
            display: "grid", placeItems: "center",
            fontFamily: "Source Serif 4, Georgia, serif",
            fontWeight: 600, fontSize: 14, fontStyle: "italic",
            flexShrink: 0, marginRight: 10,
          }}
        >R</div>
      )}
      <div
        style={{
          maxWidth: "78%",
          padding: "10px 14px",
          borderRadius: isUser ? "14px 14px 4px 14px" : "14px 14px 14px 4px",
          background: isUser
            ? "var(--card)"
            : (accent ? "var(--accent-tint)" : "var(--bg-deep)"),
          border: isUser ? "1px solid var(--rule-strong)" : "1px solid var(--accent-tint-2)",
          color: "var(--ink)",
          fontSize: 13.5,
          lineHeight: 1.55,
          whiteSpace: "pre-wrap",
        }}
      >
        {children}
      </div>
    </div>
  );
}

function RayaPanel({ onSubmit, scaffoldPrompt, onConsumeScaffold, history, thinking, replyDraft }) {
  const t = window.useT();
  const isZh = window.getLang() === "zh";
  const { Icon } = window;
  const [input, setInput] = useState("");
  const [focused, setFocused] = useState(false);
  const inputRef = useRef(null);
  const suggestions = pickSuggestions(input);

  // Consume scaffold prompt (from "+ create" modal) — focus input + fill.
  useEffect(() => {
    if (scaffoldPrompt) {
      setInput(scaffoldPrompt);
      if (inputRef.current) {
        inputRef.current.focus();
        // Move caret to end
        const len = scaffoldPrompt.length;
        setTimeout(() => inputRef.current.setSelectionRange(len, len), 30);
      }
      onConsumeScaffold && onConsumeScaffold();
    }
  }, [scaffoldPrompt]);

  function handleSubmit() {
    const trimmed = input.trim();
    if (!trimmed || thinking) return;
    onSubmit(trimmed);
    setInput("");
  }

  return (
    <div
      style={{
        background: "linear-gradient(160deg, var(--accent-tint) 0%, var(--card) 100%)",
        border: "1px solid var(--accent-tint-2)",
        borderRadius: 10,
        padding: "22px 24px 18px",
        marginTop: 24,
        boxShadow: "0 4px 18px rgba(209, 74, 31, 0.06)",
      }}
    >
      {/* Header: Raya identity */}
      <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 14 }}>
        <div
          style={{
            width: 40, height: 40, borderRadius: "50%",
            background: "var(--accent)", color: "var(--accent-ink)",
            display: "grid", placeItems: "center",
            fontFamily: "Source Serif 4, Georgia, serif",
            fontWeight: 700, fontSize: 19, fontStyle: "italic",
            boxShadow: "0 0 0 4px rgba(209, 74, 31, 0.15)",
          }}
        >R</div>
        <div>
          <div className="serif" style={{ fontSize: 19, lineHeight: 1, color: "var(--ink)" }}>
            {t("Raya", "Raya")}
            <span className="mono" style={{ fontSize: 9, marginLeft: 8, padding: "1px 6px", background: "var(--accent)", color: "var(--accent-ink)", borderRadius: 2, letterSpacing: ".08em", fontWeight: 600, verticalAlign: "middle" }}>HOT</span>
          </div>
          <div className="label" style={{ marginTop: 4, color: "var(--accent)" }}>
            {t("Atria's AI Creative Agent · ad creation in one sentence", "Atria 的 AI 创意代理 · 一句话生成广告")}
          </div>
        </div>
      </div>

      {/* Chat history */}
      <div style={{ minHeight: 60, marginBottom: 10 }}>
        {/* Default greeting if no history */}
        {history.length === 0 && (
          <RayaBubble side="raya" accent>
            {t(
              "Hi, I'm Raya. Tell me what to make — I'll pull your top performers + competitor cues, generate variants, and ping you when they're ready to push live.",
              "嗨,我是 Raya。告诉我要做什么 —— 我会调出你的最强广告 + 竞品参考、生成变体,搞定了 ping 你上线。"
            )}
          </RayaBubble>
        )}
        {history.map((msg, i) => (
          <RayaBubble key={i} side={msg.side} accent={msg.side !== "user"}>
            {msg.text}
          </RayaBubble>
        ))}
        {thinking && (
          <RayaBubble side="raya" accent>
            <ThinkingDots />
            <span className="mono" style={{ fontSize: 10, marginLeft: 8, color: "var(--ink-3)", letterSpacing: ".04em" }}>
              {t("Raya is working…", "Raya 正在思考…")}
            </span>
          </RayaBubble>
        )}
        {replyDraft && (
          <RayaBubble side="raya" accent>
            {replyDraft}
          </RayaBubble>
        )}
      </div>

      {/* Input + send */}
      <div
        style={{
          background: "var(--card)",
          border: focused ? "1.5px solid var(--accent)" : "1px solid var(--rule-strong)",
          borderRadius: 8,
          padding: "10px 12px",
          transition: "border-color .15s",
        }}
      >
        <textarea
          ref={inputRef}
          value={input}
          onChange={e => setInput(e.target.value)}
          onFocus={() => setFocused(true)}
          onBlur={() => setFocused(false)}
          onKeyDown={e => {
            if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
              e.preventDefault();
              handleSubmit();
            }
          }}
          placeholder={t(
            "Say what you want — «3 variants of my top coffee ad for Gen-Z», or «retarget cart abandoners with 24h urgency»…",
            "说你想要什么 —— 比如「把我最强的咖啡广告出 3 个 Gen-Z 改版」、「再营销加购未付款用户,24 小时紧迫感」…"
          )}
          style={{
            width: "100%",
            minHeight: 50,
            border: "0",
            outline: "none",
            background: "transparent",
            fontSize: 14,
            fontFamily: "inherit",
            color: "var(--ink)",
            resize: "vertical",
          }}
        />

        {/* Associative suggestion chips */}
        <div style={{ display: "flex", flexWrap: "wrap", gap: 6, marginTop: 8, alignItems: "center" }}>
          {suggestions.map((s, i) => (
            <button
              key={`${input.length}-${i}`}
              onClick={() => setInput(isZh ? s.zh : s.en)}
              style={{
                padding: "4px 10px",
                background: "var(--bg-deep)",
                border: "1px solid var(--rule)",
                borderRadius: 999,
                fontSize: 11,
                color: "var(--ink-2)",
                cursor: "pointer",
                fontFamily: "inherit",
                animation: `raya-chip-in 0.32s ${i * 0.06}s both ease-out`,
                transition: "background .15s, border-color .15s, color .15s",
              }}
              onMouseEnter={e => { e.currentTarget.style.background = "var(--accent-tint)"; e.currentTarget.style.borderColor = "var(--accent)"; e.currentTarget.style.color = "var(--accent)"; }}
              onMouseLeave={e => { e.currentTarget.style.background = "var(--bg-deep)"; e.currentTarget.style.borderColor = "var(--rule)"; e.currentTarget.style.color = "var(--ink-2)"; }}
              title={t("Click to use this prompt", "点一下填进去")}
            >
              <Icon name="sparkle" size={9} /> {(isZh ? s.zh : s.en).slice(0, 56)}{(isZh ? s.zh : s.en).length > 56 ? "…" : ""}
            </button>
          ))}
          <span style={{ flex: 1 }} />
          <button
            className="btn primary sm"
            disabled={!input.trim() || thinking}
            onClick={handleSubmit}
            style={{ opacity: (!input.trim() || thinking) ? 0.55 : 1 }}
          >
            <Icon name="arrow" size={12} />
            {thinking ? t("Working…", "处理中…") : t("Ask Raya", "请 Raya")}
            <span className="mono" style={{ fontSize: 9, marginLeft: 4, opacity: 0.7 }}>⌘↵</span>
          </button>
        </div>
      </div>
    </div>
  );
}

// ===== Main Playground component =====

function Playground({ demos, onBackToRadar, onPushCreatedAdToRadar, scaffoldPrompt, onConsumeScaffold }) {
  const [activeId, setActiveId] = useState(demos[0]?.id);
  const [customPrompt, setCustomPrompt] = useState("");
  const [customRuns, setCustomRuns] = useState([]);
  const [generating, setGenerating] = useState(false);

  // Raya chat state
  const [rayaHistory, setRayaHistory] = useState([]);   // [{ side: "user"|"raya", text: string }]
  const [rayaThinking, setRayaThinking] = useState(false);
  const [rayaReply, setRayaReply] = useState("");        // last reply (also stored in history; this is for transient styling)
  const [rayaRuns, setRayaRuns] = useState([]);          // [{ id, prompt, variants[] }]

  const active = demos.find(d => d.id === activeId) || demos[0];
  const { Icon } = window;
  const t = window.useT();
  const isZh = window.getLang() === "zh";

  function surpriseMe() {
    const others = demos.filter(d => d.id !== activeId);
    const pick = others[Math.floor(Math.random() * others.length)];
    setActiveId(pick.id);
    setCustomPrompt("");
  }

  const promptHints = [
    {
      label: t("Coffee · Gen-Z · sustainability", "咖啡 · Gen-Z · 环保"),
      en: "Lifestyle ad for a freeze-dried coffee subscription. Target Gen-Z urban professionals 22-30. Tone: confident, slightly ironic, sustainability-aware.",
      zh: "冻干咖啡订阅服务的生活方式广告。目标:22-30 岁 Gen-Z 都市白领。基调:自信、略带反讽、有环保意识。",
    },
    {
      label: t("DTC tee · 35+ men · understated", "DTC T恤 · 35+ 男士 · 克制"),
      en: "Fitted basics tee for professional men 35-45. Tone: understated, confident, no irony. Documentary photography mood.",
      zh: "面向 35-45 岁职业男性的修身基础款 T 恤。基调:克制、自信、不带反讽。纪实摄影风格。",
    },
    {
      label: t("Plant-based dinner kit · busy parent", "植物基晚餐套餐 · 忙父母"),
      en: "Plant-based dinner kit ad. Target millennial parents who care about sustainability but want fast weeknight dinners. Warm, honest, no greenwashing.",
      zh: "植物基晚餐套餐广告。目标:关心可持续但工作日想快速做饭的千禧一代父母。温暖、诚实、不绑架环保。",
    },
    {
      label: t("Skincare · post-acne millennials", "护肤 · 痘后千禧一代"),
      en: "Vitamin C serum ad for millennials 28-40 entering more serious skincare. Tone: knowledgeable but not clinical, beauty without intimidation.",
      zh: "维 C 精华广告,面向 28-40 岁开始认真护肤的千禧一代。基调:专业但不冷感、美感不带压迫。",
    },
  ];

  function applyHint(h) {
    setCustomPrompt(isZh ? h.zh : h.en);
  }

  function handleGenerate() {
    if (!customPrompt.trim() || generating) return;
    setGenerating(true);
    setTimeout(() => {
      const seed = customRuns.length + 1;
      const variantPool = [
        { name: isZh ? "情绪开场" : "Mood opener",         desc: isZh ? "黄金时刻光,产品慢慢入画"        : "Golden-hour light, product slowly enters frame", delta: 28 + (seed * 3) % 9 },
        { name: isZh ? "对比型说明" : "Comparison angle",   desc: isZh ? "你的方案 vs 老方案,左右分屏"     : "Your solution vs the old way — split-screen",      delta: 21 + (seed * 5) % 11 },
        { name: isZh ? "数字直击" : "Numbers up front",     desc: isZh ? "把核心数字做成最大的视觉元素"     : "Make the headline number the biggest visual",      delta: 33 + (seed * 2) % 7 },
        { name: isZh ? "故事化场景" : "Day-in-the-life",    desc: isZh ? "一个微场景:某个时刻 + 产品出现" : "A micro-scene: one moment + the product appears",  delta: 17 + (seed * 4) % 14 },
      ];
      const picked = [variantPool[(seed * 2) % 4], variantPool[(seed * 2 + 1) % 4]];
      const run = {
        id: "run-" + Date.now(),
        prompt: customPrompt.trim(),
        variants: picked.map((v, i) => ({ ...v, idx: i })),
      };
      setCustomRuns(cur => [run, ...cur]);
      setCustomPrompt("");
      setGenerating(false);
    }, 1600);
  }

  // === Raya: process a user command ===
  // Pipeline: append user bubble → thinking dots → compose response →
  // generate 4 variant cards. Variant cards animate in below with stagger.
  function handleRayaSubmit(text) {
    setRayaHistory(h => [...h, { side: "user", text }]);
    setRayaThinking(true);

    setTimeout(() => {
      // Build a Raya response summarizing what she'll do.
      const reply = isZh
        ? `好的。我会做这 4 件事:\n  1. 调出最匹配你 prompt 的近期表现数据\n  2. 在你的品牌色 + 字体内,出 4 个不同方向的变体\n  3. 给每个变体估算上线后的 ROAS 提升\n  4. 等你选「推到平台」,我直接上 Meta + 在 Tasks 面板 ping 你`
        : `Got it. Here's what I'll do:\n  1. Pull your recent performance data matching this prompt\n  2. Generate 4 variants — different angles, within your brand colors + type\n  3. Estimate the ROAS lift each one is likely to produce\n  4. When you click «Push to platform», I'll upload to Meta + ping you in Tasks`;

      setRayaThinking(false);
      setRayaHistory(h => [...h, { side: "raya", text: reply }]);

      // Generate 4 variant cards after a brief beat
      setTimeout(() => {
        const seed = rayaRuns.length + 1;
        const variantPool = [
          { name: isZh ? "情绪开场" : "Mood opener",      desc: isZh ? "黄金时刻光,产品慢慢入画"          : "Golden-hour light, product slowly enters frame", delta: 28 + (seed * 3) % 9 },
          { name: isZh ? "对比叙事" : "Comparison",       desc: isZh ? "「老方案 vs 你」左右分屏"            : "Old-way vs you — split screen narrative",         delta: 21 + (seed * 5) % 11 },
          { name: isZh ? "数字直击" : "Numbers first",    desc: isZh ? "把最强的数字做成最大的视觉元素"      : "Make the headline number the biggest element",    delta: 33 + (seed * 2) % 7 },
          { name: isZh ? "故事场景" : "Day-in-the-life", desc: isZh ? "一个微场景:某个时刻 + 产品自然出现" : "A micro-scene: one moment + the product appears", delta: 17 + (seed * 4) % 14 },
        ];
        const run = {
          id: "raya-run-" + Date.now(),
          prompt: text,
          variants: variantPool.map((v, i) => ({ ...v, idx: i })),
        };
        setRayaRuns(cur => [run, ...cur]);
      }, 380);
    }, 1400);
  }

  // Variant push handler — used by all 3 surfaces (Raya, demo, custom).
  // Calls the app-level callback to prepend a new ad to Radar.
  function handlePushToRadar(v, prompt) {
    if (typeof onPushCreatedAdToRadar === "function") {
      onPushCreatedAdToRadar({ variant: v, prompt: prompt || "" });
    }
  }

  return (
    <div style={{ padding: "0 24px 60px" }}>
      {/* CSS keyframes injected with the panel so the component is
          self-contained. */}
      <style>{`
        @keyframes raya-bubble-in {
          from { opacity: 0; transform: translateY(8px); }
          to   { opacity: 1; transform: translateY(0); }
        }
        @keyframes raya-chip-in {
          from { opacity: 0; transform: translateY(4px); }
          to   { opacity: 1; transform: translateY(0); }
        }
        @keyframes raya-blink {
          0%, 80%, 100% { opacity: 0.25; }
          40%           { opacity: 1; }
        }
        @keyframes raya-card-in {
          from { opacity: 0; transform: translateY(10px) scale(0.98); }
          to   { opacity: 1; transform: translateY(0) scale(1); }
        }
      `}</style>

      <div style={{ padding: "32px 0 8px" }}>
        <div className="eyebrow">{t("Creation · AI Playground · Talk to Raya", "创意生成 · AI 实验场 · 跟 Raya 对话")}</div>
        <h1 className="t-display" style={{ margin: "6px 0 0" }}>
          <em>Playground.</em> {t("Make an ad in one sentence.", "一句话,做一个广告。")}
        </h1>
        <div style={{ marginTop: 10, color: "var(--ink-3)", fontSize: 13, maxWidth: 720 }}>
          {t(
            "Talk to Raya — Atria's AI creative agent. Say what you want; she'll pull your performance data, generate 4 variants, and push the winner straight to Meta when you say go. Don't know what to say? Pick a suggestion chip below the input, or scroll down for ready-made demos.",
            "跟 Raya 对话 —— Atria 的 AI 创意代理。说你想要什么,她会调出你的投放数据、出 4 个变体,你点「推到平台」她直接上 Meta。不知道说什么?点输入框下面的灵感 chip,或者往下滑看现成的样例。"
          )}
        </div>
      </div>

      <RayaPanel
        onSubmit={handleRayaSubmit}
        scaffoldPrompt={scaffoldPrompt}
        onConsumeScaffold={onConsumeScaffold}
        history={rayaHistory}
        thinking={rayaThinking}
        replyDraft={rayaReply}
      />

      {/* Raya's variant outputs */}
      {rayaRuns.length > 0 && (
        <div style={{ marginTop: 26 }}>
          {rayaRuns.map((run, runIdx) => (
            <div key={run.id} style={{ marginBottom: 22 }}>
              <div className="mono" style={{ fontSize: 10, color: "var(--accent)", letterSpacing: ".06em", textTransform: "uppercase", marginBottom: 6 }}>
                {t(`Raya · run ${rayaRuns.length - runIdx}`, `Raya · 第 ${rayaRuns.length - runIdx} 轮`)}
              </div>
              <div style={{ fontSize: 12, color: "var(--ink-2)", lineHeight: 1.55, marginBottom: 12, fontStyle: "italic", maxWidth: 720 }}>
                「{run.prompt}」
              </div>
              <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(220px, 1fr))", gap: 12 }}>
                {run.variants.map((v, i) => (
                  <PlaygroundVariant
                    key={`${run.id}-${i}`}
                    v={v} idx={i}
                    demoId={run.id}
                    fromRaya
                    onPush={() => handlePushToRadar(v, run.prompt)}
                    stagger={i}
                  />
                ))}
              </div>
            </div>
          ))}
        </div>
      )}

      <div className="hr" style={{ marginTop: 36 }} />

      {/* Or pick from saved demos */}
      <div style={{ marginTop: 28 }}>
        <div className="label" style={{ marginBottom: 6 }}>
          {t("Or pick from saved demos →", "或者从样例库里挑一个 →")}
        </div>
        <div style={{ fontSize: 12, color: "var(--ink-3)", marginBottom: 12, maxWidth: 680 }}>
          {t(
            "Six prompt × variant presets the team has been iterating on. Useful when you want to see what «good» looks like before talking to Raya.",
            "团队这阵子在迭代的 6 组 prompt + 变体预设。在跟 Raya 对话之前,先看看「好的产出长什么样」。"
          )}
        </div>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(220px, 1fr))", gap: 10 }}>
          {demos.map(d => {
            const isActive = d.id === activeId;
            return (
              <button
                key={d.id}
                onClick={() => { setActiveId(d.id); setCustomPrompt(""); }}
                style={{
                  textAlign: "left",
                  padding: "12px 14px",
                  background: isActive ? "var(--accent-tint)" : "var(--card)",
                  border: isActive ? "1.5px solid var(--accent)" : "1px solid var(--rule)",
                  borderRadius: 4,
                  cursor: "pointer",
                  display: "flex", flexDirection: "column", gap: 4,
                  transition: "background .15s, border-color .15s",
                }}
                onMouseEnter={e => { if (!isActive) e.currentTarget.style.background = "var(--bg-deep)"; }}
                onMouseLeave={e => { if (!isActive) e.currentTarget.style.background = "var(--card)"; }}
              >
                <span className="mono" style={{ fontSize: 9, color: isActive ? "var(--accent)" : "var(--ink-3)", letterSpacing: ".08em" }}>
                  {t("DEMO", "样例")} {demos.indexOf(d) + 1}/{demos.length}
                </span>
                <span className="serif" style={{ fontSize: 14, fontWeight: 600, lineHeight: 1.3 }}>
                  {isZh && d.titleZh ? d.titleZh : d.title}
                </span>
                <span className="mono" style={{ fontSize: 10, color: "var(--ink-3)", marginTop: 2 }}>
                  {isZh && d.styleZh ? d.styleZh : d.style}
                </span>
              </button>
            );
          })}
        </div>
        <div style={{ marginTop: 12, display: "flex", gap: 10, alignItems: "center", flexWrap: "wrap" }}>
          <button className="btn" onClick={surpriseMe}>
            <Icon name="sparkle" size={12} /> {t("Surprise me", "随机来一个")}
          </button>
          <span className="mono" style={{ fontSize: 11, color: "var(--ink-3)" }}>
            {t("Or scroll down to write your own prompt", "或者往下滑,自己写 prompt")}
          </span>
        </div>
      </div>

      {/* Active demo + variants */}
      <div style={{ marginTop: 28 }}>
        <div style={{ display: "flex", alignItems: "flex-start", gap: 16, marginBottom: 18, flexWrap: "wrap" }}>
          <div style={{ flex: 1, minWidth: 240 }}>
            <div className="label" style={{ marginBottom: 4 }}>{t("Current prompt", "当前 prompt")}</div>
            <div className="t-h2" style={{ marginBottom: 6 }}>{isZh && active.titleZh ? active.titleZh : active.title}</div>
            <div style={{ fontSize: 13, color: "var(--ink-2)", lineHeight: 1.6, maxWidth: 720 }}>
              {isZh && active.promptZh ? active.promptZh : active.promptEn}
            </div>
            <div className="mono" style={{ fontSize: 10, color: "var(--ink-4)", marginTop: 6, letterSpacing: ".06em" }}>
              {t("STYLE", "风格")} · {isZh && active.styleZh ? active.styleZh : active.style}
            </div>
          </div>
          <span
            className="mono"
            style={{
              display: "inline-flex", alignItems: "center", gap: 6,
              padding: "5px 10px",
              fontSize: 11, fontWeight: 600,
              color: "var(--grade-a)",
              background: "var(--card)",
              border: "1px solid var(--rule-strong)",
              borderRadius: 4,
              letterSpacing: ".04em",
            }}
          >
            <Icon name="check" size={11} /> {t("4 variants ready below", "下面有 4 个变体")}
          </span>
        </div>

        <div style={{
          display: "grid",
          gridTemplateColumns: "repeat(auto-fill, minmax(220px, 1fr))",
          gap: 12,
        }}>
          {active.variants.map((v, i) => (
            <PlaygroundVariant
              key={`${active.id}-${i}`}
              v={v} idx={i}
              demoId={active.id}
              onPush={() => handlePushToRadar(v, isZh && active.promptZh ? active.promptZh : active.promptEn)}
              stagger={i}
            />
          ))}
        </div>
      </div>

      {/* Custom prompt — write + generate (kept for power users) */}
      <div style={{ marginTop: 36, paddingTop: 22, borderTop: "1px solid var(--rule)" }}>
        <div className="label" style={{ marginBottom: 8 }}>{t("Or hand-write a prompt", "或者手写一个 prompt")}</div>

        <div style={{ marginBottom: 10 }}>
          <div className="mono" style={{ fontSize: 10, color: "var(--ink-3)", marginBottom: 6, letterSpacing: ".06em", textTransform: "uppercase" }}>
            {t("Try one of these shapes", "试试这几个模板(点一下填进去)")}
          </div>
          <div style={{ display: "flex", flexWrap: "wrap", gap: 6 }}>
            {promptHints.map((h, i) => (
              <button
                key={i}
                onClick={() => applyHint(h)}
                style={{
                  padding: "5px 11px",
                  background: "var(--card)",
                  border: "1px solid var(--rule-strong)",
                  borderRadius: 999,
                  fontSize: 11,
                  color: "var(--ink-2)",
                  cursor: "pointer",
                  fontFamily: "inherit",
                }}
                onMouseEnter={e => { e.currentTarget.style.background = "var(--bg-deep)"; e.currentTarget.style.borderColor = "var(--accent)"; e.currentTarget.style.color = "var(--accent)"; }}
                onMouseLeave={e => { e.currentTarget.style.background = "var(--card)"; e.currentTarget.style.borderColor = "var(--rule-strong)"; e.currentTarget.style.color = "var(--ink-2)"; }}
              >
                <Icon name="sparkle" size={10} /> {h.label}
              </button>
            ))}
          </div>
          <div className="mono" style={{ fontSize: 10, color: "var(--ink-4)", marginTop: 8, lineHeight: 1.5 }}>
            {t(
              "A good prompt usually names: (1) product or service, (2) target audience, (3) tone of voice, (4) visual style. Keep it under 2 sentences.",
              "好的 prompt 通常说清楚 4 件事:(1) 产品 / 服务、(2) 目标人群、(3) 语气基调、(4) 视觉风格。控制在 2 句话以内。"
            )}
          </div>
        </div>

        <textarea
          value={customPrompt}
          onChange={e => setCustomPrompt(e.target.value)}
          placeholder={t(
            "e.g. «Lifestyle ad for cold-brew coffee, target Gen-Z urban professionals, confident slightly-ironic tone, warm orange palette».",
            "例如「冷萃咖啡的生活方式广告,目标 Gen-Z 都市白领,自信略反讽的基调,暖橙色调」"
          )}
          style={{
            width: "100%", minHeight: 80,
            padding: "10px 12px",
            border: "1px solid var(--rule-strong)",
            borderRadius: 4,
            fontSize: 13, fontFamily: "inherit",
            color: "var(--ink)",
            background: "var(--card)",
            resize: "vertical",
          }}
        />
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginTop: 8 }}>
          <span className="mono" style={{ fontSize: 10, color: "var(--ink-3)" }}>
            {customRuns.length > 0
              ? t(`${customRuns.length} run${customRuns.length > 1 ? "s" : ""} so far`, `已生成 ${customRuns.length} 轮`)
              : t("Mock mode — each Generate fakes ~1.6s + drops 2 variants below.", "演示模式 —— 每次「生成」假等 ~1.6 秒,产出 2 个变体卡。")}
          </span>
          <button
            className="btn primary"
            disabled={generating || !customPrompt.trim()}
            onClick={handleGenerate}
            style={{ opacity: (generating || !customPrompt.trim()) ? 0.55 : 1 }}
          >
            {generating
              ? <><span className="spinner" />{t("Generating…", "生成中…")}</>
              : <><Icon name="bolt" size={11} />{t("Generate 2 variants", "生成 2 个变体")}</>}
          </button>
        </div>

        {customRuns.length > 0 && (
          <div style={{ marginTop: 22, display: "flex", flexDirection: "column", gap: 18 }}>
            {customRuns.map((run, runIdx) => (
              <div key={run.id} style={{ borderTop: runIdx === 0 ? "0" : "1px solid var(--rule)", paddingTop: runIdx === 0 ? 0 : 14 }}>
                <div className="mono" style={{ fontSize: 10, color: "var(--accent)", letterSpacing: ".06em", textTransform: "uppercase", marginBottom: 4 }}>
                  {t(`Your run · ${customRuns.length - runIdx}`, `你的第 ${customRuns.length - runIdx} 次生成`)}
                </div>
                <div style={{ fontSize: 12, color: "var(--ink-2)", lineHeight: 1.55, marginBottom: 10, fontStyle: "italic", maxWidth: 720 }}>
                  「{run.prompt}」
                </div>
                <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(220px, 1fr))", gap: 12 }}>
                  {run.variants.map((v, i) => (
                    <PlaygroundVariant
                      key={`${run.id}-${i}`}
                      v={v} idx={i}
                      demoId={run.id}
                      fromCustom
                      onPush={() => handlePushToRadar(v, run.prompt)}
                      stagger={i}
                    />
                  ))}
                </div>
              </div>
            ))}
          </div>
        )}
      </div>

      <div style={{ marginTop: 28, textAlign: "center", color: "var(--ink-3)", fontSize: 11 }}>
        <button className="btn ghost sm" onClick={onBackToRadar}>← {t("Back to Radar", "返回 Radar")}</button>
      </div>
    </div>
  );
}

function PlaygroundVariant({ v, idx, demoId, fromCustom, fromRaya, onPush, stagger = 0 }) {
  const { VariantPlaceholder, Icon } = window;
  const t = window.useT();
  const accents = ["#D14A1F", "#2A5FD1", "#3D7A4F", "#8B5A2B", "#7A4D9E", "#B98424"];
  const accent = accents[(demoId.length + idx) % accents.length];

  function toast(en, zh) {
    const msg = window.t ? window.t(en, zh) : en;
    if (typeof window.__pushToast === "function") window.__pushToast(msg, "success");
  }

  return (
    <div
      style={{
        border: "1px solid var(--rule)",
        borderRadius: 4,
        background: "var(--card)",
        overflow: "hidden",
        animation: `raya-card-in 0.42s ${stagger * 0.12}s both ease-out`,
      }}
    >
      <div style={{ position: "relative", aspectRatio: "2/3" }}>
        <VariantPlaceholder
          v={{ ...v, idx, tags: [] }}
          w={220}
          h={330}
          accent={accent}
        />
        <div style={{
          position: "absolute", top: 8, right: 8,
          padding: "2px 7px",
          background: "var(--card)",
          border: "1px solid var(--rule-strong)",
          borderRadius: 3,
          fontFamily: "IBM Plex Mono, monospace",
          fontSize: 10, fontWeight: 600,
          color: v.delta >= 25 ? "var(--grade-a)" : v.delta >= 12 ? "var(--grade-b)" : "var(--grade-c)",
        }}>
          +{v.delta}% {t("est.", "预估")}
        </div>
        {fromCustom && (
          <div style={{
            position: "absolute", top: 8, left: 8,
            padding: "2px 7px",
            background: "var(--accent)", color: "var(--accent-ink)",
            fontFamily: "IBM Plex Mono, monospace",
            fontSize: 9, fontWeight: 600, letterSpacing: ".06em",
            borderRadius: 3,
          }}>{t("YOUR PROMPT", "你的 prompt")}</div>
        )}
        {fromRaya && (
          <div style={{
            position: "absolute", top: 8, left: 8,
            padding: "2px 7px",
            background: "var(--accent)", color: "var(--accent-ink)",
            fontFamily: "IBM Plex Mono, monospace",
            fontSize: 9, fontWeight: 600, letterSpacing: ".06em",
            borderRadius: 3,
          }}>{t("BY RAYA", "Raya 出的")}</div>
        )}
      </div>
      <div style={{ padding: "10px 12px" }}>
        <div className="t-h3" style={{ fontSize: 14, lineHeight: 1.3 }}>{v.name}</div>
        <div style={{ fontSize: 11, color: "var(--ink-3)", lineHeight: 1.4, marginTop: 3 }}>
          {v.desc}
        </div>
        <div style={{ display: "flex", gap: 6, marginTop: 10, flexWrap: "wrap" }}>
          <button
            className="btn sm primary"
            onClick={() => onPush ? onPush() : toast(
              `Pushed «${v.name}» to Meta Ads Manager as a new test creative.`,
              `已把「${v.name}」推到 Meta 广告管理后台 · 作为新测试创意上线`
            )}
            title={t(
              "Push this variant to Meta + jump back to Radar with the new ad highlighted.",
              "把这个变体推到 Meta + 跳回 Radar 并把新广告高亮出来。"
            )}
            style={{ flex: "1 1 auto", justifyContent: "center" }}
          >
            <Icon name="arrow" size={11} />{t("Push to platform", "推到投放平台")}
          </button>
          <button
            className="btn sm"
            onClick={() => toast(
              `Saved «${v.name}» to Image Ads.`,
              `已保存「${v.name}」到「图片广告」`
            )}
            title={t(
              "Save this variant to your Image Ads library so you (or someone else) can review later.",
              "把这个变体保存到「图片广告」库,方便之后再看 / 给同事看。"
            )}
          >
            <Icon name="download" size={11} />{t("Save", "保存")}
          </button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { Playground });
