// Brand Launch Suite — 4 specialized research modules for pre-launch validation
const { useState: useState_bl, useEffect: useEffect_bl } = React;

const KIND_TO_MODULE = {
  market_gap: 'gap',
  concept_test: 'concept',
  brand_name: 'name',
  perception: 'perception',
  pmf: 'pmf',
  top_of_mind: 'overview',
};

function LaunchSuite() {
  const [active, setActive] = useState_bl('overview');

  // Live-data plumbing: list user's campaigns, optionally pick one,
  // load its launch-suite payload from /api/campaigns/:id/launch-suite.
  const [campaigns, setCampaigns] = useState_bl([]);
  const [campaignId, setCampaignId] = useState_bl(null);
  const [suiteData, setSuiteData] = useState_bl(null);
  const [loadingSuite, setLoadingSuite] = useState_bl(false);

  useEffect_bl(() => {
    window.api
      .listCampaigns()
      .then((r) => {
        const list = r.campaigns || [];
        setCampaigns(list);
        // Auto-pick the first Launch Suite campaign if any
        const launchKinds = ['market_gap', 'concept_test', 'brand_name', 'perception', 'pmf'];
        const launchCampaign = list.find((c) => launchKinds.includes(c.kind));
        if (launchCampaign) {
          setCampaignId(launchCampaign.id);
          const m = KIND_TO_MODULE[launchCampaign.kind];
          if (m && m !== 'overview') setActive(m);
        }
      })
      .catch(() => {});
  }, []);

  useEffect_bl(() => {
    if (!campaignId) { setSuiteData(null); return; }
    setLoadingSuite(true);
    window.api
      .launchSuite(campaignId)
      .then(setSuiteData)
      .catch(() => setSuiteData(null))
      .finally(() => setLoadingSuite(false));
  }, [campaignId]);

  const modules = [
    {
      key: 'gap',
      title: 'Market Gap Survey',
      tagline: 'Validasi ada ruang di pasar',
      icon: '🎯',
      color: 'var(--primary)',
      bg: 'var(--primary-50)',
      desc: 'Ukur unmet needs, frustrasi konsumen, dan kategori yang kurang terlayani sebelum kamu invest produk baru.',
    },
    {
      key: 'concept',
      title: 'Concept Testing',
      tagline: 'Validasi idenya menarik',
      icon: '💡',
      color: 'oklch(0.55 0.16 25)',
      bg: 'oklch(0.96 0.04 25)',
      desc: 'Tes konsep produk dengan visual/deskripsi sebelum produksi. Ukur appeal, intent to buy, dan willingness-to-pay.',
    },
    {
      key: 'name',
      title: 'Brand Name Testing',
      tagline: 'Pilih nama terbaik',
      icon: '🏷',
      color: 'oklch(0.45 0.14 75)',
      bg: 'oklch(0.96 0.04 75)',
      desc: 'A/B test nama, tagline, dan logo. Lihat mana yang paling memorable, relevan, dan dipercaya target market Indonesia.',
    },
    {
      key: 'perception',
      title: 'Brand Perception Pre-launch',
      tagline: 'Pastikan persepsi sesuai visi',
      icon: '🪞',
      color: 'oklch(0.50 0.15 285)',
      bg: 'oklch(0.95 0.04 285)',
      desc: 'Cek apakah brand attribute yang ingin kamu bangun (premium, ramah, modern…) benar-benar terpancar dari materi launch-mu.',
    },
    {
      key: 'pmf',
      title: 'Product-Market Fit',
      tagline: 'Sean Ellis test — sudah klop pasar?',
      icon: '🚀',
      color: 'oklch(0.55 0.18 165)',
      bg: 'oklch(0.95 0.06 165)',
      desc: 'Ukur PMF score dari pertanyaan disappointment klasik Sean Ellis. ≥40% "sangat kecewa" = PMF achieved. Plus rangkuman target user, benefit utama, dan ide improvement.',
    },
  ];

  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: '100%', overflow: 'hidden' }}>
      <TopBar
        title="Brand Launch Suite"
        subtitle={
          suiteData
            ? `Live · ${suiteData.totalResponses} respons untuk "${suiteData.campaign.title}"`
            : '4 modul riset terstruktur untuk validasi produk & brand sebelum launching'
        }
        right={
          <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
            {campaigns.length > 0 && (
              <select
                className="select"
                value={campaignId || ''}
                onChange={(e) => {
                  setCampaignId(e.target.value || null);
                  const c = campaigns.find((x) => x.id === e.target.value);
                  if (c) {
                    const m = KIND_TO_MODULE[c.kind];
                    if (m) setActive(m);
                  }
                }}
                style={{ padding: '6px 10px', fontSize: 12.5, minWidth: 220 }}
              >
                <option value="">— pilih campaign —</option>
                {campaigns.map((c) => (
                  <option key={c.id} value={c.id}>
                    {c.title} ({c.kind})
                  </option>
                ))}
              </select>
            )}
            <button className="btn btn-soft"><I.Eye size={14} />Studi Kasus</button>
          </div>
        }
      />

      {suiteData && (
        <LiveSuiteBanner data={suiteData} loading={loadingSuite} />
      )}

      <div style={{ flex: 1, display: 'flex', overflow: 'hidden' }}>
        {/* Left: module nav */}
        <div style={{ width: 280, background: 'var(--surface)', borderRight: '1px solid var(--line)', padding: 14, overflow: 'auto' }} className="scroll">
          <button onClick={() => setActive('overview')} style={{
            width: '100%', padding: '10px 12px', textAlign: 'left',
            background: active === 'overview' ? 'var(--primary-50)' : 'transparent',
            color: active === 'overview' ? 'var(--primary)' : 'var(--ink-2)',
            border: 'none', borderRadius: 8, cursor: 'pointer', fontSize: 13.5,
            fontWeight: active === 'overview' ? 600 : 500,
            display: 'flex', alignItems: 'center', gap: 10, marginBottom: 8,
          }}>
            <I.Chart size={16} /> Overview Suite
          </button>

          <div style={{ fontSize: 10.5, color: 'var(--ink-4)', textTransform: 'uppercase', letterSpacing: '0.08em', padding: '12px 12px 6px', fontWeight: 600 }}>
            Tahapan Pre-launch
          </div>

          {modules.map((m, i) => (
            <button key={m.key} onClick={() => setActive(m.key)} style={{
              width: '100%', padding: '12px', textAlign: 'left',
              background: active === m.key ? 'var(--primary-50)' : 'transparent',
              border: active === m.key ? '1px solid oklch(0.84 0.08 155)' : '1px solid transparent',
              borderRadius: 10, cursor: 'pointer', marginBottom: 4,
              display: 'flex', gap: 10, alignItems: 'flex-start',
            }}>
              <div style={{
                width: 32, height: 32, borderRadius: 8, flexShrink: 0,
                background: m.bg, display: 'grid', placeItems: 'center', fontSize: 16,
              }}>{m.icon}</div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 11, color: 'var(--ink-3)', fontFamily: 'var(--font-mono)', fontWeight: 600 }}>0{i + 1}</div>
                <div style={{ fontSize: 13, fontWeight: 600, marginTop: 1, lineHeight: 1.3 }}>{m.title}</div>
                <div style={{ fontSize: 11.5, color: 'var(--ink-3)', marginTop: 2, lineHeight: 1.4 }}>{m.tagline}</div>
              </div>
            </button>
          ))}

          <div style={{ marginTop: 16, padding: 12, background: 'linear-gradient(135deg, var(--primary-50), var(--accent-soft))', borderRadius: 10, fontSize: 12, color: 'var(--ink-2)', lineHeight: 1.5 }}>
            <div style={{ fontWeight: 600, color: 'var(--ink)', marginBottom: 4 }}>💡 Workflow</div>
            Jalankan 4 modul berurutan untuk de-risk launching brand baru. Setiap modul punya template kuesioner siap pakai.
          </div>
        </div>

        {/* Right: content */}
        <div className="scroll" style={{ flex: 1, overflow: 'auto', background: 'var(--bg)', padding: 24 }} key={active}>
          {active === 'overview' && <SuiteOverview modules={modules} onPick={setActive} />}
          {active === 'gap' && <ModuleGap />}
          {active === 'concept' && <ModuleConcept />}
          {active === 'name' && <ModuleName />}
          {active === 'perception' && <ModulePerception />}
        </div>
      </div>
    </div>
  );
}

// ─── Live data banner ────────────────────────────────────────────────
// Renders different module-specific summary cards based on the campaign kind.
// Sits between the TopBar and the design's static module content so the user
// sees real numbers without us rewriting hundreds of lines of demo UI below.
function LiveSuiteBanner({ data, loading }) {
  const m = data.module;
  return (
    <div style={{
      flexShrink: 0, padding: '14px 18px',
      background: 'linear-gradient(135deg, var(--primary-50), var(--surface))',
      borderBottom: '1px solid oklch(0.84 0.08 155)',
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 10 }}>
        <I.Sparkle size={14} style={{ color: 'var(--primary)' }} />
        <span style={{ fontSize: 11, color: 'var(--primary)', textTransform: 'uppercase', letterSpacing: '0.06em', fontWeight: 600 }}>
          Live data · {m.label}
        </span>
        {loading && <span style={{ fontSize: 11, color: 'var(--ink-3)' }}>memuat…</span>}
        <span style={{ marginLeft: 'auto', fontSize: 11.5, color: 'var(--ink-3)' }}>
          {data.questionsCount} pertanyaan · {data.totalResponses} respons
        </span>
      </div>

      {m.kind === 'market_gap' && (
        <div style={{ display: 'grid', gridTemplateColumns: 'auto 1fr', gap: 24, alignItems: 'center' }}>
          <div>
            <div style={{ fontSize: 11, color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: '0.05em', fontWeight: 600 }}>Gap Score</div>
            <div className="mono" style={{ fontSize: 28, fontWeight: 700, color: 'var(--primary)', letterSpacing: '-0.02em', marginTop: 2 }}>{m.gapScore}</div>
            <div style={{ fontSize: 11, color: 'var(--ink-3)' }}>{m.mentionCount} mention unik</div>
          </div>
          <div>
            <div style={{ fontSize: 11, color: 'var(--ink-3)', marginBottom: 4 }}>Top mentions dari open-ended answers</div>
            <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4 }}>
              {(m.topMentions || []).slice(0, 8).map((t) => (
                <span key={t.word} className="badge" style={{ fontSize: 11 }}>
                  {t.word} <span className="mono" style={{ color: 'var(--ink-3)', marginLeft: 4 }}>×{t.n}</span>
                </span>
              ))}
              {(m.topMentions || []).length === 0 && (
                <span style={{ fontSize: 12, color: 'var(--ink-3)' }}>Belum ada open-ended answer.</span>
              )}
            </div>
          </div>
        </div>
      )}

      {m.kind === 'concept_test' && (
        <div style={{ display: 'grid', gridTemplateColumns: 'auto 1fr', gap: 24, alignItems: 'center' }}>
          <div>
            <div style={{ fontSize: 11, color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: '0.05em', fontWeight: 600 }}>Verdict</div>
            <div className="mono" style={{
              fontSize: 22, fontWeight: 700, marginTop: 2, letterSpacing: '-0.01em',
              color: m.verdict === 'Go' ? 'oklch(0.42 0.12 155)' : m.verdict === 'No-Go' ? 'var(--danger)' : 'oklch(0.55 0.16 75)',
            }}>{m.verdict}</div>
            <div style={{ fontSize: 11, color: 'var(--ink-3)' }}>Appeal {m.appeal}/10</div>
          </div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
            {(m.scales || []).slice(0, 3).map((s) => (
              <div key={s.question} style={{ fontSize: 12, color: 'var(--ink-2)' }}>
                <span style={{ fontWeight: 500 }}>{s.question}</span>
                <span className="mono" style={{ marginLeft: 8, color: 'var(--primary)', fontWeight: 600 }}>
                  {s.stats?.avg?.toFixed(1) ?? '—'}
                </span>
              </div>
            ))}
          </div>
        </div>
      )}

      {m.kind === 'brand_name' && (
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 12, fontSize: 12 }}>
          {(m.ranking || []).slice(0, 5).map((r, i) => (
            <div key={r.name} style={{ padding: '8px 12px', background: 'var(--surface)', borderRadius: 8, border: '1px solid var(--line)' }}>
              <span className="mono" style={{ color: 'var(--ink-3)', fontSize: 11 }}>#{i + 1}</span>
              <span style={{ fontWeight: 600, marginLeft: 6 }}>{r.name}</span>
              <span className="mono" style={{ color: 'var(--primary)', fontWeight: 600, marginLeft: 8 }}>×{r.n}</span>
            </div>
          ))}
          {(m.ranking || []).length === 0 && (
            <span style={{ fontSize: 12, color: 'var(--ink-3)' }}>Belum ada respons untuk diranking.</span>
          )}
        </div>
      )}

      {m.kind === 'perception' && (
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
          {(m.attributes || []).map((a) => (
            <div key={a.attribute} style={{
              padding: '8px 12px', background: 'var(--surface)',
              border: '1px solid var(--line)', borderRadius: 8, fontSize: 12, minWidth: 200,
            }}>
              <div style={{ color: 'var(--ink-2)', fontWeight: 500, fontSize: 11.5, marginBottom: 4 }}>
                {a.attribute}
              </div>
              <div style={{ display: 'flex', justifyContent: 'space-between', gap: 12 }}>
                <span style={{ color: 'var(--ink-3)' }}>Aktual <span className="mono" style={{ color: 'var(--primary)', fontWeight: 600 }}>{a.actual}</span></span>
                <span style={{ color: 'var(--ink-3)' }}>Target <span className="mono" style={{ fontWeight: 600 }}>{a.target}</span></span>
                <span style={{ color: a.gap > 1 ? 'var(--danger)' : 'oklch(0.42 0.12 155)' }}>
                  Gap <span className="mono" style={{ fontWeight: 600 }}>{a.gap}</span>
                </span>
              </div>
            </div>
          ))}
          {(m.attributes || []).length === 0 && (
            <span style={{ fontSize: 12, color: 'var(--ink-3)' }}>Belum ada pertanyaan skala untuk dihitung.</span>
          )}
        </div>
      )}

      {m.kind === 'pmf' && (
        <PMFCard m={m} />
      )}

      {m.kind === 'top_of_mind' && (
        <div style={{ fontSize: 12, color: 'var(--ink-2)' }}>
          Campaign ini bertipe <b>Top of Mind</b>. Hasil ringkas tersedia di Dashboard. Buat campaign baru dengan tipe Market Gap / Concept Test / Brand Name / Perception / PMF untuk mengaktifkan modul Launch Suite.
        </div>
      )}
    </div>
  );
}

// ─── Overview ────────────────────────────────────────────────────────
function SuiteOverview({ modules, onPick }) {
  return (
    <div className="fade-in" style={{ maxWidth: 920 }}>
      <div className="badge badge-primary" style={{ fontSize: 11.5 }}>🚀 Untuk brand yang akan launching</div>
      <h2 style={{ fontSize: 28, fontWeight: 700, letterSpacing: '-0.02em', margin: '12px 0 8px', lineHeight: 1.2 }}>
        Validasi 4 hipotesis kunci sebelum launch.
      </h2>
      <p style={{ fontSize: 14.5, color: 'var(--ink-2)', lineHeight: 1.55, maxWidth: 620, margin: 0 }}>
        Brand Launch Suite menggabungkan 4 modul riset spesialis dalam satu workflow terstruktur — dari validasi pasar hingga audit persepsi pre-launch. Hasilnya: keputusan launching berbasis data, bukan asumsi.
      </p>

      {/* Pipeline */}
      <div style={{ marginTop: 22, padding: 18, background: 'var(--surface)', border: '1px solid var(--line)', borderRadius: 14 }}>
        <div style={{ fontSize: 11.5, color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: '0.06em', fontWeight: 600, marginBottom: 12 }}>
          Pipeline Riset
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 8, position: 'relative' }}>
          {modules.map((m, i) => (
            <button key={m.key} onClick={() => onPick(m.key)} style={{
              padding: 14, background: 'var(--surface)',
              border: '1px solid var(--line)', borderRadius: 10,
              textAlign: 'left', cursor: 'pointer', position: 'relative',
            }}>
              {i < modules.length - 1 && (
                <div style={{
                  position: 'absolute', right: -6, top: '50%', width: 12, height: 12,
                  background: 'var(--bg)', borderRight: '1px solid var(--line)',
                  borderTop: '1px solid var(--line)', transform: 'translateY(-50%) rotate(45deg)',
                  zIndex: 1,
                }}></div>
              )}
              <div style={{
                width: 32, height: 32, borderRadius: 8, background: m.bg,
                display: 'grid', placeItems: 'center', fontSize: 16, marginBottom: 8,
              }}>{m.icon}</div>
              <div style={{ fontSize: 11, color: 'var(--ink-3)', fontFamily: 'var(--font-mono)', fontWeight: 600 }}>0{i + 1}</div>
              <div style={{ fontSize: 13, fontWeight: 600, marginTop: 2 }}>{m.title}</div>
              <div style={{ fontSize: 11.5, color: 'var(--ink-3)', marginTop: 2 }}>{m.tagline}</div>
            </button>
          ))}
        </div>
      </div>

      {/* Cards: status from real campaign */}
      <div style={{ marginTop: 22 }}>
        <div style={{ fontSize: 11.5, color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: '0.06em', fontWeight: 600, marginBottom: 10 }}>
          Studi Aktif · "Kopi Nusa" (sub-brand baru)
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 10 }}>
          {[
            { ic: '🎯', t: 'Market Gap', s: 'Selesai', n: 412, conclusion: '✅ Ada gap di segmen kopi spesialti kemasan ready-to-drink di Surabaya', good: true },
            { ic: '💡', t: 'Concept Testing', s: 'Selesai', n: 384, conclusion: '⚠️ Konsep "kopi rempah Nusantara" appeal 6.4/10 — perlu refinement', good: false },
            { ic: '🏷', t: 'Brand Name', s: 'Berjalan', n: 218, conclusion: '⏳ "Kopi Nusa" unggul tipis vs "Senja Brew" (38% vs 34%)', good: null },
            { ic: '🪞', t: 'Brand Perception', s: 'Belum mulai', n: 0, conclusion: 'Jadwalkan 2 minggu sebelum launch', good: null },
          ].map((c) => (
            <div key={c.t} className="card" style={{ padding: 14 }}>
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 6 }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                  <span style={{ fontSize: 16 }}>{c.ic}</span>
                  <span style={{ fontSize: 13, fontWeight: 600 }}>{c.t}</span>
                </div>
                <span className={`badge ${c.s === 'Selesai' ? 'badge-success' : ''}`} style={{ fontSize: 10.5 }}>{c.s}</span>
              </div>
              <div style={{ fontSize: 11, color: 'var(--ink-3)', marginBottom: 6 }}>{c.n > 0 ? `${c.n} responden` : '—'}</div>
              <div style={{ fontSize: 12.5, color: 'var(--ink-2)', lineHeight: 1.5 }}>{c.conclusion}</div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

// ─── Module: Market Gap ──────────────────────────────────────────────
function ModuleGap() {
  const gaps = [
    { theme: 'Kopi siap-minum kemasan kaca', score: 78, mentions: 142, sentiment: '+', desc: 'Mention "kopi botolan enak" naik 3.2× — kompetitor existing dianggap "terlalu manis" atau "rasa kopi tipis"' },
    { theme: 'Outlet 24 jam dekat kampus', score: 72, mentions: 96, sentiment: '+', desc: 'Frustrasi: tidak ada tempat ngopi serius selepas 22:00 di Sukolilo & Keputih' },
    { theme: 'Menu rendah gula / sugar-free', score: 64, mentions: 84, sentiment: '+', desc: 'Permintaan yang tumbuh dari segmen 30+, terutama wanita pekerja' },
    { theme: 'Loyalty program cashback', score: 41, mentions: 58, sentiment: '~', desc: 'Sudah jenuh — banyak kompetitor punya program serupa' },
  ];
  return (
    <div className="fade-in" style={{ maxWidth: 920 }}>
      <ModuleHeader icon="🎯" title="Market Gap Survey" tagline="Validasi ada ruang di pasar" desc="Identifikasi kebutuhan konsumen yang belum terlayani — peluang untuk produk atau positioning baru." />

      {/* Hero result */}
      <div className="card" style={{ padding: 20, marginTop: 16, background: 'linear-gradient(135deg, var(--surface), var(--primary-50))' }}>
        <div style={{ display: 'grid', gridTemplateColumns: 'auto 1fr auto', gap: 24, alignItems: 'center' }}>
          <div>
            <div style={{ fontSize: 11.5, color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: '0.06em', fontWeight: 600 }}>Gap Score Tertinggi</div>
            <div className="mono" style={{ fontSize: 36, fontWeight: 700, color: 'var(--primary)', letterSpacing: '-0.02em', marginTop: 4 }}>78<span style={{ fontSize: 18, color: 'var(--ink-3)' }}>/100</span></div>
            <div style={{ fontSize: 13, color: 'var(--ink-2)', marginTop: 4 }}>Kopi siap-minum kemasan kaca</div>
          </div>
          <div style={{ fontSize: 13, color: 'var(--ink-2)', lineHeight: 1.55, maxWidth: 360 }}>
            Dari 412 respons, 142 menyebut variasi tema ini sebagai pain point — dengan sentiment positif terhadap konsep solusi.
          </div>
          <button className="btn btn-primary"><I.Sparkle size={14} />Lanjut ke Concept Testing</button>
        </div>
      </div>

      {/* Gap leaderboard */}
      <div className="card" style={{ padding: 20, marginTop: 12 }}>
        <div style={{ fontSize: 14, fontWeight: 600, marginBottom: 12 }}>Peluang Pasar Teridentifikasi</div>
        {gaps.map((g) => (
          <div key={g.theme} style={{ display: 'grid', gridTemplateColumns: '1fr auto auto', gap: 14, padding: '12px 0', borderTop: '1px solid var(--line)', alignItems: 'center' }}>
            <div>
              <div style={{ fontSize: 13.5, fontWeight: 600 }}>{g.theme}</div>
              <div style={{ fontSize: 12, color: 'var(--ink-3)', marginTop: 3, lineHeight: 1.5 }}>{g.desc}</div>
            </div>
            <div style={{ width: 140 }}>
              <div style={{ fontSize: 10.5, color: 'var(--ink-3)', marginBottom: 3 }}>Gap Score</div>
              <div style={{ height: 6, background: 'var(--bg-2)', borderRadius: 3 }}>
                <div style={{ width: g.score + '%', height: '100%', background: g.score > 70 ? 'oklch(0.62 0.16 155)' : g.score > 50 ? 'var(--primary)' : 'var(--ink-4)', borderRadius: 3 }}></div>
              </div>
              <div className="mono" style={{ fontSize: 11, color: 'var(--ink-2)', marginTop: 3, fontWeight: 600 }}>{g.score} · {g.mentions} mention</div>
            </div>
            <I.ChevronRight size={14} style={{ color: 'var(--ink-3)' }} />
          </div>
        ))}
      </div>
    </div>
  );
}

// ─── Module: Concept Testing ─────────────────────────────────────────
function ModuleConcept() {
  const concepts = [
    { name: 'Kopi Rempah Nusantara', appeal: 6.4, intent: 38, wtp: 28000, status: 'review' },
    { name: 'Cold Brew Botolan',     appeal: 8.2, intent: 67, wtp: 32000, status: 'go' },
    { name: 'Coffee Smoothie',       appeal: 5.1, intent: 24, wtp: 22000, status: 'no-go' },
  ];
  const meta = {
    go: { color: 'oklch(0.42 0.12 155)', bg: 'var(--success-soft)', label: '✅ Lanjutkan' },
    review: { color: 'oklch(0.45 0.14 75)', bg: 'oklch(0.96 0.04 75)', label: '⚠️ Perlu refinement' },
    'no-go': { color: 'oklch(0.50 0.18 25)', bg: 'var(--danger-soft)', label: '🛑 Hentikan' },
  };
  return (
    <div className="fade-in" style={{ maxWidth: 920 }}>
      <ModuleHeader icon="💡" title="Concept Testing" tagline="Validasi idenya menarik" desc="Tes konsep produk dengan visual/deskripsi sebelum produksi. Ukur appeal, intent, dan willingness-to-pay." />

      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 12, marginTop: 16 }}>
        {concepts.map((c) => {
          const m = meta[c.status];
          return (
            <div key={c.name} className="card" style={{ padding: 16, border: c.status === 'go' ? '1.5px solid oklch(0.62 0.16 155)' : '1px solid var(--line)' }}>
              <div className="ph-img" style={{ width: '100%', aspectRatio: '4/3', marginBottom: 12, fontSize: 11 }}>KONSEP {c.name.split(' ')[0]}</div>
              <div style={{ fontSize: 14, fontWeight: 600, marginBottom: 8 }}>{c.name}</div>
              <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 6, marginBottom: 10 }}>
                <Metric label="Appeal" value={c.appeal} suffix="/10" highlight={c.appeal >= 7} />
                <Metric label="Intent" value={c.intent} suffix="%" highlight={c.intent >= 50} />
                <Metric label="WTP" value={`Rp${(c.wtp / 1000).toFixed(0)}k`} suffix="" highlight={c.wtp >= 30000} />
              </div>
              <div style={{ padding: 8, background: m.bg, color: m.color, borderRadius: 6, fontSize: 12, fontWeight: 600, textAlign: 'center' }}>
                {m.label}
              </div>
            </div>
          );
        })}
      </div>

      {/* Insight */}
      <div className="card" style={{ padding: 16, marginTop: 12, display: 'flex', gap: 12 }}>
        <div style={{ width: 36, height: 36, borderRadius: 10, background: 'var(--primary-50)', color: 'var(--primary)', display: 'grid', placeItems: 'center', flexShrink: 0 }}>
          <I.Sparkle size={16} />
        </div>
        <div style={{ fontSize: 13, color: 'var(--ink-2)', lineHeight: 1.55 }}>
          <b style={{ color: 'var(--ink)' }}>AI Insight:</b> "Cold Brew Botolan" menang di semua metrik. Drivers utama: kemudahan dibawa (mention 67%) dan rasa "tidak terlalu manis" (52%). Pertimbangkan launching kategori ini lebih dulu, dengan "Kopi Rempah" sebagai limited edition setelah refinement positioning.
        </div>
      </div>
    </div>
  );
}

// ─── Module: Brand Name Testing ──────────────────────────────────────
function ModuleName() {
  const names = [
    { name: 'Kopi Nusa',     mem: 78, rel: 72, trust: 81, pref: 38 },
    { name: 'Senja Brew',    mem: 81, rel: 68, trust: 74, pref: 34 },
    { name: 'Kopi Pagi',     mem: 64, rel: 78, trust: 70, pref: 18 },
    { name: 'Brewlokal',     mem: 58, rel: 62, trust: 64, pref: 10 },
  ];
  const max = names[0];
  return (
    <div className="fade-in" style={{ maxWidth: 920 }}>
      <ModuleHeader icon="🏷" title="Brand Name Testing" tagline="Pilih nama terbaik" desc="A/B test nama, tagline, dan logo. Lihat mana yang paling memorable, relevan, dan dipercaya target market Indonesia." />

      <div className="card" style={{ padding: 20, marginTop: 16 }}>
        <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 4 }}>
          <div style={{ fontSize: 14, fontWeight: 600 }}>Pemenang Sementara</div>
          <span style={{ fontSize: 12, color: 'var(--ink-3)' }}>Berdasarkan 218 responden · margin tipis</span>
        </div>
        <div style={{ display: 'flex', alignItems: 'baseline', gap: 12, marginTop: 8 }}>
          <span style={{ fontSize: 32, fontWeight: 700, letterSpacing: '-0.02em', color: 'var(--primary)' }}>{max.name}</span>
          <span className="mono" style={{ fontSize: 14, padding: '4px 10px', borderRadius: 6, background: 'var(--success-soft)', color: 'oklch(0.42 0.12 155)', fontWeight: 600 }}>↑ {max.pref - names[1].pref} pp vs runner-up</span>
        </div>
      </div>

      <div className="card" style={{ padding: 20, marginTop: 12 }}>
        <div style={{ fontSize: 14, fontWeight: 600, marginBottom: 14 }}>Komparasi Lengkap</div>
        <table style={{ width: '100%', fontSize: 13, borderCollapse: 'collapse' }}>
          <thead>
            <tr style={{ color: 'var(--ink-3)', fontSize: 11.5, textTransform: 'uppercase', letterSpacing: '0.05em', textAlign: 'left' }}>
              <th style={{ padding: '8px 0', fontWeight: 600 }}>Nama</th>
              <th style={{ padding: '8px 0', fontWeight: 600 }}>Memorable</th>
              <th style={{ padding: '8px 0', fontWeight: 600 }}>Relevan</th>
              <th style={{ padding: '8px 0', fontWeight: 600 }}>Trust</th>
              <th style={{ padding: '8px 0', fontWeight: 600 }}>Preference</th>
            </tr>
          </thead>
          <tbody>
            {names.map((n, i) => (
              <tr key={n.name} style={{ borderTop: '1px solid var(--line)' }}>
                <td style={{ padding: '12px 0' }}>
                  <span style={{ fontWeight: i === 0 ? 600 : 500, color: i === 0 ? 'var(--primary)' : 'var(--ink)' }}>{n.name}</span>
                  {i === 0 && <span className="badge badge-primary" style={{ marginLeft: 6, fontSize: 10 }}>WINNER</span>}
                </td>
                <td><BarCell value={n.mem} /></td>
                <td><BarCell value={n.rel} /></td>
                <td><BarCell value={n.trust} /></td>
                <td><BarCell value={n.pref} max={50} highlight={i === 0} /></td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}

// ─── Module: Brand Perception ────────────────────────────────────────
function ModulePerception() {
  const target = { Premium: 75, Modern: 80, Ramah: 60, Lokal: 85, Inovatif: 70 };
  const actual = { Premium: 62, Modern: 78, Ramah: 71, Lokal: 81, Inovatif: 54 };
  const attrs = Object.keys(target);

  return (
    <div className="fade-in" style={{ maxWidth: 920 }}>
      <ModuleHeader icon="🪞" title="Brand Perception Pre-launch" tagline="Pastikan persepsi sesuai visi" desc="Cek apakah brand attribute yang ingin kamu bangun benar-benar terpancar dari materi launch-mu." />

      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12, marginTop: 16 }}>
        {/* Radar */}
        <div className="card" style={{ padding: 20 }}>
          <div style={{ fontSize: 14, fontWeight: 600, marginBottom: 4 }}>Target vs Persepsi Aktual</div>
          <div style={{ fontSize: 12, color: 'var(--ink-3)', marginBottom: 14 }}>Skor 0-100 dari 5 atribut brand</div>
          <RadarChart target={target} actual={actual} attrs={attrs} />
          <div style={{ display: 'flex', gap: 14, fontSize: 11.5, marginTop: 10, justifyContent: 'center' }}>
            <span style={{ display: 'flex', alignItems: 'center', gap: 5 }}><span style={{ width: 10, height: 2, background: 'var(--primary)' }}></span>Persepsi aktual</span>
            <span style={{ display: 'flex', alignItems: 'center', gap: 5, color: 'var(--ink-3)' }}><span style={{ width: 10, height: 2, background: 'var(--ink-3)', borderTop: '1px dashed var(--ink-3)' }}></span>Target visi</span>
          </div>
        </div>

        {/* Gap analysis */}
        <div className="card" style={{ padding: 20 }}>
          <div style={{ fontSize: 14, fontWeight: 600, marginBottom: 14 }}>Gap Analysis</div>
          {attrs.map((a) => {
            const t = target[a], ac = actual[a];
            const gap = ac - t;
            const ok = Math.abs(gap) <= 5;
            return (
              <div key={a} style={{ padding: '10px 0', borderTop: '1px solid var(--line)' }}>
                <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 5 }}>
                  <span style={{ fontSize: 13, fontWeight: 500 }}>{a}</span>
                  <span className="mono" style={{
                    fontSize: 11.5, padding: '2px 7px', borderRadius: 5, fontWeight: 600,
                    background: ok ? 'var(--success-soft)' : gap < 0 ? 'var(--danger-soft)' : 'var(--primary-50)',
                    color: ok ? 'oklch(0.42 0.12 155)' : gap < 0 ? 'oklch(0.50 0.18 25)' : 'var(--primary)',
                  }}>{gap > 0 ? '+' : ''}{gap}</span>
                </div>
                <div style={{ position: 'relative', height: 6, background: 'var(--bg-2)', borderRadius: 3 }}>
                  <div style={{ position: 'absolute', left: 0, top: 0, height: '100%', width: ac + '%', background: 'var(--primary)', borderRadius: 3 }}></div>
                  <div style={{ position: 'absolute', left: t + '%', top: -3, width: 2, height: 12, background: 'var(--ink-2)' }}></div>
                </div>
              </div>
            );
          })}

          <div style={{ marginTop: 14, padding: 12, background: 'var(--bg-2)', borderRadius: 8, fontSize: 12, color: 'var(--ink-2)', lineHeight: 1.55 }}>
            <b style={{ color: 'var(--ink)' }}>Rekomendasi:</b> Atribut <b>"Inovatif"</b> dan <b>"Premium"</b> di bawah target. Revisi materi launch — tonjolkan teknologi proses (cold brew slow-drip) dan packaging premium di pre-launch teaser.
          </div>
        </div>
      </div>
    </div>
  );
}

// ─── Helpers ─────────────────────────────────────────────────────────
function ModuleHeader({ icon, title, tagline, desc }) {
  return (
    <div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 6 }}>
        <span style={{ fontSize: 28 }}>{icon}</span>
        <div>
          <div style={{ fontSize: 11.5, color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: '0.06em', fontWeight: 600 }}>{tagline}</div>
          <h2 style={{ fontSize: 24, fontWeight: 700, letterSpacing: '-0.015em', margin: '2px 0 0' }}>{title}</h2>
        </div>
      </div>
      <p style={{ fontSize: 13.5, color: 'var(--ink-2)', lineHeight: 1.55, margin: 0, maxWidth: 620 }}>{desc}</p>
    </div>
  );
}

function Metric({ label, value, suffix, highlight }) {
  return (
    <div style={{ padding: 8, background: 'var(--bg-2)', borderRadius: 6 }}>
      <div style={{ fontSize: 10, color: 'var(--ink-3)' }}>{label}</div>
      <div className="mono" style={{ fontSize: 15, fontWeight: 700, color: highlight ? 'oklch(0.42 0.12 155)' : 'var(--ink)', letterSpacing: '-0.01em' }}>
        {value}<span style={{ fontSize: 11, color: 'var(--ink-3)' }}>{suffix}</span>
      </div>
    </div>
  );
}

function BarCell({ value, max = 100, highlight }) {
  const pct = (value / max) * 100;
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '12px 8px 12px 0' }}>
      <div style={{ flex: 1, height: 6, background: 'var(--bg-2)', borderRadius: 3, maxWidth: 100 }}>
        <div style={{ width: pct + '%', height: '100%', background: highlight ? 'var(--primary)' : 'var(--ink-3)', borderRadius: 3 }}></div>
      </div>
      <span className="mono" style={{ fontSize: 11.5, color: 'var(--ink-2)', fontWeight: 600, minWidth: 24 }}>{value}</span>
    </div>
  );
}

function RadarChart({ target, actual, attrs }) {
  const cx = 150, cy = 130, r = 90;
  const n = attrs.length;
  const angle = (i) => -Math.PI / 2 + (i / n) * 2 * Math.PI;
  const point = (val, i) => {
    const dist = (val / 100) * r;
    return [cx + Math.cos(angle(i)) * dist, cy + Math.sin(angle(i)) * dist];
  };
  const targetPath = attrs.map((a, i) => point(target[a], i)).map((p, i) => `${i === 0 ? 'M' : 'L'} ${p[0]} ${p[1]}`).join(' ') + ' Z';
  const actualPath = attrs.map((a, i) => point(actual[a], i)).map((p, i) => `${i === 0 ? 'M' : 'L'} ${p[0]} ${p[1]}`).join(' ') + ' Z';

  return (
    <svg viewBox="0 0 300 260" style={{ width: '100%', display: 'block' }}>
      {/* gridlines */}
      {[0.25, 0.5, 0.75, 1].map((s, i) => (
        <polygon key={i}
          points={attrs.map((_, j) => {
            const dist = s * r;
            return `${cx + Math.cos(angle(j)) * dist},${cy + Math.sin(angle(j)) * dist}`;
          }).join(' ')}
          fill="none" stroke="var(--line)" strokeWidth="0.8"
        />
      ))}
      {/* spokes */}
      {attrs.map((_, i) => {
        const [x, y] = point(100, i);
        return <line key={i} x1={cx} y1={cy} x2={x} y2={y} stroke="var(--line)" strokeWidth="0.8" />;
      })}
      {/* target */}
      <path d={targetPath} fill="none" stroke="var(--ink-3)" strokeWidth="1.5" strokeDasharray="4 3" />
      {/* actual */}
      <path d={actualPath} fill="oklch(0.52 0.18 265 / 0.18)" stroke="var(--primary)" strokeWidth="2" />
      {/* labels */}
      {attrs.map((a, i) => {
        const [x, y] = point(118, i);
        return <text key={a} x={x} y={y + 4} fontSize="11" fill="var(--ink-2)" textAnchor="middle" fontWeight="500">{a}</text>;
      })}
    </svg>
  );
}

// ─── PMF card ─────────────────────────────────────────────────────────
// Renders the Sean Ellis PMF score: big number, verdict badge, breakdown
// bar, plus open-answer samples (target user / benefit / improvement).
function PMFCard({ m }) {
  const score = m.score;
  const verdict = m.verdict;
  const b = m.breakdown || { veryDisappointed: 0, somewhatDisappointed: 0, notDisappointed: 0, total: 0 };

  // Verdict copy + theme
  const verdictMeta = {
    achieved:    { label: '🎉 PMF Tercapai',     desc: '≥40% pengguna sangat kecewa kalau tidak bisa pakai lagi — ini sinyal kuat product-market fit.', color: 'oklch(0.55 0.18 165)', bg: 'oklch(0.95 0.06 165)' },
    approaching: { label: '⚡ Hampir PMF',       desc: '25-40% sangat kecewa. Sudah dekat — fokus iterasi pada apa yang membuat power user puas.',     color: 'oklch(0.55 0.16 75)',  bg: 'oklch(0.96 0.05 75)'  },
    not_yet:     { label: '🛠 Belum PMF',        desc: '<25% sangat kecewa. Masih perlu iterasi produk atau penyempitan target user yang paling cocok.', color: 'oklch(0.62 0.20 25)', bg: 'oklch(0.95 0.05 25)' },
    insufficient:{ label: '⏳ Belum cukup data', desc: 'Pertanyaan disappointment belum ada / belum ada respons. Aktifkan campaign & kumpulkan respons.', color: 'var(--ink-3)',         bg: 'var(--bg-2)'           },
  }[verdict] || { label: '—', desc: '', color: 'var(--ink-3)', bg: 'var(--bg-2)' };

  const bar = (v) => (b.total > 0 ? (v / b.total) * 100 : 0);

  // Map dari pertanyaan terbuka ke kategori PMF — pakai kata kunci sederhana
  // di teks pertanyaan untuk label section.
  const labelFor = (q) => {
    const t = (q || '').toLowerCase();
    if (/cocok|target|tipe orang|siapa.*pakai/.test(t)) return 'Target user terbaik';
    if (/benefit|manfaat|kamu dapat|gunanya/.test(t))  return 'Benefit utama';
    if (/improve|tingkatkan|perbaiki|saran/.test(t))    return 'Saran improvement';
    return 'Jawaban responden';
  };

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
      {/* Hero: Score + verdict */}
      <div style={{
        padding: 22, background: verdictMeta.bg,
        border: `1px solid ${verdictMeta.color.replace(')', ' / 0.3)')}`,
        borderRadius: 14, display: 'grid', gridTemplateColumns: 'auto 1fr', gap: 22, alignItems: 'center',
      }}>
        <div style={{ textAlign: 'center', minWidth: 140 }}>
          <div className="mono" style={{ fontSize: 56, fontWeight: 700, letterSpacing: '-0.03em', color: verdictMeta.color, lineHeight: 1 }}>
            {score == null ? '—' : `${score}%`}
          </div>
          <div style={{ fontSize: 11.5, color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: '0.08em', fontWeight: 600, marginTop: 6 }}>
            PMF Score
          </div>
        </div>
        <div>
          <div style={{ fontSize: 18, fontWeight: 700, color: verdictMeta.color, marginBottom: 4 }}>
            {verdictMeta.label}
          </div>
          <div style={{ fontSize: 13, color: 'var(--ink-2)', lineHeight: 1.55, marginBottom: 12 }}>
            {verdictMeta.desc}
          </div>

          {b.total > 0 && (
            <>
              <div style={{ display: 'flex', height: 8, borderRadius: 4, overflow: 'hidden', marginBottom: 8, background: 'var(--bg-2)' }}>
                <div style={{ width: `${bar(b.veryDisappointed)}%`, background: verdictMeta.color }} />
                <div style={{ width: `${bar(b.somewhatDisappointed)}%`, background: 'oklch(0.78 0.10 75)' }} />
                <div style={{ width: `${bar(b.notDisappointed)}%`, background: 'oklch(0.85 0.02 265)' }} />
              </div>
              <div style={{ display: 'flex', gap: 16, fontSize: 11.5, color: 'var(--ink-3)' }}>
                <span><span style={{ display: 'inline-block', width: 8, height: 8, borderRadius: 2, background: verdictMeta.color, marginRight: 5 }}></span>Sangat kecewa <b style={{ color: 'var(--ink-2)' }}>{b.veryDisappointed}</b></span>
                <span><span style={{ display: 'inline-block', width: 8, height: 8, borderRadius: 2, background: 'oklch(0.78 0.10 75)', marginRight: 5 }}></span>Sedikit kecewa <b style={{ color: 'var(--ink-2)' }}>{b.somewhatDisappointed}</b></span>
                <span><span style={{ display: 'inline-block', width: 8, height: 8, borderRadius: 2, background: 'oklch(0.85 0.02 265)', marginRight: 5 }}></span>Tidak kecewa <b style={{ color: 'var(--ink-2)' }}>{b.notDisappointed}</b></span>
                <span style={{ marginLeft: 'auto', color: 'var(--ink-2)' }}>Total {b.total} respons</span>
              </div>
            </>
          )}
        </div>
      </div>

      {/* Insufficient state */}
      {!m.questionResolved && (
        <div className="card" style={{ padding: 16, fontSize: 12.5, color: 'var(--ink-3)', background: 'var(--bg-2)' }}>
          ⚠️ Tidak ditemukan pertanyaan disappointment di campaign ini. Pastikan saat generate AI, pertanyaan pertama bertipe <b>choice</b> dengan opsi <b>"Sangat kecewa / Sedikit kecewa / Tidak kecewa"</b>.
        </div>
      )}

      {/* Open samples — target user, benefit, improvement */}
      {(m.openSamples || []).length > 0 && (
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(280px, 1fr))', gap: 12 }}>
          {m.openSamples.map((s, i) => (
            <div key={i} className="card" style={{ padding: 16 }}>
              <div style={{ fontSize: 11, color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: '0.06em', fontWeight: 600, marginBottom: 4 }}>
                {labelFor(s.question)}
              </div>
              <div style={{ fontSize: 12.5, color: 'var(--ink-2)', marginBottom: 10, fontStyle: 'italic', lineHeight: 1.4 }}>
                "{s.question}"
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                {s.samples.map((ans, j) => (
                  <div key={j} style={{
                    fontSize: 12.5, color: 'var(--ink)',
                    padding: '8px 10px', background: 'var(--bg-2)', borderRadius: 8,
                    lineHeight: 1.45,
                  }}>{ans}</div>
                ))}
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

Object.assign(window, { LaunchSuite });
