/* Shared building blocks for all variations */
const { useState, useEffect, useRef } = React;

// === Brand icon (the LOL Gamers icon) ===
function BrandIcon({ size = 48, rounded = true }) {
  return (
    <img
      src="assets/lol-gamers-icon.webp"
      alt="LOL Gamers"
      width={size}
      height={size}
      style={{
        display: 'block',
        borderRadius: rounded ? size * 0.22 : 0,
        boxShadow: '0 4px 16px rgba(77,163,255,0.25)',
      }}
    />
  );
}

// === Hook: scroll reveal ===
function useScrollReveal(rootSelector) {
  useEffect(() => {
    const root = rootSelector ? document.querySelector(rootSelector) : document;
    if (!root) return;
    const els = root.querySelectorAll('.fade-up');
    const io = new IntersectionObserver(
      (entries) => {
        entries.forEach((e) => {
          if (e.isIntersecting) {
            e.target.classList.add('in');
            io.unobserve(e.target);
          }
        });
      },
      { threshold: 0.12, rootMargin: '0px 0px -40px 0px' }
    );
    els.forEach((el) => io.observe(el));
    return () => io.disconnect();
  }, [rootSelector]);
}

// === Animated number counter ===
function CountUp({ to, duration = 1400, suffix = '', prefix = '' }) {
  const [n, setN] = useState(0);
  const ref = useRef(null);
  const started = useRef(false);
  useEffect(() => {
    if (!ref.current) return;
    const io = new IntersectionObserver(
      (entries) => {
        entries.forEach((e) => {
          if (e.isIntersecting && !started.current) {
            started.current = true;
            const start = performance.now();
            const tick = (now) => {
              const t = Math.min(1, (now - start) / duration);
              const eased = 1 - Math.pow(1 - t, 3);
              setN(Math.floor(eased * to));
              if (t < 1) requestAnimationFrame(tick);
              else setN(to);
            };
            requestAnimationFrame(tick);
          }
        });
      },
      { threshold: 0.4 }
    );
    io.observe(ref.current);
    return () => io.disconnect();
  }, [to, duration]);
  return <span ref={ref} className="num-count">{prefix}{n.toLocaleString()}{suffix}</span>;
}

// === Discord-style real-time preview widget ===
function DiscordLivePreview({ accent = '#4DA3FF' }) {
  const [online, setOnline] = useState(847);
  const [voice, setVoice] = useState(42);
  useEffect(() => {
    const t = setInterval(() => {
      setOnline((n) => Math.max(820, Math.min(890, n + (Math.random() < 0.5 ? -1 : 1) * Math.floor(Math.random() * 4))));
      setVoice((n) => Math.max(30, Math.min(60, n + (Math.random() < 0.5 ? -1 : 1) * Math.floor(Math.random() * 3))));
    }, 1800);
    return () => clearInterval(t);
  }, []);

  const channels = [
    { type: 'text', name: 'はじめに', unread: false },
    { type: 'text', name: '雑談', unread: true },
    { type: 'text', name: 'カスタム募集', unread: true },
    { type: 'voice', name: 'カスタム部屋 #1', count: 10 },
    { type: 'voice', name: 'まったり通話', count: 5 },
    { type: 'voice', name: '初心者ロビー', count: 8 },
  ];

  return (
    <div style={{
      background: '#1A1F2E',
      borderRadius: 16,
      overflow: 'hidden',
      boxShadow: '0 24px 60px -20px rgba(15,26,46,0.35), 0 8px 24px -8px rgba(15,26,46,0.2)',
      border: '1px solid rgba(255,255,255,0.06)',
      display: 'grid',
      gridTemplateColumns: '180px 1fr',
      color: '#DCDDDE',
      fontSize: 13,
      minHeight: 380,
    }}>
      <div style={{ background: '#11141C', padding: '14px 0' }}>
        <div style={{
          padding: '0 14px 12px',
          borderBottom: '1px solid rgba(255,255,255,0.06)',
          marginBottom: 10,
          display: 'flex',
          alignItems: 'center',
          gap: 8,
        }}>
          <div style={{
            width: 26, height: 26, borderRadius: 8,
            background: 'linear-gradient(135deg, #4DA3FF, #F5C842)',
            display: 'grid', placeItems: 'center', fontSize: 11, fontWeight: 800, color: '#0F1A2E',
          }}>L</div>
          <div style={{ fontWeight: 700, color: '#fff', fontSize: 13 }}>LOL Gamers</div>
        </div>
        {channels.map((c, i) => (
          <div key={i} style={{
            padding: '5px 14px',
            display: 'flex', alignItems: 'center', gap: 6,
            color: c.unread ? '#fff' : '#8E9297',
            fontWeight: c.unread ? 600 : 400,
          }}>
            <span style={{ opacity: 0.7, fontSize: 14 }}>{c.type === 'text' ? '#' : '🔊'}</span>
            <span style={{ fontSize: 12.5, flex: 1, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{c.name}</span>
            {c.type === 'voice' && (
              <span style={{ fontSize: 10, color: accent, fontWeight: 700 }}>{c.count}</span>
            )}
            {c.unread && <span style={{ width: 6, height: 6, borderRadius: 3, background: accent }} />}
          </div>
        ))}
      </div>
      <div style={{ padding: 14, display: 'flex', flexDirection: 'column' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, paddingBottom: 10, borderBottom: '1px solid rgba(255,255,255,0.06)' }}>
          <span style={{ color: '#8E9297' }}>#</span>
          <span style={{ fontWeight: 700, color: '#fff' }}>カスタム募集</span>
          <span style={{ marginLeft: 'auto', fontSize: 11, color: '#8E9297' }}>
            <span className="dot live" style={{ background: '#22C55E', display: 'inline-block', marginRight: 6 }}></span>
            <span className="num-count">{online}</span> オンライン · 🎙 {voice}
          </span>
        </div>
        <div style={{ flex: 1, padding: '12px 4px', display: 'flex', flexDirection: 'column', gap: 12 }}>
          {[
            { u: 'みかん🍊', c: '#FF6B9D', t: '今夜21時から5v5やるよ〜！初心者枠あり🔰', m: '2分前' },
            { u: 'kuro_ADC', c: '#4DA3FF', t: '今ランクで誰か行かない？', m: '5分前' },
            { u: 'moderator', c: '#F5C842', t: '📅 週末トーナメント受付開始しました！', m: '12分前' },
          ].map((m, i) => (
            <div key={i} style={{ display: 'flex', gap: 10 }}>
              <div style={{
                width: 32, height: 32, borderRadius: '50%', flexShrink: 0,
                background: m.c, display: 'grid', placeItems: 'center',
                fontSize: 13, fontWeight: 700, color: '#fff',
              }}>{m.u[0]}</div>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 12.5 }}>
                  <span style={{ color: m.c, fontWeight: 700 }}>{m.u}</span>
                  <span style={{ color: '#72767D', marginLeft: 8, fontSize: 10 }}>{m.m}</span>
                </div>
                <div style={{ color: '#DCDDDE', fontSize: 13, marginTop: 2 }}>{m.t}</div>
              </div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

// === Bot command demo ===
function BotDemo({ accent = '#4DA3FF', accentYellow = '#F5C842' }) {
  const [step, setStep] = useState(0);
  const commands = [
    { cmd: '/rank check', desc: 'ランクをチェックして役割を自動付与', result: { user: 'あなた', rank: 'Gold IV', icon: '🥇', msg: 'ランクロール `Gold` を付与しました ✨' } },
    { cmd: '/match find', desc: '今の気分でマッチングメイト募集', result: { user: 'BOT', rank: '3人マッチしました', icon: '⚡', msg: 'kuro_ADC, みかん, naoki が参加可能です' } },
    { cmd: '/event join', desc: '開催中のカスタムに参加', result: { user: 'BOT', rank: '週末カスタム#42', icon: '🎮', msg: '参加登録完了！リマインダーを設定しました 🔔' } },
  ];
  const c = commands[step];
  return (
    <div style={{
      background: '#11141C', borderRadius: 16, padding: 18,
      boxShadow: '0 24px 60px -20px rgba(15,26,46,0.35)',
      border: '1px solid rgba(255,255,255,0.08)',
      fontFamily: "'JetBrains Mono', monospace",
      color: '#DCDDDE',
    }}>
      <div style={{ display: 'flex', gap: 8, marginBottom: 14 }}>
        {commands.map((x, i) => (
          <button
            key={i}
            onClick={() => setStep(i)}
            style={{
              flex: 1,
              background: i === step ? accent : 'rgba(255,255,255,0.06)',
              color: i === step ? '#fff' : '#9BA3B5',
              padding: '8px 10px', borderRadius: 10,
              fontSize: 11, fontWeight: 700,
              fontFamily: "'JetBrains Mono', monospace",
              transition: 'all 0.2s',
            }}>{x.cmd}</button>
        ))}
      </div>
      <div style={{ fontSize: 11, color: '#9BA3B5', marginBottom: 10 }}>{c.desc}</div>
      <div style={{ background: '#1A1F2E', borderRadius: 10, padding: 12, marginBottom: 10 }}>
        <div style={{ fontSize: 11, color: '#9BA3B5' }}>$ あなた</div>
        <div style={{ color: accent, fontSize: 14, marginTop: 2 }}>{c.cmd}</div>
      </div>
      <div key={step} style={{
        background: '#1A1F2E', borderRadius: 10, padding: 12,
        borderLeft: `3px solid ${accentYellow}`,
        animation: 'fadeInBot 0.4s ease',
      }}>
        <div style={{ fontSize: 11, color: accentYellow, fontWeight: 700 }}>🤖 LOL Bot</div>
        <div style={{ marginTop: 6, fontSize: 13, color: '#fff' }}>
          <span style={{ marginRight: 6 }}>{c.result.icon}</span>
          <strong>{c.result.rank}</strong>
        </div>
        <div style={{ marginTop: 4, fontSize: 12, color: '#DCDDDE' }}>{c.result.msg}</div>
      </div>
      <style>{`@keyframes fadeInBot { from { opacity: 0; transform: translateY(8px);} to { opacity: 1; transform: none; } }`}</style>
    </div>
  );
}

// === FAQ accordion ===
function FAQ({ items, accent = '#4DA3FF' }) {
  const [open, setOpen] = useState(0);
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
      {items.map((item, i) => {
        const isOpen = open === i;
        return (
          <div key={i} style={{
            background: '#fff',
            border: '1px solid var(--line)',
            borderRadius: 14,
            overflow: 'hidden',
            transition: 'all 0.2s',
            boxShadow: isOpen ? '0 6px 20px -8px rgba(77,163,255,0.2)' : 'none',
          }}>
            <button
              onClick={() => setOpen(isOpen ? -1 : i)}
              style={{
                width: '100%', textAlign: 'left',
                padding: '16px 18px',
                background: 'transparent',
                display: 'flex', alignItems: 'center', gap: 12,
                fontSize: 15, fontWeight: 700, color: 'var(--ink)',
              }}>
              <span style={{
                width: 26, height: 26, borderRadius: 8,
                background: isOpen ? accent : 'var(--brand-blue-soft)',
                color: isOpen ? '#fff' : accent,
                display: 'grid', placeItems: 'center',
                fontSize: 13, fontWeight: 800,
                transition: 'all 0.2s',
              }}>Q</span>
              <span style={{ flex: 1 }}>{item.q}</span>
              <span style={{
                fontSize: 18, color: 'var(--ink-3)',
                transform: isOpen ? 'rotate(45deg)' : 'none',
                transition: 'transform 0.25s',
              }}>+</span>
            </button>
            <div style={{
              maxHeight: isOpen ? 280 : 0,
              overflow: 'hidden',
              transition: 'max-height 0.3s ease',
            }}>
              <div style={{
                padding: '0 18px 18px 56px',
                color: 'var(--ink-2)',
                fontSize: 14,
                lineHeight: 1.7,
              }}>{item.a}</div>
            </div>
          </div>
        );
      })}
    </div>
  );
}

// === Stat card ===
function StatCard({ label, value, suffix, sub, color = '#4DA3FF', icon }) {
  return (
    <div style={{
      background: '#fff',
      border: '1px solid var(--line)',
      borderRadius: 16,
      padding: '20px 22px',
      position: 'relative',
      overflow: 'hidden',
    }}>
      {icon && (
        <div style={{
          position: 'absolute', top: 16, right: 16,
          width: 36, height: 36, borderRadius: 10,
          background: color + '18', color, display: 'grid', placeItems: 'center',
          fontSize: 18,
        }}>{icon}</div>
      )}
      <div style={{ fontSize: 12, color: 'var(--ink-3)', fontWeight: 600, letterSpacing: '0.04em' }}>{label}</div>
      <div style={{ fontSize: 36, fontWeight: 800, color: 'var(--ink)', marginTop: 6, lineHeight: 1, fontFamily: "'Plus Jakarta Sans', sans-serif" }}>
        <CountUp to={value} suffix={suffix} />
      </div>
      {sub && <div style={{ fontSize: 11, color: 'var(--ink-3)', marginTop: 8 }}>{sub}</div>}
    </div>
  );
}

// === Sample data ===
const FEATURES = [
  {
    icon: '🌱',
    title: '初心者から熟練者まで',
    desc: 'ランク帯別のロビーや、メンタリング制度で誰もが楽しめる仕組み。',
    tag: 'For Everyone',
  },
  {
    icon: '🎮',
    title: '定期的なカスタムイベント',
    desc: '隔週でカスタムイベントを開催。参加は簡単、開催時に指定VCに参加するだけ。',
    tag: 'Weekly Custom',
  },
  {
    icon: '🏆',
    title: '大規模イベントも開催',
    desc: '不定期で様々な形式の大会を開催。観戦専用チャンネルやYoutube配信も。',
    tag: 'Tournament',
  },
  {
    icon: '🛟',
    title: '充実の運営サポート',
    desc: 'モデレーターがサーバー体験をサポート。\n初参加ガイド、トラブル相談窓口などで\n安心して楽しめる環境を守るよ。',
    tag: 'Always On',
  },
  {
    icon: '🤖',
    title: '独自Botで楽しさ倍増',
    desc: 'カスタム自動振り分けや独自通貨によって、\nLOL Gamers独自の遊びを搭載。',
    tag: 'Custom Bot',
  },
];

const FAQS = [
  { q: 'LoLの腕前に自信がないんだけど大丈夫？', a: 'もちろん大丈夫だよ！むしろ初心者さん大歓迎。ランク帯ごとのロビーや、上手な人が教えてくれるメンター制度があるから、自分のペースで上達できるよ。' },
  { q: '参加するのにお金はかかる？', a: '完全無料で参加できます！イベントの参加費なども一切ありません。賞金つき大会の場合は別途エントリーが必要になることもあるよ。' },
  { q: 'ボイスチャットは必須？', a: '必須じゃないよ。テキストだけで楽しんでる人もたくさんいます。ボイスチャンネルは「参加してもいいし、聞き専でもOK」が基本ルール。' },
  { q: '荒らしや迷惑行為があった場合は？', a: 'モデレーターが対応してます。専用の通報チャンネルも用意してるので、気になることがあればすぐに相談してね。' },
];

const STATS = [
  { label: 'メンバー数', value: 12480, suffix: '+', sub: '先月比 +320', color: '#4DA3FF', icon: '👥' },
  { label: '今オンライン', value: 847, suffix: '', sub: 'リアルタイム', color: '#22C55E', icon: '🟢' },
  { label: '今月のイベント', value: 24, suffix: '回', sub: 'カスタム & 大会', color: '#F5C842', icon: '🎮' },
  { label: 'Bot総コマンド', value: 156, suffix: '個', sub: '日々アップデート', color: '#FF6B9D', icon: '🤖' },
];

// expose
Object.assign(window, {
  BrandIcon, useScrollReveal, CountUp,
  DiscordLivePreview, BotDemo, FAQ, StatCard,
  FEATURES, FAQS, STATS,
});
