/* qhud.jsx — Shell, HUD, Phone frame, type-badge, AnimatedFeedback anchor
   All Brief-02 components share these primitives.                         */

const { useState, useEffect, useRef } = React;

/* ─── Question-type catalog (9 tokens from cross-spec) ─── */
const QTYPE = {
  TERM_DEFINITION:  { label: 'Begrippen',     color: '#2563EB', icon: 'book-open',      slug: 'term-definition'  },
  MULTIPLE_CHOICE:  { label: 'Meerkeuze',     color: '#16A34A', icon: 'list-checks',    slug: 'multiple-choice'  },
  CONTEXTUAL:       { label: 'Contextvraag',  color: '#4F46E5', icon: 'file-text',      slug: 'contextual'       },
  FILL_IN_BLANK:    { label: 'Invulvelden',   color: '#EA580C', icon: 'pen-line',       slug: 'fill-in-blank'    },
  MATCHING:         { label: 'Koppelen',      color: '#DB2777', icon: 'link',           slug: 'matching'         },
  ORDERING:         { label: 'Volgorde',      color: '#0891B2', icon: 'arrow-up-down',  slug: 'ordering'         },
  IMAGE_BASED:      { label: 'Beeldvraag',    color: '#0D9488', icon: 'image',          slug: 'image-based'      },
  TABLE_FILL:       { label: 'Tabel invullen',color: '#7C3AED', icon: 'table',          slug: 'table-fill'       },
  MULTI_FIELD:      { label: 'Meerdere velden',color:'#D97706', icon: 'rows-3',         slug: 'multi-field'      },
};
window.QTYPE = QTYPE;

/* ─── Phone frame (iOS-ish, neutral) ─── */
function Phone({ children, dark = false, w = 360, h = 760, label, sub, scale = 1 }) {
  const cssVars = dark ? { '--frameBg': '#0A0F1E', '--frameFg': '#F1F5F9' } : { '--frameBg': '#FFFFFF', '--frameFg': '#0F172A' };
  return (
    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 10 }}>
      <div className={dark ? 'is-dark' : ''} style={{
        width: w * scale, height: h * scale,
        position: 'relative',
      }}>
        <div className={dark ? 'is-dark' : ''} style={{
          width: w, height: h,
          transform: `scale(${scale})`, transformOrigin: 'top left',
          background: 'var(--frameBg)', color: 'var(--frameFg)',
          borderRadius: 38, border: dark ? '1px solid #1E293B' : '1px solid #CBD5E1',
          boxShadow: '0 18px 48px rgba(0,0,0,0.20), 0 4px 12px rgba(0,0,0,0.10)',
          overflow: 'hidden', position: 'absolute', top: 0, left: 0,
          ...cssVars,
        }}>
          {/* Status-bar */}
          <div style={{
            height: 36, padding: '10px 22px 4px',
            display: 'flex', justifyContent: 'space-between', alignItems: 'center',
            fontSize: 13, fontWeight: 700, color: dark ? '#F1F5F9' : '#0F172A',
          }}>
            <span>09:41</span>
            <div style={{ display: 'flex', gap: 4, alignItems: 'center', opacity: 0.85 }}>
              <window.LucideIcon name="signal" size={14} />
              <window.LucideIcon name="wifi" size={14} />
              <window.LucideIcon name="battery-full" size={16} />
            </div>
          </div>
          {/* Notch sim */}
          <div style={{
            position: 'absolute', top: 8, left: '50%', transform: 'translateX(-50%)',
            width: 100, height: 26, borderRadius: 14, background: '#000',
          }}></div>
          {children}
        </div>
      </div>
      {label && (
        <div style={{ textAlign: 'center', marginTop: 6 }}>
          <div style={{ fontSize: 13, fontWeight: 800, color: '#0F172A' }}>{label}</div>
          {sub && <div style={{ fontSize: 11, color: '#64748B', marginTop: 2 }}>{sub}</div>}
        </div>
      )}
    </div>
  );
}
window.Phone = Phone;

/* ─── HUD-CORE (lean version) ─────────────────────────────────────
   Three-tier HUD philosophy:
   • Always: progress bar + X/N + points-pill (streak fused) + exit-X
   • Conditional: timer (only EXAM-mode or opt-in)
   • On-demand: hint button (bottom-right corner of card-area)
   Highscore moved out of in-quiz HUD → start-screen + result-screen only
*/
function QuizHUD({
  current = 1, total = 12,
  points = 80, streak = 0,
  pointsBumped = false,             // momentary +N flash
  delta = null,                     // e.g. "+40"
  timerSec = null,                  // null = hidden
  timerMode = 'practice',           // 'practice' | 'exam' | 'oefentoets' | 'examensim'
  dark = false,
  modeBadge = null,                 // optional mode-strip above HUD
}) {
  const fg = dark ? '#F1F5F9' : '#0F172A';
  const dim = dark ? '#94A3B8' : '#64748B';
  const border = dark ? '#1E293B' : '#E2E8F0';
  const cardBg = dark ? '#111827' : '#FFFFFF';
  const pct = Math.min(100, Math.round((current / total) * 100));
  const timerCritical = timerSec !== null && timerSec < 30;

  return (
    <div style={{ borderBottom: `1px solid ${border}`, background: cardBg }}>
      {modeBadge && (
        <div style={{
          padding: '6px 16px', fontSize: 10, fontWeight: 800, letterSpacing: 1,
          textTransform: 'uppercase',
          background: modeBadge.bg, color: modeBadge.fg,
          textAlign: 'center', borderBottom: `1px solid ${border}`,
        }}>
          {modeBadge.label}
        </div>
      )}
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '12px 14px 6px' }}>
        {/* Exit-X */}
        <button style={{
          width: 32, height: 32, borderRadius: 8, border: 'none', cursor: 'pointer',
          background: 'transparent', color: fg, display: 'grid', placeItems: 'center',
        }} aria-label="Stoppen">
          <window.LucideIcon name="x" size={18} />
        </button>

        {/* Progress block */}
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{
            display: 'flex', justifyContent: 'space-between', alignItems: 'center',
            marginBottom: 4,
          }}>
            <span style={{ fontSize: 12, fontWeight: 700, color: dim }}>
              Vraag {current} van {total}
            </span>
            {timerSec !== null && (
              <span style={{
                fontSize: 12, fontWeight: 800, fontVariantNumeric: 'tabular-nums',
                color: timerCritical ? '#DC2626' : dim,
                display: 'inline-flex', alignItems: 'center', gap: 4,
              }}>
                {timerMode === 'examensim' && (
                  <window.LucideIcon name="clock" size={12} />
                )}
                {formatTime(timerSec)}
              </span>
            )}
          </div>
          <div style={{
            height: 4, borderRadius: 2,
            background: dark ? '#1E293B' : '#E2E8F0', overflow: 'hidden',
          }}>
            <div style={{
              height: '100%', width: `${pct}%`,
              background: timerMode === 'examensim' ? '#023E8A'
                       : timerMode === 'oefentoets' ? '#16A34A'
                       : '#0096C7',
              transition: 'width .25s ease',
            }}></div>
          </div>
        </div>

        {/* Points-pill (with streak fused as flame) */}
        <div style={{
          height: 32, padding: '0 12px 0 8px', borderRadius: 999,
          background: pointsBumped ? '#FACC15' : '#FCD34D',
          display: 'inline-flex', alignItems: 'center', gap: 6,
          fontWeight: 900, fontSize: 14, color: '#451A03',
          fontVariantNumeric: 'tabular-nums',
          boxShadow: pointsBumped ? '0 0 0 4px rgba(250,204,21,0.30)' : 'none',
          transition: 'all .25s ease', position: 'relative',
        }}>
          {streak >= 3 && (
            <span style={{
              display: 'inline-flex', alignItems: 'center', gap: 2,
              fontSize: 11, color: '#7C2D12', fontWeight: 800,
              borderRight: '1px solid rgba(124,45,18,0.20)', paddingRight: 6,
            }}>
              <window.LucideIcon name="flame" size={12} />
              {streak}×
            </span>
          )}
          <window.LucideIcon name="zap" size={14} />
          {points}
          {delta && (
            <span style={{
              position: 'absolute', top: -22, right: 4,
              fontSize: 13, fontWeight: 900, color: '#16A34A',
              animation: 'floatUp 1s ease-out forwards', pointerEvents: 'none',
            }}>{delta}</span>
          )}
        </div>
      </div>
    </div>
  );
}
window.QuizHUD = QuizHUD;

function formatTime(s) {
  const m = Math.floor(s / 60);
  const r = s % 60;
  return `${String(m).padStart(2, '0')}:${String(r).padStart(2, '0')}`;
}

/* ─── Type badge — colored by qtype-token ─── */
function TypeBadge({ type, size = 'sm' }) {
  const meta = QTYPE[type];
  if (!meta) return null;
  const big = size === 'md';
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 6,
      padding: big ? '6px 12px' : '4px 10px',
      borderRadius: 999, fontSize: big ? 12 : 11,
      fontWeight: 800, letterSpacing: 0.3,
      color: meta.color,
      background: hexA(meta.color, 0.10),
      border: `1px solid ${hexA(meta.color, 0.25)}`,
    }}>
      <window.LucideIcon name={meta.icon} size={big ? 14 : 12} />
      {meta.label}
    </span>
  );
}
window.TypeBadge = TypeBadge;

function hexA(hex, a) {
  const m = hex.replace('#','');
  const r = parseInt(m.slice(0,2),16), g = parseInt(m.slice(2,4),16), b = parseInt(m.slice(4,6),16);
  return `rgba(${r},${g},${b},${a})`;
}
window.hexA = hexA;

/* ─── AnimatedFeedback — anchor pattern (subtle inline card) ───
   Used uniformly across all 9 players for correct/wrong/partial.
   No fullscreen overlays.                                       */
function AnimatedFeedback({ kind = 'correct', text, sub, dark = false, expanded = false, children }) {
  const c = {
    correct: { bg: dark ? 'rgba(34,197,94,0.12)' : '#F0FDF4', fg: '#16A34A', border: dark ? 'rgba(34,197,94,0.30)' : '#BBF7D0', icon: 'check-circle-2', mascotMood: 'happy' },
    wrong:   { bg: dark ? 'rgba(220,38,38,0.12)' : '#FEF2F2', fg: '#DC2626', border: dark ? 'rgba(220,38,38,0.30)' : '#FECACA', icon: 'x-circle',       mascotMood: 'sad'   },
    partial: { bg: dark ? 'rgba(217,119,6,0.14)' : '#FFFBEB', fg: '#D97706', border: dark ? 'rgba(217,119,6,0.30)' : '#FDE68A', icon: 'minus-circle',  mascotMood: 'thinking' },
  }[kind];
  return (
    <div style={{
      background: c.bg, border: `1px solid ${c.border}`,
      borderRadius: 14, padding: expanded ? '14px 14px 12px' : '12px 14px',
      display: 'flex', gap: 12, alignItems: 'flex-start',
    }}>
      <div style={{
        width: 36, height: 36, borderRadius: 999,
        background: hexA(c.fg, 0.14), color: c.fg,
        display: 'grid', placeItems: 'center', flexShrink: 0,
      }}>
        <window.LucideIcon name={c.icon} size={22} strokeWidth={2.5} />
      </div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontWeight: 900, fontSize: 15, color: c.fg }}>{text}</div>
        {sub && <div style={{ fontSize: 13, color: dark ? '#CBD5E1' : '#475569', marginTop: 4, lineHeight: 1.4 }}>{sub}</div>}
        {children && <div style={{ marginTop: 8 }}>{children}</div>}
      </div>
    </div>
  );
}
window.AnimatedFeedback = AnimatedFeedback;

/* ─── Bottom CTA (consistent across players) ─── */
function CtaBar({ label, onClick, disabled, kind = 'primary', dark = false, icon }) {
  const styles = {
    primary:   { bg: '#0096C7', fg: '#FFFFFF', bgD: '#94A3B8' },
    success:   { bg: '#16A34A', fg: '#FFFFFF', bgD: '#94A3B8' },
    secondary: { bg: dark ? '#1E293B' : '#F1F5F9', fg: dark ? '#F1F5F9' : '#0F172A', bgD: '#CBD5E1' },
  }[kind];
  return (
    <button onClick={onClick} disabled={disabled} style={{
      width: '100%', height: 52, borderRadius: 14,
      background: disabled ? styles.bgD : styles.bg,
      color: '#FFF', fontSize: 16, fontWeight: 800,
      border: 'none', cursor: disabled ? 'not-allowed' : 'pointer',
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8,
      letterSpacing: 0.3,
    }}>
      {icon && <window.LucideIcon name={icon} size={18} />}
      {label}
    </button>
  );
}
window.CtaBar = CtaBar;

/* ─── PulseFace — minimal mascot (used inline) ─── */
function PulseFace({ size = 56, mood = 'neutral' }) {
  // Pulse-blue circle with simple expression — placeholder for the 24-mood lib
  const moodFace = {
    neutral:   <><circle cx="20" cy="22" r="2.5" fill="#0F172A"/><circle cx="36" cy="22" r="2.5" fill="#0F172A"/><path d="M22 36 Q28 38 34 36" stroke="#0F172A" strokeWidth="2" fill="none" strokeLinecap="round"/></>,
    happy:     <><path d="M16 22 Q20 18 24 22" stroke="#0F172A" strokeWidth="2.2" fill="none" strokeLinecap="round"/><path d="M32 22 Q36 18 40 22" stroke="#0F172A" strokeWidth="2.2" fill="none" strokeLinecap="round"/><path d="M20 32 Q28 40 36 32" stroke="#0F172A" strokeWidth="2.4" fill="none" strokeLinecap="round"/></>,
    sad:       <><circle cx="20" cy="22" r="2.5" fill="#0F172A"/><circle cx="36" cy="22" r="2.5" fill="#0F172A"/><path d="M22 38 Q28 33 34 38" stroke="#0F172A" strokeWidth="2.2" fill="none" strokeLinecap="round"/></>,
    thinking:  <><circle cx="20" cy="22" r="2.5" fill="#0F172A"/><circle cx="36" cy="22" r="2.5" fill="#0F172A"/><path d="M22 36 L34 36" stroke="#0F172A" strokeWidth="2.2" fill="none" strokeLinecap="round"/></>,
    excited:   <><path d="M16 22 Q20 16 24 22" stroke="#0F172A" strokeWidth="2.4" fill="none" strokeLinecap="round"/><path d="M32 22 Q36 16 40 22" stroke="#0F172A" strokeWidth="2.4" fill="none" strokeLinecap="round"/><ellipse cx="28" cy="35" rx="6" ry="5" fill="#0F172A"/></>,
    focused:   <><rect x="14" y="20" width="12" height="3" rx="1.5" fill="#0F172A"/><rect x="30" y="20" width="12" height="3" rx="1.5" fill="#0F172A"/><path d="M22 36 L34 36" stroke="#0F172A" strokeWidth="2.2" strokeLinecap="round"/></>,
  }[mood] || null;
  return (
    <svg width={size} height={size} viewBox="0 0 56 56" style={{ flexShrink: 0 }}>
      <defs>
        <radialGradient id={`pf-${mood}`} cx="0.4" cy="0.35">
          <stop offset="0%" stopColor="#7DD3FC"/>
          <stop offset="100%" stopColor="#0096C7"/>
        </radialGradient>
      </defs>
      <circle cx="28" cy="28" r="26" fill={`url(#pf-${mood})`} stroke="#0284A7" strokeWidth="1.5"/>
      <ellipse cx="28" cy="14" rx="14" ry="6" fill="#FFFFFF" opacity="0.20"/>
      {moodFace}
    </svg>
  );
}
window.PulseFace = PulseFace;

/* ─── Hint button (unified, all 9 players) ─── */
function HintButton({ used = 0, dark = false, onClick }) {
  return (
    <button onClick={onClick} style={{
      height: 36, padding: '0 12px', borderRadius: 999,
      background: dark ? 'rgba(245,158,11,0.14)' : '#FEF3C7',
      border: `1px solid ${dark ? 'rgba(245,158,11,0.30)' : '#FCD34D'}`,
      color: '#B45309', fontSize: 13, fontWeight: 800,
      display: 'inline-flex', alignItems: 'center', gap: 6, cursor: 'pointer',
    }}>
      <window.LucideIcon name="lightbulb" size={14} />
      Hint
      {used > 0 && <span style={{ opacity: 0.75 }}>· −{used * 25}%</span>}
    </button>
  );
}
window.HintButton = HintButton;

/* ─── Body wrapper (consistent padding for question content) ─── */
function PlayBody({ children, dark = false, qtype, accent = true }) {
  const meta = qtype && QTYPE[qtype];
  return (
    <div style={{
      flex: 1, padding: '16px 18px 14px',
      background: dark ? 'rgba(0,0,0,0)' : 'transparent',
      borderLeft: accent && meta ? `3px solid ${meta.color}` : 'none',
      marginLeft: accent && meta ? 0 : 0,
      display: 'flex', flexDirection: 'column', gap: 14,
      overflow: 'hidden',
    }}>{children}</div>
  );
}
window.PlayBody = PlayBody;

/* ─── Floating animation keyframes (injected once) ─── */
if (!document.getElementById('qhud-keyframes')) {
  const s = document.createElement('style'); s.id = 'qhud-keyframes';
  s.textContent = `
    @keyframes floatUp { 0% { opacity: 0; transform: translateY(0); } 25% { opacity: 1; } 100% { opacity: 0; transform: translateY(-22px); } }
    @keyframes pulseRing { 0% { box-shadow: 0 0 0 0 rgba(0,150,199,0.4); } 70% { box-shadow: 0 0 0 14px rgba(0,150,199,0); } 100% { box-shadow: 0 0 0 0 rgba(0,150,199,0); } }
    @keyframes shake { 0%,100% { transform: translateX(0); } 25% { transform: translateX(-4px); } 50% { transform: translateX(4px); } 75% { transform: translateX(-2px); } }
    @keyframes scaleIn { from { transform: scale(0.85); opacity: 0; } to { transform: scale(1); opacity: 1; } }
    @keyframes flameGrow { 0%,100% { transform: scale(1); } 50% { transform: scale(1.15); } }
  `;
  document.head.appendChild(s);
}
