// Roast Battle — shared chaotic gen-z components
// All components read theme from props.t

// ─── halftone + grid backgrounds ────────────────────────────────
function Halftone({ color = '#000', size = 3, gap = 8, opacity = 0.18 }) {
  const dot = `radial-gradient(${color} ${size/2}px, transparent ${size/2 + 0.5}px)`;
  return (
    <div style={{
      position: 'absolute', inset: 0, pointerEvents: 'none',
      backgroundImage: dot, backgroundSize: `${gap}px ${gap}px`,
      opacity, mixBlendMode: 'multiply',
    }} />
  );
}

function Grid({ color = 'rgba(0,0,0,0.05)', size = 24 }) {
  return (
    <div style={{
      position: 'absolute', inset: 0, pointerEvents: 'none',
      backgroundImage: `linear-gradient(${color} 1px, transparent 1px), linear-gradient(90deg, ${color} 1px, transparent 1px)`,
      backgroundSize: `${size}px ${size}px`,
    }} />
  );
}

// ─── sparkle / star burst ──────────────────────────────────────
function Sparkle({ size = 24, color = '#FFD400', style = {} }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" style={{ display: 'block', ...style }}>
      <path d="M12 0 L13.5 9 L24 12 L13.5 14.5 L12 24 L10.5 14.5 L0 12 L10.5 9 Z" fill={color}/>
    </svg>
  );
}

function StarBurst({ size = 80, color = '#FF2D87', points = 14, style = {} }) {
  const cx = 12, cy = 12;
  const r1 = 11, r2 = 6.5;
  const path = [];
  for (let i = 0; i < points * 2; i++) {
    const a = (Math.PI / points) * i - Math.PI / 2;
    const r = i % 2 ? r2 : r1;
    path.push(`${cx + Math.cos(a) * r},${cy + Math.sin(a) * r}`);
  }
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" style={{ display: 'block', ...style }}>
      <polygon points={path.join(' ')} fill={color}/>
    </svg>
  );
}

// ─── marquee tape ───────────────────────────────────────────────
function Marquee({ children, speed = 25, color, ink, tilt = 0, style = {} }) {
  const text = typeof children === 'string' ? children : '';
  const reps = 6;
  return (
    <div style={{
      overflow: 'hidden', background: color, color: ink,
      transform: `rotate(${tilt}deg)`,
      borderTop: `2px solid currentColor`,
      borderBottom: `2px solid currentColor`,
      ...style,
    }}>
      <div style={{
        display: 'flex', whiteSpace: 'nowrap',
        animation: `rb-marquee ${speed}s linear infinite`,
      }}>
        {Array.from({ length: reps }).map((_, i) => (
          <span key={i} style={{
            fontFamily: 'Bungee, system-ui', fontSize: 14,
            padding: '8px 18px', letterSpacing: 0.5,
          }}>{text} ✦ </span>
        ))}
      </div>
    </div>
  );
}

// ─── chunky button (3d offset shadow) ──────────────────────────
function ChunkyButton({ children, onClick, t, color, ink, full, small, tilt = 0, style = {} }) {
  const bg = color || t.pop;
  const fg = ink || t.popInk;
  const [pressed, setPressed] = React.useState(false);
  return (
    <button
      onClick={onClick}
      onPointerDown={() => setPressed(true)}
      onPointerUp={() => setPressed(false)}
      onPointerLeave={() => setPressed(false)}
      style={{
        appearance: 'none', cursor: 'pointer',
        fontFamily: 'Bungee, system-ui',
        fontSize: small ? 14 : 18, letterSpacing: 0.5,
        color: fg, background: bg,
        padding: small ? '10px 18px' : '16px 22px',
        border: `2px solid ${t.rule}`,
        borderRadius: 18,
        width: full ? '100%' : undefined,
        transform: `translate(${pressed ? 4 : 0}px, ${pressed ? 4 : 0}px) rotate(${tilt}deg)`,
        boxShadow: pressed ? 'none' : `4px 4px 0 0 ${t.shadow}`,
        transition: 'transform 60ms, box-shadow 60ms',
        display: 'inline-flex', alignItems: 'center', gap: 8,
        justifyContent: 'center',
        ...style,
      }}
    >{children}</button>
  );
}

// ─── paper card with rule + offset shadow ──────────────────────
function PaperCard({ children, t, tilt = 0, color, style = {}, onClick }) {
  return (
    <div onClick={onClick} style={{
      background: color || t.paper, color: t.ink,
      border: `2px solid ${t.rule}`, borderRadius: 22,
      boxShadow: `4px 4px 0 0 ${t.shadow}`,
      transform: `rotate(${tilt}deg)`,
      position: 'relative',
      cursor: onClick ? 'pointer' : undefined,
      ...style,
    }}>{children}</div>
  );
}

// ─── washi tape ─────────────────────────────────────────────────
function Tape({ color = '#FFD400', tilt = -8, w = 90, top = -10, left = 16, opacity = 0.9 }) {
  return (
    <div style={{
      position: 'absolute', top, left,
      width: w, height: 22,
      background: color, opacity,
      transform: `rotate(${tilt}deg)`,
      boxShadow: '0 1px 2px rgba(0,0,0,0.15)',
      zIndex: 2,
      backgroundImage: 'repeating-linear-gradient(90deg, rgba(255,255,255,0.18) 0 6px, transparent 6px 12px)',
    }} />
  );
}

// ─── sticker label ──────────────────────────────────────────────
function Sticker({ children, t, color, ink, tilt = -4, style = {} }) {
  return (
    <span style={{
      display: 'inline-block',
      fontFamily: 'Bungee, system-ui', fontSize: 12, letterSpacing: 0.6,
      color: ink || t.popInk, background: color || t.pop,
      border: `2px solid ${t.rule}`, borderRadius: 999,
      padding: '4px 10px 3px',
      transform: `rotate(${tilt}deg)`,
      boxShadow: `2px 2px 0 0 ${t.shadow}`,
      ...style,
    }}>{children}</span>
  );
}

// ─── avatar bubble ──────────────────────────────────────────────
function Avatar({ person, t, size = 56, tilt = 0, ring }) {
  return (
    <div style={{
      width: size, height: size, borderRadius: '50%',
      background: ring || t.accent,
      border: `2px solid ${t.rule}`,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      fontSize: size * 0.5, lineHeight: 1,
      transform: `rotate(${tilt}deg)`,
      boxShadow: `2px 2px 0 0 ${t.shadow}`,
      flexShrink: 0,
    }}>{person?.avatar || '?'}</div>
  );
}

// ─── VS slam ────────────────────────────────────────────────────
function VsSlam({ t, size = 56, style = {} }) {
  return (
    <div style={{ position: 'relative', width: size, height: size, ...style }}>
      <StarBurst size={size} color={t.sun} points={16} />
      <div style={{
        position: 'absolute', inset: 0, display: 'flex',
        alignItems: 'center', justifyContent: 'center',
        fontFamily: 'Bungee, system-ui', fontSize: size * 0.38,
        color: t.ink,
        WebkitTextStroke: `1.5px ${t.ink}`,
        letterSpacing: -1,
      }}>VS</div>
    </div>
  );
}

// ─── doodle accents ─────────────────────────────────────────────
function Squiggle({ color = '#000', w = 80, h = 14, style = {} }) {
  return (
    <svg width={w} height={h} viewBox="0 0 80 14" style={{ display: 'block', ...style }}>
      <path d="M2 7 Q 12 1, 22 7 T 42 7 T 62 7 T 78 7" stroke={color} strokeWidth="2.5" fill="none" strokeLinecap="round"/>
    </svg>
  );
}

function ArrowDoodle({ color = '#000', size = 40, tilt = 10, style = {} }) {
  return (
    <svg width={size} height={size} viewBox="0 0 40 40" style={{ display: 'block', transform: `rotate(${tilt}deg)`, ...style }}>
      <path d="M5 8 Q 22 6, 32 22" stroke={color} strokeWidth="2.5" fill="none" strokeLinecap="round"/>
      <path d="M26 18 L32 22 L28 28" stroke={color} strokeWidth="2.5" fill="none" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  );
}

// ─── mobile detector — shared across components ─────────────────
// Reads window.__isMobile (set + maintained in app-v2.jsx) and re-renders
// when the rb-mobile-change event fires. Multiple instances safely coexist.
function useIsMobile() {
  const get = () => typeof window !== 'undefined' && !!window.__isMobile;
  const [m, set] = React.useState(get);
  React.useEffect(() => {
    const onChange = () => set(get());
    window.addEventListener('rb-mobile-change', onChange);
    return () => window.removeEventListener('rb-mobile-change', onChange);
  }, []);
  return m;
}

// ─── screen scaffold (handles status bar / home indicator padding) ──
// Desktop: padTop/padBottom are px values that clear the iOS mockup's
// fake status bar (~50px) + home indicator (~34px).
// Mobile (fullscreen): subtract those chrome heights and add the real
// env(safe-area-inset-*) so we clear the actual notch + home indicator.
// The `max(env, Npx)` floor keeps Chrome devtools emulation usable —
// emulation always returns env=0, which would otherwise glue content
// to the very edge of the viewport.
function Screen({ children, t, scroll = true, padTop = 56, padBottom = 42, bg, style = {} }) {
  const isMobile = useIsMobile();
  const padT = isMobile
    ? `calc(max(env(safe-area-inset-top, 0px), 20px) + ${Math.max(0, padTop - 56)}px)`
    : padTop;
  const padB = isMobile
    ? `calc(max(env(safe-area-inset-bottom, 0px), 12px) + ${Math.max(0, padBottom - 42)}px)`
    : padBottom;
  return (
    <div style={{
      width: '100%', height: '100%',
      background: bg || t.bg, color: t.ink,
      position: 'relative', overflow: 'hidden',
      fontFamily: 'Space Grotesk, system-ui',
    }}>
      <div style={{
        position: 'absolute', inset: 0,
        overflowY: scroll ? 'auto' : 'hidden',
        paddingTop: padT, paddingBottom: padB,
        ...style,
      }}>{children}</div>
    </div>
  );
}

// ─── top bar (back + title) ─────────────────────────────────────
function TopBar({ t, onBack, right, title, sub }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      padding: '6px 18px 14px',
    }}>
      {onBack ? (
        <button onClick={onBack} style={{
          appearance: 'none', cursor: 'pointer',
          width: 38, height: 38, borderRadius: '50%',
          background: t.paper, border: `2px solid ${t.rule}`,
          boxShadow: `2px 2px 0 0 ${t.shadow}`,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          color: t.ink, fontSize: 18, padding: 0,
        }}>
          <svg width="14" height="14" viewBox="0 0 14 14"><path d="M10 2L4 7l6 5" stroke={t.ink} strokeWidth="2.4" fill="none" strokeLinecap="round" strokeLinejoin="round"/></svg>
        </button>
      ) : <div style={{ width: 38 }} />}
      {title ? (
        <div style={{
          fontFamily: 'Bungee, system-ui', fontSize: 14, letterSpacing: 1,
          textAlign: 'center', color: t.ink,
        }}>
          {title}
          {sub && <div style={{ fontFamily: 'Space Grotesk', fontWeight: 400, fontSize: 11, color: t.sub, letterSpacing: 0, textTransform: 'lowercase', marginTop: 2 }}>{sub}</div>}
        </div>
      ) : <div />}
      {right || <div style={{ width: 38 }} />}
    </div>
  );
}

// ─── bottom tab bar ─────────────────────────────────────────────
// On mobile we lift the bar off the home-indicator zone by adding
// env(safe-area-inset-bottom) to its bottom offset. On desktop the
// IOSDevice frame's fake home indicator sits below the scroll area
// already, so a constant 26px is correct there.
function TabBar({ t, current, go }) {
  const isMobile = useIsMobile();
  const tabs = [
    { id: 'home',    label: 'BATTLE',  icon: '🥊' },
    { id: 'friends', label: 'FRIENDS', icon: '🫂' },
    { id: 'profile', label: 'ME',      icon: '🐀' },
  ];
  return (
    <div style={{
      position: 'absolute', left: 14, right: 14,
      bottom: isMobile ? 'calc(env(safe-area-inset-bottom, 0px) + 14px)' : 26,
      background: t.paper, border: `2px solid ${t.rule}`,
      borderRadius: 999, boxShadow: `3px 3px 0 0 ${t.shadow}`,
      display: 'flex', padding: 6, gap: 4, zIndex: 30,
    }}>
      {tabs.map(tab => {
        const active = current === tab.id;
        return (
          <button key={tab.id} onClick={() => go(tab.id)} style={{
            appearance: 'none', cursor: 'pointer', flex: 1,
            background: active ? t.pop : 'transparent',
            color: active ? t.popInk : t.ink,
            border: 'none', borderRadius: 999,
            padding: '10px 6px',
            minHeight: 44,
            fontFamily: 'Bungee, system-ui', fontSize: 11, letterSpacing: 0.8,
            display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 5,
          }}>
            <span style={{ fontSize: 14 }}>{tab.icon}</span>
            <span>{tab.label}</span>
          </button>
        );
      })}
    </div>
  );
}

Object.assign(window, {
  Halftone, Grid, Sparkle, StarBurst, Marquee,
  ChunkyButton, PaperCard, Tape, Sticker, Avatar, VsSlam,
  Squiggle, ArrowDoodle, Screen, TopBar, TabBar,
  useIsMobile,
});
