// Ludilove design tokens — extracted from the reference SVGs
const LL = {
  cream: '#F2E5CA',
  creamSoft: '#EADAB8',
  creamDark: '#E0CA9E',
  navy: '#17468D',
  navyDeep: '#033289',
  navyInk: '#0E2F63',
  white: '#FDFBF5',
  red: '#C94A3A',
  gold: '#E2B13A',
  green: '#4F8E5A',
  muted: 'rgba(23, 70, 141, 0.55)',
  mutedInk: 'rgba(23, 70, 141, 0.78)',
  shadow: '0 4px 4px rgba(0,0,0,0.25)',
  shadowSoft: '0 2px 8px rgba(23,70,141,0.12)',
  fontDisplay: '"Space Grotesque", "Space Grotesk", system-ui, sans-serif',
  fontBody: '"Space Grotesk", -apple-system, system-ui, sans-serif',
  fontMono: '"JetBrains Mono", "SF Mono", monospace',
};

// ──────────────────────────────────────────────────────────────
// FoldedCard — the signature card with a ribbon/folded corner.
// Used for game tiles, session cards, and key CTAs.
// ──────────────────────────────────────────────────────────────
function FoldedCard({
  children,
  color = LL.navy,
  bg = LL.cream,
  radius = 22,
  fold = 28, // kept for API compat — ignored now
  foldColor,
  stroke = 2,
  style = {},
  onClick,
  active = false,
}) {
  const fc = foldColor || color;
  return (
    <div
      onClick={onClick}
      style={{
        position: 'relative',
        borderRadius: radius,
        background: bg,
        border: `${stroke}px solid ${fc}`,
        cursor: onClick ? 'pointer' : 'default',
        transition: 'transform .18s ease, box-shadow .18s ease',
        transform: active ? 'translateY(-2px)' : 'none',
        overflow: 'hidden',
        ...style,
      }}
    >
      <div style={{ position: 'relative', zIndex: 2, height: '100%' }}>
        {children}
      </div>
    </div>
  );
}

// ──────────────────────────────────────────────────────────────
// LoadingDie — dé stylisé pour l'écran de chargement (animé en CSS)
// ──────────────────────────────────────────────────────────────
function LoadingDie({ color = LL.cream, bg = LL.navy }) {
  return (
    <svg viewBox="0 0 44 44" width="100%" height="100%">
      <rect x="2" y="2" width="40" height="40" rx="9"
        fill={bg} stroke={color} strokeWidth="2.4"/>
      <circle cx="13" cy="13" r="3" fill={color}/>
      <circle cx="31" cy="13" r="3" fill={color}/>
      <circle cx="22" cy="22" r="3" fill={color}/>
      <circle cx="13" cy="31" r="3" fill={color}/>
      <circle cx="31" cy="31" r="3" fill={color}/>
    </svg>
  );
}

// ──────────────────────────────────────────────────────────────
// GameTile — a game cover rendered as FoldedCard with ribbon
// ──────────────────────────────────────────────────────────────
function GameTile({ game, size = 'md', onClick, style = {} }) {
  const dims = {
    sm: { w: 84, h: 84, title: 11, fold: 16 },
    md: { w: 120, h: 120, title: 13, fold: 20 },
    lg: { w: 160, h: 160, title: 15, fold: 24 },
    xl: { w: 240, h: 320, title: 22, fold: 36 },
    swipe: { w: 300, h: 420, title: 28, fold: 44 },
  }[size];
  return (
    <FoldedCard
      onClick={onClick}
      fold={dims.fold}
      bg={game.bg || '#E8D5B0'}
      color={LL.navy}
      stroke={0}
      radius={18}
      style={{ width: dims.w, height: dims.h, ...style }}
    >
      <div style={{
        width: '100%', height: '100%',
        display: 'flex', flexDirection: 'column',
        position: 'relative', overflow: 'hidden',
        borderRadius: 14,
      }}>
        <GameCover game={game} />
        {size !== 'sm' && (
          <div style={{
            position: 'absolute', left: 0, right: 0, bottom: 0,
            padding: '6px 12px',
            background: 'linear-gradient(180deg, transparent, rgba(23,70,141,0.85) 65%)',
            color: LL.cream,
            fontFamily: LL.fontDisplay,
            fontSize: dims.title,
            fontWeight: 700,
            letterSpacing: 0.3,
            textAlign: 'center',
            paddingBottom: 10,
          }}>
            {game.name}
          </div>
        )}
      </div>
    </FoldedCard>
  );
}

// Real cover if available (scraped from Amazon / BGG), else procedural SVG.
function GameCover({ game }) {
  const [failed, setFailed] = React.useState(false);
  if (game.cover_url && !failed) {
    return (
      <div style={{
        position: 'absolute', inset: 0,
        background: game.bg || '#E8D5B0',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        overflow: 'hidden',
      }}>
        <img
          src={game.cover_url}
          alt={game.name}
          loading="lazy"
          onError={() => setFailed(true)}
          style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }}
        />
      </div>
    );
  }
  const art = GAME_ART[game.art] || GAME_ART.default;
  return (
    <div style={{
      position: 'absolute', inset: 0,
      background: game.bg || '#E8D5B0',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      overflow: 'hidden',
    }}>
      {art(game)}
    </div>
  );
}

// A small library of illustrative covers built with SVG primitives
const GAME_ART = {
  scythe: (g) => (
    <svg viewBox="0 0 200 280" width="100%" height="100%" preserveAspectRatio="xMidYMid slice">
      <defs>
        <linearGradient id="sky-s" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0" stopColor="#D4B878"/>
          <stop offset="0.5" stopColor="#C89B5C"/>
          <stop offset="1" stopColor="#8B5A2B"/>
        </linearGradient>
      </defs>
      <rect width="200" height="280" fill="url(#sky-s)"/>
      <circle cx="150" cy="60" r="28" fill="#E8C67A" opacity="0.6"/>
      <path d="M0 200 L60 170 L100 185 L160 160 L200 180 L200 280 L0 280 Z" fill="#6B4423"/>
      <path d="M0 220 L200 210 L200 280 L0 280 Z" fill="#3D2817"/>
      <rect x="60" y="140" width="18" height="40" fill="#2A1810"/>
      <polygon points="55,145 83,145 69,125" fill="#2A1810"/>
      <rect x="120" y="150" width="22" height="30" fill="#2A1810"/>
    </svg>
  ),
  dixit: (g) => (
    <svg viewBox="0 0 200 280" width="100%" height="100%" preserveAspectRatio="xMidYMid slice">
      <rect width="200" height="280" fill="#F5F1E8"/>
      <circle cx="50" cy="50" r="35" fill="#F4C542"/>
      <path d="M100 80 Q130 50 170 90 Q180 140 140 170 Q90 180 80 130 Z" fill="#7FB069"/>
      <path d="M30 180 Q80 160 130 200 Q170 230 190 260 L190 280 L10 280 Z" fill="#6A994E"/>
      <circle cx="140" cy="220" r="8" fill="#F4A261"/>
      <circle cx="60" cy="230" r="5" fill="#E76F51"/>
    </svg>
  ),
  trio: (g) => (
    <svg viewBox="0 0 200 280" width="100%" height="100%" preserveAspectRatio="xMidYMid slice">
      <rect width="200" height="280" fill="#E6B33A"/>
      <g stroke="#5C2E0E" strokeWidth="1.5" fill="none" opacity="0.6">
        {Array.from({length: 8}).map((_, i) => (
          <path key={i} d={`M ${i*30-10} 0 Q ${i*30+10} 140 ${i*30-10} 280`}/>
        ))}
      </g>
      <rect x="30" y="110" width="140" height="60" rx="6" fill="#5C2E0E"/>
      <text x="100" y="153" textAnchor="middle" fontFamily="Georgia, serif"
        fontWeight="900" fontSize="42" fill="#E6B33A" letterSpacing="4">TRIO</text>
    </svg>
  ),
  catan: (g) => (
    <svg viewBox="0 0 200 280" width="100%" height="100%" preserveAspectRatio="xMidYMid slice">
      <rect width="200" height="280" fill="#E8A048"/>
      <polygon points="100,40 150,70 150,130 100,160 50,130 50,70" fill="#D57028" stroke="#8B3A0F" strokeWidth="2"/>
      <polygon points="40,130 80,150 80,195 40,215 0,195 0,150" fill="#8BA842" stroke="#4E5E24" strokeWidth="2"/>
      <polygon points="160,130 200,150 200,195 160,215 120,195 120,150" fill="#6A994E" stroke="#4E5E24" strokeWidth="2"/>
      <polygon points="100,170 140,190 140,235 100,255 60,235 60,190" fill="#C9893D" stroke="#6B4423" strokeWidth="2"/>
      <circle cx="100" cy="100" r="12" fill="#F2E5CA"/>
      <text x="100" y="106" textAnchor="middle" fontSize="14" fontWeight="700" fill="#8B3A0F">8</text>
    </svg>
  ),
  darwin: (g) => (
    <svg viewBox="0 0 200 280" width="100%" height="100%" preserveAspectRatio="xMidYMid slice">
      <rect width="200" height="280" fill="#C8D4E3"/>
      <path d="M0 180 Q50 160 100 175 T200 170 L200 280 L0 280 Z" fill="#7D9AB8"/>
      <path d="M20 240 Q100 210 180 245 L180 280 L20 280 Z" fill="#3E5F7E"/>
      <ellipse cx="100" cy="120" rx="60" ry="80" fill="#F5F1E8" opacity="0.7"/>
      <path d="M80 90 L120 90 L115 140 L85 140 Z" fill="#8B5A2B"/>
      <circle cx="100" cy="85" r="12" fill="#D4B478"/>
      <path d="M70 95 Q60 80 75 70" stroke="#8B5A2B" strokeWidth="3" fill="none"/>
    </svg>
  ),
  diceForge: (g) => (
    <svg viewBox="0 0 200 280" width="100%" height="100%" preserveAspectRatio="xMidYMid slice">
      <defs>
        <radialGradient id="df-bg" cx="0.5" cy="0.5">
          <stop offset="0" stopColor="#E8D5B0"/>
          <stop offset="1" stopColor="#A88250"/>
        </radialGradient>
      </defs>
      <rect width="200" height="280" fill="url(#df-bg)"/>
      <polygon points="100,70 130,110 115,180 85,180 70,110" fill="#C73E4A" stroke="#5C1A20" strokeWidth="2"/>
      <polygon points="100,70 115,95 85,95" fill="#E85A68"/>
      <polygon points="85,180 115,180 105,210 95,210" fill="#5C1A20"/>
      <text x="100" y="260" textAnchor="middle" fontFamily="Georgia, serif"
        fontWeight="900" fontSize="18" fill="#5C1A20">DICE FORGE</text>
    </svg>
  ),
  bloodRage: (g) => (
    <svg viewBox="0 0 200 280" width="100%" height="100%" preserveAspectRatio="xMidYMid slice">
      <rect width="200" height="280" fill="#8B1A1A"/>
      <path d="M0 200 L60 150 L100 180 L140 140 L200 190 L200 280 L0 280 Z" fill="#3D0808"/>
      <circle cx="100" cy="100" r="40" fill="#E8A048" opacity="0.8"/>
      <path d="M80 80 L100 50 L120 80 L115 110 L85 110 Z" fill="#2A0404"/>
    </svg>
  ),
  odin: (g) => (
    <svg viewBox="0 0 200 280" width="100%" height="100%" preserveAspectRatio="xMidYMid slice">
      <rect width="200" height="280" fill="#6B8E4E"/>
      <circle cx="100" cy="120" r="50" fill="#F2E5CA" opacity="0.9"/>
      <path d="M70 110 L100 80 L130 110 L120 145 L80 145 Z" fill="#3D2817"/>
      <rect x="90" y="145" width="20" height="50" fill="#8B5A2B"/>
      <text x="100" y="240" textAnchor="middle" fontFamily="Georgia, serif"
        fontWeight="900" fontSize="28" fill="#F2E5CA">ODIN</text>
    </svg>
  ),
  default: (g) => (
    <svg viewBox="0 0 200 280" width="100%" height="100%" preserveAspectRatio="xMidYMid slice">
      <rect width="200" height="280" fill={g.bg || '#D4B878'}/>
      <circle cx="100" cy="140" r="60" fill={LL.navy} opacity="0.15"/>
      <text x="100" y="155" textAnchor="middle" fontFamily="Georgia, serif"
        fontWeight="900" fontSize="48" fill={LL.navy} opacity="0.4">
        {g.name?.[0] || '?'}
      </text>
    </svg>
  ),
};

// The game catalog used across the app
const GAMES = [
  { id: 'scythe', name: 'Scythe', art: 'scythe', bg: '#C89B5C',
    players: '1-5', duration: '90-115 min', mood: 'strategic', weight: 3.4, price: 74.90,
    desc: "Un jeu de stratégie épique dans une Europe de l'Est alternative des années 1920, où des factions s'affrontent pour la gloire." },
  { id: 'dixit', name: 'Dixit', art: 'dixit', bg: '#F5E8D0',
    players: '3-6', duration: '30 min', mood: 'creative', weight: 1.2, price: 32.90,
    desc: "Un jeu poétique d'imagination et de narration avec des illustrations oniriques." },
  { id: 'trio', name: 'Trio', art: 'trio', bg: '#E6B33A',
    players: '3-6', duration: '15 min', mood: 'party', weight: 1.1, price: 12.90,
    desc: "Un jeu de déduction ultra-simple et malin. Trouvez les trios !" },
  { id: 'catan', name: 'Catan', art: 'catan', bg: '#E8A048',
    players: '3-4', duration: '75 min', mood: 'strategic', weight: 2.3, price: 44.90,
    desc: "Négociez, construisez, développez votre île. Le classique intemporel." },
  { id: 'darwin', name: "Darwin's Journey", art: 'darwin', bg: '#C8D4E3',
    players: '1-4', duration: '60-120 min', mood: 'strategic', weight: 3.8, price: 64.90,
    desc: "Un jeu de placement d'ouvriers qui propose un système de progression des ouvriers innovant où chaque ouvrier devra étudier les disciplines qui sont un prérequis pour effectuer plusieurs actions dans le jeu." },
  { id: 'dice-forge', name: 'Dice Forge', art: 'diceForge', bg: '#C89B5C',
    players: '2-4', duration: '45 min', mood: 'mid', weight: 2.1, price: 34.90,
    desc: "Forgez vos dés, développez vos pouvoirs divins. Alea jacta est !" },
  { id: 'blood-rage', name: 'Blood Rage', art: 'bloodRage', bg: '#8B1A1A',
    players: '2-4', duration: '90 min', mood: 'competitive', weight: 2.9, price: 79.90,
    desc: "Vikings, gloire et rage. Un jeu de conquête brutal et tactique." },
  { id: 'odin', name: 'Odin', art: 'odin', bg: '#6B8E4E',
    players: '2-6', duration: '20 min', mood: 'family', weight: 1.8, price: 19.90,
    desc: "Un jeu de cartes rapide aux décisions tranchantes." },
];

Object.assign(window, { LL, FoldedCard, GameTile, GameCover, LoadingDie, GAME_ART, GAMES });
