// Reusable visual building blocks. All accept `dark` and the standard React
// `style` to compose freely.

function ApprovalBg({ dark = true, children }) {
  return (
    <div style={{
      position: 'relative', width: '100%', minHeight: '100vh', overflow: 'hidden',
      background: dark
        ? 'radial-gradient(ellipse at top left, #1a0d2e 0%, #0a0a14 60%)'
        : 'radial-gradient(ellipse at top left, #fde6f0 0%, #ede1ff 60%)',
      color: dark ? '#fff' : '#1a0d2e',
    }}>
      <div style={{ position: 'fixed', width: '50%', aspectRatio: '1', borderRadius: '50%',
        top: '-15%', left: '-5%', background: '#7c3aed', opacity: dark ? 0.55 : 0.45,
        filter: 'blur(80px)', animation: 'apBlobA 22s ease-in-out infinite alternate',
        pointerEvents: 'none' }}/>
      <div style={{ position: 'fixed', width: '45%', aspectRatio: '1', borderRadius: '50%',
        bottom: '-15%', right: '-5%', background: '#ff4d8d', opacity: dark ? 0.45 : 0.4,
        filter: 'blur(90px)', animation: 'apBlobB 26s ease-in-out infinite alternate',
        pointerEvents: 'none' }}/>
      <div style={{ position: 'fixed', width: '30%', aspectRatio: '1', borderRadius: '50%',
        top: '40%', left: '50%', background: '#3eb8ff', opacity: dark ? 0.3 : 0.25,
        filter: 'blur(70px)', animation: 'apBlobC 30s ease-in-out infinite alternate',
        pointerEvents: 'none' }}/>
      <div style={{ position: 'relative' }}>{children}</div>
    </div>
  );
}

function ApGlass({ children, dark = true, radius = 20, padding = 0, blur = 20, style = {}, onClick }) {
  return (
    <div onClick={onClick} style={{
      background: dark ? 'rgba(255,255,255,0.06)' : 'rgba(255,255,255,0.55)',
      backdropFilter: `blur(${blur}px) saturate(140%)`,
      WebkitBackdropFilter: `blur(${blur}px) saturate(140%)`,
      border: dark ? '1px solid rgba(255,255,255,0.10)' : '1px solid rgba(255,255,255,0.7)',
      borderRadius: radius, padding,
      boxShadow: dark
        ? '0 10px 40px rgba(0,0,0,0.35), inset 0 1px 0 rgba(255,255,255,0.08)'
        : '0 10px 40px rgba(124,58,237,0.10), inset 0 1px 0 rgba(255,255,255,0.9)',
      cursor: onClick ? 'pointer' : undefined,
      ...style,
    }}>{children}</div>
  );
}

function ApCover({ colors, src, size = 80, radius = 14, style = {} }) {
  const [a, b] = colors || ['#7c3aed', '#ff4d8d'];
  return (
    <div style={{
      width: size, height: size, borderRadius: radius, flexShrink: 0,
      background: src ? `url(${src}) center/cover` : `linear-gradient(135deg, ${a}, ${b})`,
      position: 'relative', overflow: 'hidden',
      boxShadow: `0 6px 20px ${a}40`,
      ...style,
    }}>
      {!src && (
        <div style={{
          position: 'absolute', top: '-20%', right: '-20%', width: '60%', height: '60%',
          borderRadius: '50%', background: 'rgba(255,255,255,0.25)', filter: 'blur(12px)',
        }}/>
      )}
    </div>
  );
}

function ApAvatar({ player, size = 36 }) {
  if (!player) return null;
  const colors = player.avatar || fallbackAvatar(player.identifier);
  const [a, b] = colors;
  const initial = (player.name || '?').split(/\s+/).map(s => s[0]).slice(0, 2).join('').toUpperCase();
  return (
    <div style={{
      width: size, height: size, borderRadius: '50%', flexShrink: 0,
      background: `linear-gradient(135deg, ${a}, ${b})`,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      fontSize: Math.round(size * 0.38), fontWeight: 800, color: '#fff',
      boxShadow: `0 4px 12px ${a}55`,
    }}>{initial}</div>
  );
}

function ApPlayerName({ player, size = 13, opacity = 0.7, color, badge = true, style = {} }) {
  if (!player) return null;
  const verified = isVerifiedArtist(player.identifier);
  const adm = player.group === 'admin';
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4, fontSize: size, opacity, color, minWidth: 0, ...style }}>
      <span style={{ whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', minWidth: 0 }}>{player.name}</span>
      {badge && verified && <ApIcon name="verified" size={Math.round(size * 1.05)} color="#3eb8ff"/>}
      {badge && adm && <ApIcon name="shield" size={Math.round(size * 0.95)} color="#fbbf24"/>}
    </span>
  );
}

function ApStatusPill({ status }) {
  const cfg = {
    pending:  { bg: 'rgba(251,191,36,0.15)', fg: '#fbbf24', label: 'In Prüfung' },
    accepted: { bg: 'rgba(52,211,153,0.18)', fg: '#34d399', label: 'Veröffentlicht' },
    rejected: { bg: 'rgba(239,68,68,0.18)',  fg: '#f87171', label: 'Abgelehnt' },
  }[status];
  // Unknown/corrupt status: render a neutral placeholder instead of
  // dumping the raw value into the DOM. Earlier versions did
  // `label: status` as a fallback which let upstream data bugs leak
  // ugly raw payloads into the UI (e.g. peaks arrays accidentally
  // assigned to status — see commit log).
  if (!cfg) {
    return (
      <span style={{
        display: 'inline-flex', alignItems: 'center', gap: 4, padding: '4px 10px',
        borderRadius: 100, background: 'rgba(255,255,255,0.08)', color: 'rgba(255,255,255,0.55)',
        fontSize: 11, fontWeight: 700, letterSpacing: 0.3, textTransform: 'uppercase',
      }}>?</span>
    );
  }
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 4, padding: '4px 10px',
      borderRadius: 100, background: cfg.bg, color: cfg.fg,
      fontSize: 11, fontWeight: 700, letterSpacing: 0.3, textTransform: 'uppercase',
    }}>{cfg.label}</span>
  );
}

function ApRolePill({ player, dark }) {
  if (!player) return null;
  const verified = isVerifiedArtist(player.identifier);
  let label, color;
  if (player.group === 'admin') { label = 'Admin'; color = '#fbbf24'; }
  else if (player.group === 'mod') { label = 'Moderator'; color = '#a78bfa'; }
  else if (player.group === 'whitelist') { label = 'Whitelist'; color = '#3b82f6'; }
  else if (verified) { label = 'Verifiziert'; color = '#3eb8ff'; }
  else { label = 'Spieler'; color = dark ? 'rgba(255,255,255,0.6)' : 'rgba(0,0,0,0.5)'; }
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 4, padding: '3px 9px',
      borderRadius: 100, fontSize: 10.5, fontWeight: 700, letterSpacing: 0.4,
      textTransform: 'uppercase',
      background: dark ? 'rgba(255,255,255,0.06)' : 'rgba(255,255,255,0.6)',
      color, border: `1px solid ${color}55`,
    }}>{label}</span>
  );
}

Object.assign(window, {
  ApprovalBg, ApGlass, ApCover, ApAvatar, ApPlayerName, ApStatusPill, ApRolePill,
});
