/* Shared — tokens, sidebar, topbar, icons, subject chips
   Used by all three paradigma screens */

const { useState, useEffect, useRef } = React;

// ───── Design tokens (dark mode, matching SnapSnel .is-dark) ─────
const TK = {
  bg:         '#0A0F1E',
  sidebar:    '#0F1525',
  topbar:     '#111827',
  card:       '#1A2235',
  cardAlt:    '#141B2C',
  cardHi:     '#242F47',
  input:      '#1A2235',
  border:     '#1E293B',
  borderSoft: 'rgba(226,232,240,0.06)',
  fg:         '#F1F5F9',
  fgDim:      '#94A3B8',
  fgMute:     '#64748B',
  primary:    '#00B4D8',
  primaryDim: 'rgba(0,180,216,0.12)',
  primarySoft:'rgba(0,180,216,0.06)',
  gold:       '#FFD000',
  goldDim:    'rgba(255,208,0,0.14)',
  purple:     '#9D4EDD',
  purpleDim:  'rgba(157,78,221,0.14)',
  purpleFg:   '#C4B5FD',
  green:      '#22C55E',
  greenDim:   'rgba(34,197,94,0.14)',
  warn:       '#F59E0B',
  warnDim:    'rgba(245,158,11,0.14)',
  red:        '#EF4444',
  redDim:     'rgba(239,68,68,0.14)',
};

// ───── Lucide icon helper ─────
function I({ name, size = 16, color = 'currentColor', strokeWidth = 2, style, fill = 'none' }) {
  const icons = window.lucide && window.lucide.icons;
  if (!icons) return null;
  const pascal = name.split('-').map(s => s[0].toUpperCase() + s.slice(1)).join('');
  const data = icons[pascal] || icons[name];
  if (!data) return null;
  const children = Array.isArray(data) ? (data[2] || []) : (data.children || []);
  const html = children.map(c => {
    const [tag, a] = c;
    const attrs = Object.entries(a).map(([k, v]) => `${k}="${v}"`).join(' ');
    return `<${tag} ${attrs}/>`;
  }).join('');
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill={fill}
      stroke={color} strokeWidth={strokeWidth}
      strokeLinecap="round" strokeLinejoin="round"
      style={{ flexShrink: 0, ...(style || {}) }}
      dangerouslySetInnerHTML={{ __html: html }} />
  );
}

// ───── Pulse Lottie (header / corner, 24×33 default) ─────
let pulseDataPromise = null;
function getPulseData() {
  if (!pulseDataPromise) {
    pulseDataPromise = fetch('assets/pulse-idle.json').then(r => r.json());
  }
  return pulseDataPromise;
}
function PulseLottie({ size = 36, animate = true }) {
  const ref = useRef(null);
  useEffect(() => {
    if (!ref.current) return;
    let anim;
    let cancelled = false;
    if (!window.lottie) {
      // fall back: swap in svg from disk
      return;
    }
    getPulseData().then(data => {
      if (cancelled || !ref.current) return;
      anim = window.lottie.loadAnimation({
        container: ref.current,
        renderer: 'svg',
        loop: true,
        autoplay: animate,
        animationData: JSON.parse(JSON.stringify(data)),
      });
      if (!animate) anim.goToAndStop(0, true);
    });
    return () => { cancelled = true; if (anim) anim.destroy(); };
  }, [animate]);
  // Fallback to PulseMascot component (no lottie dependency)
  return <PulseMascot variant="glow" mood="happy" size="sm" />;
}

// Render small Pulse-bolt "logo" (the "S" icon)
function PulseLogoGlyph({ size = 32 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 32 32">
      <defs>
        <linearGradient id="pglogo" x1="0" y1="0" x2="1" y2="1">
          <stop offset="0%" stopColor="#00D4FF"/>
          <stop offset="100%" stopColor="#0096C7"/>
        </linearGradient>
      </defs>
      <rect x="2" y="2" width="28" height="28" rx="8" fill="url(#pglogo)"/>
      <path d="M18 6 L10 18 L14 18 L12 26 L22 14 L18 14 Z"
        fill="#FFF" stroke="#FFF" strokeWidth="0.8" strokeLinejoin="round"/>
    </svg>
  );
}

// ───── SnapSnel lockup ─────
function Lockup({ color = '#F1F5F9', primary = '#00B4D8' }) {
  return (
    <div style={{ display: 'inline-flex', alignItems: 'center', gap: 10 }}>
      <PulseLogoGlyph size={30} />
      <span style={{ fontFamily: 'Fredoka One', fontSize: 20, lineHeight: 1, letterSpacing: '-0.02em' }}>
        <span style={{ color }}>Snap</span><span style={{ color: primary }}>Snel</span>
      </span>
    </div>
  );
}

// ───── Subject token (pill + icon) ─────
const SUBJECTS = {
  biologie:     { color: '#22C55E', icon: 'leaf',          label: 'Biologie' },
  wiskunde:     { color: '#3B82F6', icon: 'calculator',    label: 'Wiskunde' },
  scheikunde:   { color: '#A855F7', icon: 'flask-conical', label: 'Scheikunde' },
  natuurkunde:  { color: '#6366F1', icon: 'zap',           label: 'Natuurkunde' },
  geschiedenis: { color: '#EC4899', icon: 'landmark',      label: 'Geschiedenis' },
  aardrijkskunde:{color: '#14B8A6', icon: 'map',           label: 'Aardrijkskunde' },
  engels:       { color: '#7C3AED', icon: 'book',          label: 'Engels' },
  nederlands:   { color: '#EF4444', icon: 'book-open-text',label: 'Nederlands' },
  frans:        { color: '#F59E0B', icon: 'languages',     label: 'Frans' },
  economie:     { color: '#10B981', icon: 'trending-up',   label: 'Economie' },
};

function SubjPill({ k, size = 'md', showIcon = true, muted = false }) {
  const s = SUBJECTS[k];
  if (!s) return null;
  const sizes = {
    sm: { h: 20, px: '0 8px', fs: 10, ic: 10, gap: 4 },
    md: { h: 24, px: '0 10px', fs: 11, ic: 12, gap: 5 },
    lg: { h: 28, px: '0 12px', fs: 12, ic: 13, gap: 6 },
  };
  const z = sizes[size];
  const op = muted ? 0.5 : 1;
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: z.gap,
      height: z.h, padding: z.px, borderRadius: 9999,
      background: `color-mix(in srgb, ${s.color} 14%, transparent)`,
      color: s.color, border: `1px solid color-mix(in srgb, ${s.color} 22%, transparent)`,
      fontFamily: 'Nunito', fontSize: z.fs, fontWeight: 800, letterSpacing: 0.1,
      opacity: op, whiteSpace: 'nowrap', flexShrink: 0,
    }}>
      {showIcon && <I name={s.icon} size={z.ic} />}
      {s.label}
    </span>
  );
}

// ───── Snaps pill ─────
function SnapsPill({ count = 240 }) {
  return (
    <div style={{
      display: 'inline-flex', alignItems: 'center', gap: 5, height: 32, padding: '0 12px',
      borderRadius: 9999, background: TK.goldDim, color: TK.gold,
      border: `1.5px solid color-mix(in srgb, ${TK.gold} 30%, transparent)`,
      fontFamily: 'Fredoka One', fontSize: 15, lineHeight: 1,
    }}>
      <I name="zap" size={13} fill="currentColor" color={TK.gold} strokeWidth={0} />
      <span style={{ marginTop: -1 }}>{count}</span>
    </div>
  );
}
function StreakPill({ count = 5 }) {
  return (
    <div style={{
      display: 'inline-flex', alignItems: 'center', gap: 4, height: 28, padding: '0 10px',
      borderRadius: 9999, background: 'rgba(249,115,22,0.14)', color: '#F97316',
      border: '1.5px solid rgba(249,115,22,0.28)',
      fontFamily: 'Nunito', fontWeight: 800, fontSize: 12,
    }}>🔥 {count}x</div>
  );
}

// ───── Premium/Pro badge ─────
function PlanBadge({ plan = 'premium', size = 'md' }) {
  // plan: 'premium' (AI coach) | 'pro' (extra)
  const spec = plan === 'pro'
    ? { bg: 'rgba(157,78,221,0.18)', fg: '#C4B5FD', bd: 'rgba(157,78,221,0.36)', label: 'Pro', icon: 'sparkles' }
    : { bg: 'rgba(255,208,0,0.14)', fg: TK.gold, bd: 'rgba(255,208,0,0.36)', label: 'Premium', icon: 'sparkles' };
  const z = size === 'sm'
    ? { h: 18, px: '0 7px', fs: 9, ic: 9, gap: 3 }
    : { h: 22, px: '0 9px', fs: 10, ic: 10, gap: 4 };
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: z.gap, height: z.h, padding: z.px,
      borderRadius: 9999, background: spec.bg, color: spec.fg, border: `1px solid ${spec.bd}`,
      fontFamily: 'Nunito', fontWeight: 800, fontSize: z.fs, letterSpacing: 0.4, textTransform: 'uppercase',
    }}>
      <I name={spec.icon} size={z.ic} fill="currentColor" strokeWidth={0} color={spec.fg} />
      {spec.label}
    </span>
  );
}

// ───── Sidebar (web, active = plannen) ─────
function Sidebar({ collapsed = false }) {
  const items = [
    { id: 'home',      label: 'Home',      icon: 'home' },
    { id: 'leren',     label: 'Leren',     icon: 'book-open' },
    { id: 'quizzen',   label: 'Quizzen',   icon: 'layers' },
    { id: 'plannen',   label: 'Plannen',   icon: 'calendar', active: true },
    { id: 'ai',        label: 'AI Coach',  icon: 'sparkles', plan: 'premium' },
    { id: 'trofeeen',  label: 'Trofeeën',  icon: 'trophy' },
  ];
  const width = collapsed ? 72 : 232;
  return (
    <aside style={{
      width, flexShrink: 0, height: '100%', background: TK.sidebar,
      borderRight: `1px solid ${TK.border}`, display: 'flex', flexDirection: 'column',
      padding: '20px 12px', boxSizing: 'border-box',
    }}>
      <div style={{ padding: '0 6px 18px', marginBottom: 12,
        borderBottom: `1px solid ${TK.border}` }}>
        <Lockup color={TK.fg} primary={TK.primary} />
      </div>
      <nav style={{ display: 'flex', flexDirection: 'column', gap: 2, flex: 1 }}>
        {items.map(it => {
          const isActive = !!it.active;
          return (
            <div key={it.id} style={{
              display: 'flex', alignItems: 'center', gap: 12, padding: '10px 12px',
              borderRadius: 10, background: isActive ? TK.primaryDim : 'transparent',
              color: isActive ? TK.primary : TK.fgDim,
              fontFamily: 'Nunito', fontWeight: isActive ? 800 : 600, fontSize: 13.5,
              cursor: 'pointer', position: 'relative',
            }}>
              <I name={it.icon} size={17} />
              <span style={{ flex: 1 }}>{it.label}</span>
              {it.plan === 'premium' && <PlanBadge plan="premium" size="sm" />}
              {isActive && <div style={{ width: 3, height: 18, background: TK.primary, borderRadius: 2 }} />}
            </div>
          );
        })}
      </nav>
      <div style={{ paddingTop: 12, borderTop: `1px solid ${TK.border}` }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: 10,
          background: TK.card, borderRadius: 10 }}>
          <div style={{ width: 34, height: 34, borderRadius: 9999,
            background: 'linear-gradient(135deg, #0096C7, #9D4EDD)',
            color: '#fff', fontWeight: 800, fontSize: 14, display: 'flex',
            alignItems: 'center', justifyContent: 'center', flexShrink: 0,
            fontFamily: 'Nunito',
          }}>S</div>
          <div style={{ minWidth: 0, flex: 1 }}>
            <div style={{ fontWeight: 800, fontSize: 13, color: TK.fg,
              overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>Sanne de Vries</div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 5, marginTop: 1 }}>
              <span style={{ fontSize: 11, fontWeight: 700, color: TK.fgMute }}>4 HAVO · lvl 12</span>
            </div>
          </div>
        </div>
      </div>
    </aside>
  );
}

// ───── Topbar with page title + snaps/streak ─────
function Topbar({ title, subtitle, rightExtra = null }) {
  return (
    <header style={{
      padding: '18px 28px', display: 'flex', alignItems: 'center', gap: 16,
      background: TK.topbar, borderBottom: `1px solid ${TK.border}`, flexShrink: 0,
    }}>
      <div style={{ minWidth: 0, flex: 1 }}>
        <div style={{ fontFamily: 'Fredoka One', fontSize: 24, lineHeight: '28px',
          color: TK.fg, letterSpacing: '-0.01em' }}>{title}</div>
        {subtitle && <div style={{ fontSize: 12.5, fontWeight: 600, color: TK.fgDim, marginTop: 3 }}>{subtitle}</div>}
      </div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexShrink: 0 }}>
        {rightExtra}
        <SnapsPill count={240} />
        <StreakPill count={5} />
        <button style={{
          width: 36, height: 36, borderRadius: 10, background: TK.card,
          border: `1px solid ${TK.border}`, color: TK.fgDim,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          cursor: 'pointer', position: 'relative',
        }}>
          <I name="bell" size={17} />
          <div style={{ position: 'absolute', top: 7, right: 7, width: 8, height: 8,
            borderRadius: 9999, background: TK.red, border: `2px solid ${TK.topbar}` }} />
        </button>
      </div>
    </header>
  );
}

// ───── Small helpers ─────
function Dot({ c = TK.primary, size = 6 }) {
  return <span style={{ display: 'inline-block', width: size, height: size, borderRadius: 9999, background: c }} />;
}

function Sectionlabel({ children, right = null, spaced = true, color = TK.fgMute }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: spaced ? 12 : 6 }}>
      <div style={{ fontSize: 11, fontWeight: 800, color, letterSpacing: 0.8, textTransform: 'uppercase' }}>{children}</div>
      <div style={{ flex: 1, height: 1, background: TK.border }} />
      {right}
    </div>
  );
}

// expose
window.TK = TK;
window.I = I;
window.Lockup = Lockup;
window.PulseLogoGlyph = PulseLogoGlyph;
window.SUBJECTS = SUBJECTS;
window.SubjPill = SubjPill;
window.SnapsPill = SnapsPill;
window.StreakPill = StreakPill;
window.PlanBadge = PlanBadge;
window.Sidebar = Sidebar;
window.Topbar = Topbar;
window.Dot = Dot;
window.Sectionlabel = Sectionlabel;
