// Shared UI primitives, icons, illustrations
const { useState, useEffect, useRef, useMemo, Fragment } = React;

// ---------- Icons (lucide-style stroke 1.5) ----------
const Icon = ({ d, size=16, fill='none', stroke=1.5, ...rest }) => (
  <svg width={size} height={size} viewBox="0 0 24 24" fill={fill} stroke="currentColor" strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round" {...rest}>
    {typeof d === 'string' ? <path d={d}/> : d}
  </svg>
);

const IconSearch    = (p) => <Icon {...p} d="M21 21l-4.3-4.3M11 19a8 8 0 1 1 0-16 8 8 0 0 1 0 16Z"/>;
const IconChevR     = (p) => <Icon {...p} d="M9 18l6-6-6-6"/>;
const IconChevL     = (p) => <Icon {...p} d="M15 18l-6-6 6-6"/>;
const IconChevD     = (p) => <Icon {...p} d="M6 9l6 6 6-6"/>;
const IconChevU     = (p) => <Icon {...p} d="M18 15l-6-6-6 6"/>;
const IconCheck     = (p) => <Icon {...p} d="M5 13l4 4L19 7"/>;
const IconX         = (p) => <Icon {...p} d="M18 6L6 18M6 6l12 12"/>;
const IconPlus      = (p) => <Icon {...p} d="M12 5v14M5 12h14"/>;
const IconStar      = (p) => <Icon {...p} d="M12 3.2l2.7 5.4 6 .9-4.3 4.2 1 6-5.4-2.8L6.6 19.7l1-6L3.3 9.5l6-.9z" stroke={1.3}/>;
const IconHome      = (p) => <Icon {...p} d="M3 11l9-8 9 8M5 9.5V21h14V9.5"/>;
const IconGrid      = (p) => <Icon {...p} d="M3 3h7v7H3zM14 3h7v7h-7zM3 14h7v7H3zM14 14h7v7h-7z"/>;
const IconHeart     = (p) => <Icon {...p} d="M20.8 4.6a5.5 5.5 0 0 0-7.8 0L12 5.7l-1-1.1a5.5 5.5 0 1 0-7.8 7.8L12 21.2l8.8-8.8a5.5 5.5 0 0 0 0-7.8z"/>;
const IconUser      = (p) => <Icon {...p} d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2M12 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8z"/>;
const IconBell      = (p) => <Icon {...p} d="M18 8a6 6 0 0 0-12 0c0 7-3 9-3 9h18s-3-2-3-9M13.7 21a2 2 0 0 1-3.4 0"/>;
const IconCart      = (p) => <Icon {...p} d="M3 3h2l2.7 13.4a2 2 0 0 0 2 1.6h7.7a2 2 0 0 0 2-1.6L21 8H6M9 21a1 1 0 1 0 0-2 1 1 0 0 0 0 2zM18 21a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/>;
const IconShield    = (p) => <Icon {...p} d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>;
const IconReceipt   = (p) => <Icon {...p} d="M4 2h16v20l-3-2-2 2-3-2-2 2-3-2-3 2zM8 7h8M8 11h8M8 15h5"/>;
const IconClock     = (p) => <Icon {...p} d="M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20zM12 6v6l4 2"/>;
const IconArrowR    = (p) => <Icon {...p} d="M5 12h14M13 5l7 7-7 7"/>;
const IconArrowU    = (p) => <Icon {...p} d="M12 19V5M5 12l7-7 7 7"/>;
const IconArrowD    = (p) => <Icon {...p} d="M12 5v14M19 12l-7 7-7-7"/>;
const IconExternal  = (p) => <Icon {...p} d="M15 3h6v6M10 14L21 3M21 14v7H3V3h7"/>;
const IconCopy      = (p) => <Icon {...p} d="M16 4h4v16H8v-4M4 8h12v12H4z"/>;
const IconUpload    = (p) => <Icon {...p} d="M12 16V4M5 11l7-7 7 7M3 20h18"/>;
const IconDownload  = (p) => <Icon {...p} d="M12 4v12M19 13l-7 7-7-7M3 20h18" />;
const IconFilter    = (p) => <Icon {...p} d="M3 5h18l-7 8v6l-4-2v-4z"/>;
const IconCalendar  = (p) => <Icon {...p} d="M3 7h18v14H3zM8 3v4M16 3v4M3 11h18"/>;
const IconLayers    = (p) => <Icon {...p} d="M12 2L2 7l10 5 10-5zM2 12l10 5 10-5M2 17l10 5 10-5"/>;
const IconWebhook   = (p) => <Icon {...p} d="M18 16.98h-5.99M16 8a4 4 0 1 0-7 2.5l1.5 2.5M9 18a3 3 0 1 0-2.6-4.5l1.6 1M14 12l3 5"/>;
const IconCard      = (p) => <Icon {...p} d="M3 7h18v12H3zM3 11h18M7 16h3"/>;
const IconBox       = (p) => <Icon {...p} d="M21 8L12 3 3 8l9 5 9-5zM3 8v8l9 5M21 8v8l-9 5M3 13l9 5M21 13l-9 5"/>;
const IconBolt      = (p) => <Icon {...p} d="M13 2L3 14h7l-1 8 10-12h-7z"/>;
const IconBook      = (p) => <Icon {...p} d="M4 4h12a4 4 0 0 1 4 4v13H8a4 4 0 0 1-4-4V4z M4 17a4 4 0 0 1 4-4h12"/>;
const IconChat      = (p) => <Icon {...p} d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>;
const IconNews      = (p) => <Icon {...p} d="M4 4h13v16H6a2 2 0 0 1-2-2zM17 8h3v10a2 2 0 0 1-2 2M8 8h5M8 12h5M8 16h5"/>;
const IconSettings  = (p) => <Icon {...p} d="M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM19.4 15a1.7 1.7 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.8-.3 1.7 1.7 0 0 0-1 1.5V21a2 2 0 1 1-4 0v-.1a1.7 1.7 0 0 0-1-1.5 1.7 1.7 0 0 0-1.8.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0 .3-1.8 1.7 1.7 0 0 0-1.5-1H3a2 2 0 1 1 0-4h.1a1.7 1.7 0 0 0 1.5-1 1.7 1.7 0 0 0-.3-1.8l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.8.3H9a1.7 1.7 0 0 0 1-1.5V3a2 2 0 1 1 4 0v.1a1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.8-.3l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.8V9a1.7 1.7 0 0 0 1.5 1H21a2 2 0 1 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1z" stroke={1.3}/>;
const IconChart     = (p) => <Icon {...p} d="M3 3v18h18M7 14l4-4 4 4 5-6"/>;
const IconUsers     = (p) => <Icon {...p} d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM23 21v-2a4 4 0 0 0-3-3.9M16 3.1A4 4 0 0 1 16 11"/>;
const IconCash      = (p) => <Icon {...p} d="M2 7h20v10H2zM12 12a2 2 0 1 0 0-4 2 2 0 0 0 0 4zM6 7v10M18 7v10"/>;
const IconCode      = (p) => <Icon {...p} d="M16 18l6-6-6-6M8 6l-6 6 6 6"/>;
const IconPackage   = (p) => <Icon {...p} d="M21 16V8a2 2 0 0 0-1-1.7l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.7l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16zM3.3 7L12 12l8.7-5M12 22V12"/>;
const IconRefresh   = (p) => <Icon {...p} d="M3 12a9 9 0 0 1 15-6.7L21 8M21 3v5h-5M21 12a9 9 0 0 1-15 6.7L3 16M3 21v-5h5"/>;
const IconShield2   = (p) => <Icon {...p} d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10zM9 12l2 2 4-4"/>;
const IconLock      = (p) => <Icon {...p} d="M5 11h14v10H5zM8 11V7a4 4 0 1 1 8 0v4"/>;
const IconInfo      = (p) => <Icon {...p} d="M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20zM12 16v-4M12 8h0"/>;
const IconWarn      = (p) => <Icon {...p} d="M10.3 3.9 2 18a2 2 0 0 0 1.7 3h16.6a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0zM12 9v4M12 17h0"/>;
const IconMail      = (p) => <Icon {...p} d="M3 5h18v14H3zM3 7l9 6 9-6"/>;
const IconQrCode    = (p) => <Icon {...p} d="M3 3h7v7H3zM14 3h7v7h-7zM3 14h7v7H3zM14 14h3v3h-3zM20 14v3M14 20h3M20 20h1"/>;
const IconPlay      = (p) => <Icon {...p} d="M6 4l14 8-14 8z" fill="currentColor" stroke="none"/>;
const IconMobile    = (p) => <Icon {...p} d="M6 2h12v20H6zM10 19h4"/>;
const IconDesktop   = (p) => <Icon {...p} d="M2 4h20v13H2zM8 21h8M12 17v4"/>;

// ---------- Game cover SVGs (procedural) ----------
function GameCover({ slug, accent, accent2, w='100%', h='100%' }) {
  // Each game gets a distinct procedural cover
  const id = 'g-' + slug;
  return (
    <svg viewBox="0 0 320 180" width={w} height={h} preserveAspectRatio="xMidYMid slice" style={{display:'block', borderRadius: 'inherit'}}>
      <defs>
        <linearGradient id={id+'-bg'} x1="0" y1="0" x2="1" y2="1">
          <stop offset="0%" stopColor={accent} />
          <stop offset="100%" stopColor={accent2} />
        </linearGradient>
        <radialGradient id={id+'-glow'} cx="0.7" cy="0.3">
          <stop offset="0%" stopColor="#fff" stopOpacity="0.4"/>
          <stop offset="100%" stopColor="#fff" stopOpacity="0"/>
        </radialGradient>
      </defs>
      <rect width="320" height="180" fill={`url(#${id}-bg)`}/>
      <rect width="320" height="180" fill={`url(#${id}-glow)`}/>
      {slug === 'astral-chronicles' && <>
        <circle cx="240" cy="60" r="44" fill="#fff" opacity="0.16"/>
        <circle cx="240" cy="60" r="28" fill="#fff" opacity="0.22"/>
        <path d="M40 140 L80 90 L120 130 L170 80 L220 130 L280 70 L320 110 L320 180 L0 180 Z" fill="#000" opacity="0.25"/>
        <g fill="#fff" opacity="0.85">
          {Array.from({length:14}, (_,i)=>(<circle key={i} cx={20+i*22} cy={20+(i%3)*8} r={1+ (i%3)*0.7}/>))}
        </g>
        <path d="M150 90 L160 70 L170 90 L190 95 L173 105 L178 125 L160 115 L142 125 L147 105 L130 95 Z" fill="#FDE047" opacity="0.95"/>
      </>}
      {slug === 'pixel-quest' && <>
        {/* Pixel grid */}
        <g fill="#fff" opacity="0.18">
          {Array.from({length:60}, (_,i)=>{const x=(i%12)*28; const y=Math.floor(i/12)*36; return <rect key={i} x={x} y={y} width="28" height="36" stroke={accent2} strokeWidth="0.5"/>})}
        </g>
        {/* Pixel hero */}
        <g fill="#fff">
          <rect x="140" y="60" width="40" height="12"/>
          <rect x="132" y="72" width="56" height="20"/>
          <rect x="140" y="92" width="40" height="20"/>
          <rect x="124" y="80" width="16" height="20"/>
          <rect x="180" y="80" width="16" height="20"/>
        </g>
        <rect x="148" y="68" width="6" height="6" fill={accent}/>
        <rect x="166" y="68" width="6" height="6" fill={accent}/>
      </>}
      {slug === 'race-arena' && <>
        <path d="M0 130 L320 110 L320 180 L0 180 Z" fill="#000" opacity="0.4"/>
        <path d="M0 130 L320 110" stroke="#FDE047" strokeWidth="2" strokeDasharray="20 15"/>
        <g fill="#fff">
          <path d="M180 95 L240 95 L255 110 L255 125 L180 125 L165 115 Z" opacity="0.95"/>
          <circle cx="195" cy="128" r="8" fill="#000"/>
          <circle cx="240" cy="128" r="8" fill="#000"/>
          <rect x="195" y="100" width="40" height="14" fill={accent2} opacity="0.6"/>
        </g>
      </>}
      {slug === 'kingdom-rise' && <>
        <path d="M40 140 L40 80 L60 80 L60 60 L80 60 L80 80 L100 80 L100 50 L130 50 L130 80 L160 80 L160 40 L200 40 L200 80 L240 80 L240 60 L260 60 L260 80 L280 80 L280 140 Z" fill="#fff" opacity="0.9"/>
        <path d="M40 140 L280 140 L280 180 L40 180 Z" fill="#000" opacity="0.3"/>
        <rect x="155" y="20" width="6" height="20" fill="#FDE047"/>
        <path d="M161 22 L181 28 L161 34 Z" fill="#FDE047"/>
      </>}
      {slug === 'puzzle-flow' && <>
        <g opacity="0.95">
          <rect x="60"  y="40" width="60" height="60" fill="#fff" rx="8"/>
          <rect x="130" y="40" width="60" height="60" fill="#FDE047" rx="8"/>
          <rect x="200" y="40" width="60" height="60" fill="#fff" rx="8" opacity="0.7"/>
          <rect x="95"  y="110" width="60" height="60" fill="#fff" rx="8" opacity="0.7"/>
          <rect x="165" y="110" width="60" height="60" fill="#fff" rx="8"/>
        </g>
      </>}
      {slug === 'fitcoach' && <>
        <circle cx="160" cy="90" r="55" fill="#fff" opacity="0.9"/>
        <path d="M140 90 Q150 70, 160 90 T180 90" stroke={accent} strokeWidth="6" fill="none"/>
        <path d="M120 100 L140 100 L150 78 L165 122 L175 95 L200 95" stroke={accent} strokeWidth="3" fill="none"/>
      </>}
      {slug === 'lingomate' && <>
        <g opacity="0.95" fontFamily="Manrope, sans-serif" fontWeight="900" fill="#fff">
          <text x="40"  y="80"  fontSize="36">Hola</text>
          <text x="180" y="80"  fontSize="36" opacity="0.6">你好</text>
          <text x="40"  y="140" fontSize="36" opacity="0.6">Bonjour</text>
          <text x="200" y="140" fontSize="36">Привет</text>
        </g>
      </>}
      {slug === 'idle-lords' && <>
        <g fill="#FDE047" opacity="0.95">
          <circle cx="160" cy="90" r="35"/>
          <circle cx="120" cy="120" r="18"/>
          <circle cx="200" cy="120" r="18"/>
          <circle cx="140" cy="60"  r="12"/>
          <circle cx="180" cy="60"  r="12"/>
        </g>
        <text x="160" y="98" textAnchor="middle" fill={accent} fontSize="22" fontWeight="900" fontFamily="Manrope">₽</text>
      </>}
    </svg>
  );
}

// ---------- Payment method logos (faithful word-marks) ----------
function PayLogo({ kind, size=22 }) {
  if (kind === 'mir') return (
    <svg viewBox="0 0 80 24" height={size} style={{display:'block'}}>
      <rect width="80" height="24" rx="4" fill="#0CB04A"/>
      <text x="40" y="17" textAnchor="middle" fill="#fff" fontFamily="Manrope, sans-serif" fontWeight="900" fontSize="14" letterSpacing="1">МИР</text>
    </svg>
  );
  if (kind === 'sbp') return (
    <svg viewBox="0 0 80 24" height={size} style={{display:'block'}}>
      <rect width="80" height="24" rx="4" fill="#fff" stroke="#E5E7EB"/>
      <path d="M10 6 L14 12 L10 18 M14 6 L18 12 L14 18" stroke="#5B2A86" strokeWidth="2" fill="none" strokeLinecap="round"/>
      <path d="M14 6 L18 12 L14 18" stroke="#EE3324" strokeWidth="2" fill="none" strokeLinecap="round"/>
      <text x="46" y="16" textAnchor="middle" fill="#1A1A1A" fontFamily="Manrope, sans-serif" fontWeight="800" fontSize="11">СБП</text>
    </svg>
  );
  if (kind === 'sberpay') return (
    <svg viewBox="0 0 100 24" height={size} style={{display:'block'}}>
      <rect width="100" height="24" rx="4" fill="#21A038"/>
      <circle cx="13" cy="12" r="6.5" fill="none" stroke="#fff" strokeWidth="2"/>
      <path d="M9 8 L20 8" stroke="#fff" strokeWidth="2" strokeLinecap="round"/>
      <text x="55" y="16" textAnchor="middle" fill="#fff" fontFamily="Manrope, sans-serif" fontWeight="800" fontSize="11">SberPay</text>
    </svg>
  );
  if (kind === 'yandexpay') return (
    <svg viewBox="0 0 110 24" height={size} style={{display:'block'}}>
      <rect width="110" height="24" rx="4" fill="#000"/>
      <text x="10" y="17" fill="#FFCC00" fontFamily="Manrope, sans-serif" fontWeight="900" fontSize="13">Y</text>
      <text x="22" y="16" fill="#fff" fontFamily="Manrope, sans-serif" fontWeight="700" fontSize="11">Yandex Pay</text>
    </svg>
  );
  return null;
}

// ---------- Wordmark ----------
function Wordmark({ size=18, color }) {
  return (
    <span className="wordmark" style={{fontSize: size, color: color || 'var(--n-900)'}}>
      rev<span className="dot" style={{color: 'var(--brand-500)'}}>.</span>cut
    </span>
  );
}

// ---------- Sparkline (inline svg) ----------
function Sparkline({ data, color='var(--n-900)', w=120, h=32, fill=true }) {
  const max = Math.max(...data), min = Math.min(...data);
  const norm = (v) => h - ((v - min) / Math.max(1, max - min)) * (h - 2) - 1;
  const step = w / (data.length - 1);
  const pts = data.map((v, i) => `${i*step},${norm(v)}`).join(' ');
  const area = `M0,${h} L${pts.replace(/ /g, ' L')} L${w},${h} Z`;
  return (
    <svg width={w} height={h} style={{display:'block'}}>
      {fill && <path d={area} fill={color} opacity="0.1"/>}
      <polyline points={pts} fill="none" stroke={color} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  );
}

// ---------- Avatar ----------
function Avatar({ name, size=32, accent='#0F172A' }) {
  const initials = name.split(' ').map(s => s[0]).slice(0,2).join('').toUpperCase();
  return (
    <div style={{
      width:size, height:size, borderRadius:'50%',
      background: accent, color:'#fff',
      display:'flex', alignItems:'center', justifyContent:'center',
      fontSize: size*0.36, fontWeight:700, fontFamily:'var(--font-display)',
      flexShrink:0,
    }}>{initials}</div>
  );
}

// ---------- Toast (simple) ----------
function Toast({ msg, kind='info', onClose }) {
  if (!msg) return null;
  const colors = { info: 'var(--info)', success: 'var(--success)', danger: 'var(--danger)' };
  return (
    <div style={{
      position:'fixed', top: 16, left:'50%', transform:'translateX(-50%)',
      background: 'var(--n-900)', color:'#fff', padding:'10px 14px',
      borderRadius: 'var(--r-4)', fontSize: 13, fontWeight:500, zIndex:9999,
      boxShadow:'var(--shadow-lg)', display:'flex', gap:10, alignItems:'center',
    }}>
      <span style={{width:8, height:8, borderRadius:'50%', background: colors[kind]}}/>
      {msg}
      <button onClick={onClose} style={{marginLeft:8, opacity:0.6}}><IconX size={14}/></button>
    </div>
  );
}

Object.assign(window, {
  Icon, IconSearch, IconChevR, IconChevL, IconChevD, IconChevU, IconCheck, IconX, IconPlus,
  IconStar, IconHome, IconGrid, IconHeart, IconUser, IconBell, IconCart, IconShield, IconReceipt,
  IconClock, IconArrowR, IconArrowU, IconArrowD, IconExternal, IconCopy, IconUpload, IconDownload,
  IconFilter, IconCalendar, IconLayers, IconWebhook, IconCard, IconBox, IconBolt, IconBook, IconChat,
  IconNews, IconSettings, IconChart, IconUsers, IconCash, IconCode, IconPackage, IconRefresh,
  IconShield2, IconLock, IconInfo, IconWarn, IconMail, IconQrCode, IconPlay, IconMobile, IconDesktop,
  GameCover, PayLogo, Wordmark, Sparkline, Avatar, Toast,
});
