/* shell.jsx — shared chrome for the live 咔嗒Lab site.
   Exports: KadaPage, KadaNav, KadaFooter, KadaTweaks, Backdrop, Reveal,
            Avatar, useKadaTheme, plus small icons.
   Requires: components.jsx (KSITE, Logo, ThemeToggle, Arrow), tweaks-panel.jsx */

const SOFT_MAP_S = { '柔和': 0.62, '适中': 1.0, '立体': 1.5 };
const ACCENTS_S = ['#2f6df0', '#1f9cf0', '#0fb5c4', '#6366f1'];

/* ---- icons ---- */
const IcSearch = (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" {...p}><circle cx="11" cy="11" r="7" /><path d="M21 21l-4-4" /></svg>;
const IcHeart = (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M12 20s-7-4.6-9.3-9C1 7.7 2.6 4.8 5.8 4.8c2 0 3.2 1.3 4.2 2.6 1-1.3 2.2-2.6 4.2-2.6 3.2 0 4.8 2.9 3.1 6.2C19 15.4 12 20 12 20z" /></svg>;
const IcChat = (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M21 12a8 8 0 0 1-8 8H4l2-3a8 8 0 1 1 15-5z" /></svg>;
const IcPlay = (p) => <svg viewBox="0 0 24 24" fill="currentColor" {...p}><path d="M8 5.5v13l11-6.5z" /></svg>;
const IcStar = (p) => <svg viewBox="0 0 24 24" fill="currentColor" {...p}><path d="M12 3l2.6 5.3 5.9.9-4.3 4.1 1 5.8L12 17.8 6.8 19.2l1-5.8L3.5 9.2l5.9-.9z" /></svg>;
const IcUp = (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M5 12l7-7 7 7M12 5v14" /></svg>;
const IcMenu = (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" {...p}><path d="M4 7h16M4 12h16M4 17h16" /></svg>;
const IcEye = (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7z" /><circle cx="12" cy="12" r="3" /></svg>;
Object.assign(window, { IcSearch, IcHeart, IcChat, IcPlay, IcStar, IcUp, IcMenu, IcEye });

/* ---- theme ---- */
function useKadaTheme() {
  const read = () => { try { return JSON.parse(localStorage.getItem('kada.theme') || 'null'); } catch { return null; } };
  const init = Object.assign({ dark: false, accent: '#2f6df0', soft: '适中', intro: '关键词高亮', titleAnim: '拼合' }, read() || {});
  const [t, setTweak] = useTweaks(init);
  const soft = SOFT_MAP_S[t.soft] ?? 1;
  React.useEffect(() => {
    const r = document.documentElement;
    r.setAttribute('data-theme', t.dark ? 'dark' : 'light');
    r.style.setProperty('--accent', t.accent);
    r.style.setProperty('--soft', String(soft));
    document.body.classList.add('ka-body');
    try { localStorage.setItem('kada.theme', JSON.stringify({ dark: t.dark, accent: t.accent, soft: t.soft, intro: t.intro, titleAnim: t.titleAnim })); } catch {}
  }, [t.dark, t.accent, soft, t.intro, t.titleAnim]);
  return [t, setTweak];
}

/* theme context so any page can read tweak values */
const KadaCtx = React.createContext({ t: {}, setTweak: () => {} });
function useKada() { return React.useContext(KadaCtx); }

/* ---- nav ---- */
function AccountMenu() {
  const db = useKadaDB();
  const me = db.currentUser();
  const [open, setOpen] = React.useState(false);
  React.useEffect(() => {
    if (!open) return;
    const close = () => setOpen(false);
    window.addEventListener('click', close);
    return () => window.removeEventListener('click', close);
  }, [open]);
  if (!me) {
    return <a href="#auth" className="btn btn-accent" style={{ padding: '12px 24px', fontSize: 14.5 }}>加入社区</a>;
  }
  return (
    <div className="ka-acct" style={{ position: 'relative' }} onClick={(e) => e.stopPropagation()}>
      <button className="ka-acct-btn theme-toggle nm-rise-sm" onClick={() => setOpen((o) => !o)} aria-label="account" style={{ width: 'auto', padding: '6px 12px 6px 6px', gap: 9, display: 'flex', alignItems: 'center' }}>
        <Avatar name={me.name} hue={me.hue} size={30} />
        <span style={{ fontSize: 14, fontWeight: 600, color: 'var(--ink)', maxWidth: 96, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{me.name}</span>
      </button>
      {open && (
        <div className="nm-rise ka-acct-pop" style={{ position: 'absolute', right: 0, top: 'calc(100% + 10px)', minWidth: 220, borderRadius: 16, padding: 14, zIndex: 60 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 11, padding: '4px 6px 12px' }}>
            <Avatar name={me.name} hue={me.hue} size={40} />
            <span style={{ minWidth: 0 }}>
              <div style={{ fontSize: 14.5, fontWeight: 600, color: 'var(--ink)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{me.name}</div>
              <div style={{ fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--ink-faint)' }}>{me.handle}</div>
            </span>
          </div>
          <div style={{ height: 1, background: 'var(--hair)', margin: '0 2px 8px' }} />
          <a href="#post" style={{ display: 'block', padding: '10px 8px', borderRadius: 10, fontSize: 14, color: 'var(--ink-soft)', fontWeight: 500 }}>我的社区</a>
          <a href="#new_post" style={{ display: 'block', padding: '10px 8px', borderRadius: 10, fontSize: 14, color: 'var(--ink-soft)', fontWeight: 500 }}>发布帖子</a>
          <button onClick={() => { db.logout(); setOpen(false); }} style={{ width: '100%', textAlign: 'left', padding: '10px 8px', borderRadius: 10, fontSize: 14, color: 'var(--accent)', fontWeight: 600, background: 'none', border: 'none', cursor: 'pointer' }}>退出登录</button>
        </div>
      )}
    </div>
  );
}

function KadaNav({ active, dark, onToggle }) {
  const [open, setOpen] = React.useState(false);
  return (
    <div className="ka-navwrap">
      <div className="kc">
        <nav className="ka-nav nm-rise-sm">
          <a href="咔哒Lab 首页.html" aria-label="咔嗒Lab"><Logo height={34} /></a>
          <div className="links">
            {KSITE.nav.map((n) => (
              <a key={n.key} href={n.href} className={active === n.key ? 'on' : ''}>{n.label}</a>
            ))}
          </div>
          <div className="spacer" />
          <div className="right">
            <ThemeToggle dark={dark} onToggle={onToggle} />
            <AccountMenu />
            <button className="theme-toggle nm-rise-sm ka-menu-btn" onClick={() => setOpen((o) => !o)} aria-label="menu"><IcMenu style={{ width: 19, height: 19 }} /></button>
          </div>
        </nav>
        {open && (
          <div className="nm-rise" style={{ marginTop: 10, borderRadius: 18, padding: 12, display: 'flex', flexDirection: 'column', gap: 4 }}>
            {KSITE.nav.map((n) => (
              <a key={n.key} href={n.href} style={{ padding: '12px 16px', borderRadius: 12, fontWeight: 500, color: active === n.key ? 'var(--accent)' : 'var(--ink-soft)' }}>{n.label}</a>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

function KadaFooter() {
  return (
    <footer className="ka-foot">
      <div className="kc in">
        <div className="l"><Logo height={22} /><span className="cr">© 2026 咔嗒Lab · Kada Lab</span></div>
        <div className="links">
          <a href="社区活动.html">社区活动</a>
          <a href="企业活动.html">企业活动</a>
          <a href="Demo广场.html">技术广场</a>
          <a href="社区发帖.html">社区发帖</a>
          <a href="#">关于我们</a>
        </div>
      </div>
    </footer>
  );
}

function KadaTweaks({ t, setTweak }) {
  return (
    <TweaksPanel title="Tweaks">
      <TweakSection label="外观" />
      <TweakToggle label="深色模式" value={t.dark} onChange={(v) => setTweak('dark', v)} />
      <TweakColor label="点缀色" value={t.accent} options={ACCENTS_S} onChange={(v) => setTweak('accent', v)} />
      <TweakRadio label="立体感" value={t.soft} options={['柔和', '适中', '立体']} onChange={(v) => setTweak('soft', v)} />
    </TweaksPanel>
  );
}

/* ---- animated backdrop (orbs + dot grid + particles + parallax) ---- */
function Backdrop({ particles = 6 }) {
  const ref = React.useRef(null);
  React.useEffect(() => {
    const el = ref.current; if (!el) return;
    let raf = 0, tx = 0, ty = 0, cx = 0, cy = 0;
    const onMove = (e) => {
      const w = window.innerWidth, h = window.innerHeight;
      tx = (e.clientX / w - 0.5) * 2; ty = (e.clientY / h - 0.5) * 2;
      if (!raf) raf = requestAnimationFrame(tick);
    };
    const tick = () => {
      cx += (tx - cx) * 0.06; cy += (ty - cy) * 0.06;
      el.style.setProperty('--mx', cx.toFixed(3));
      el.style.setProperty('--my', cy.toFixed(3));
      raf = (Math.abs(tx - cx) > 0.002 || Math.abs(ty - cy) > 0.002) ? requestAnimationFrame(tick) : 0;
    };
    window.addEventListener('pointermove', onMove, { passive: true });
    return () => { window.removeEventListener('pointermove', onMove); cancelAnimationFrame(raf); };
  }, []);
  const pts = Array.from({ length: particles }, (_, i) => {
    const left = 8 + (i * 83) % 84;
    const dur = 11 + (i % 4) * 3.5;
    const delay = -(i * 2.3);
    const size = 3 + (i % 3) * 1.5;
    return <span key={i} className="pt" style={{ left: left + '%', bottom: '8%', width: size, height: size, animationDuration: dur + 's', animationDelay: delay + 's' }} />;
  });
  return (
    <div className="backdrop" ref={ref} aria-hidden="true">
      <span className="grid" />
      <span className="orb orb-1" />
      <span className="orb orb-2" />
      <span className="orb orb-3" />
      {pts}
    </div>
  );
}

/* ---- reveal on scroll ---- */
function Reveal({ children, delay = 0, className = '', tag = 'div', style = {} }) {
  const ref = React.useRef(null);
  const [seen, setSeen] = React.useState(false);
  React.useEffect(() => {
    const el = ref.current; if (!el) return;
    const io = new IntersectionObserver((es) => {
      es.forEach((e) => { if (e.isIntersecting) { setSeen(true); io.disconnect(); } });
    }, { threshold: 0.12, rootMargin: '0px 0px -8% 0px' });
    io.observe(el); return () => io.disconnect();
  }, []);
  const T = tag;
  return <T ref={ref} className={`reveal ${seen ? 'in' : ''} ${className}`} style={{ transitionDelay: (delay) + 'ms', ...style }}>{children}</T>;
}

function Avatar({ name, hue = 222, size = 44, className = 'ava-c' }) {
  const ch = (name || '?').trim().charAt(0).toUpperCase();
  return <span className={className} style={{ width: size, height: size, background: `linear-gradient(150deg, hsl(${hue} 58% 58%), hsl(${hue + 24} 56% 48%))` }}>{ch}</span>;
}

/* ---- page wrapper ---- */
function KadaPage({ active, children }) {
  const [t, setTweak] = useKadaTheme();
  const kids = React.Children.map(children, (ch) => React.isValidElement(ch) ? React.cloneElement(ch, { kt: t }) : ch);
  return (
    <KadaCtx.Provider value={{ t, setTweak }}>
      <div className="ka" data-page={active || 'none'}>
        <KadaNav active={active} dark={t.dark} onToggle={() => setTweak('dark', !t.dark)} />
        {kids}
        <KadaFooter />
        <KadaTweaks t={t} setTweak={setTweak} />
      </div>
    </KadaCtx.Provider>
  );
}

Object.assign(window, { useKadaTheme, useKada, KadaCtx, KadaNav, KadaFooter, KadaTweaks, Backdrop, Reveal, Avatar, KadaPage });
