// MODIBU shared components

const { useState, useEffect, useRef, useMemo } = React;

// ============ Logo ============
function ModibuLogo({ size = 48, withTagline = false }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', width: '100%', gap: 8 }}>
      <div className="modibu-logo" style={{ 
        fontSize: size, 
        fontFamily: 'Fredoka', 
        fontWeight: 700, 
        color: '#1971C2',
        letterSpacing: '-0.02em',
        textTransform: 'uppercase',
        display: 'flex',
        justifyContent: 'center',
        alignItems: 'center',
        flexWrap: 'wrap',
        gap: 10
      }}>
        <span style={{ color: '#4DABF7' }}>Monopoli</span>
        <span style={{ color: '#FF6B6B' }}>CyberCare</span>
      </div>
      {withTagline && (
        <div style={{ 
          fontSize: Math.max(13, size * 0.35),
          fontFamily: 'Fredoka',
          fontWeight: 600,
          color: '#74C0FC',
          textAlign: 'center',
          lineHeight: 1.4
        }}>
          Bermain, belajar, dan peduli<br/>
          cegah cyberbullying!
        </div>
      )}
    </div>
  );
}

// ============ Decorative background ============
function CloudBG({ density = 'normal' }) {
  return (
    <div className="bg-clouds" aria-hidden="true">
      <Cloud style={{ top: '6%', left: '4%', width: 110, height: 36 }} />
      <Cloud style={{ top: '14%', right: '7%', width: 140, height: 44 }} />
      <Cloud style={{ top: '38%', left: '12%', width: 86, height: 28 }} />
      {density === 'normal' && (
        <>
          <Cloud style={{ top: '58%', right: '4%', width: 100, height: 32 }} />
          <Cloud style={{ top: '72%', left: '6%', width: 130, height: 40 }} />
        </>
      )}
    </div>
  );
}
function Cloud({ style }) {
  // simple cloud: a pill + two circles via pseudos (CSS .c)
  return <div className="c" style={{
    ...style,
    borderRadius: 999,
  }}>
    <div style={{
      position: 'absolute',
      width: '40%', height: '160%',
      borderRadius: '50%',
      background: 'white',
      left: '15%', top: '-50%',
    }} />
    <div style={{
      position: 'absolute',
      width: '34%', height: '130%',
      borderRadius: '50%',
      background: 'white',
      right: '15%', top: '-30%',
    }} />
  </div>;
}

// ============ Skyline (silhouette of buildings at bottom) ============
function Skyline() {
  return (
    <svg className="skyline" viewBox="0 0 1440 110" preserveAspectRatio="none" style={{ width: '100%', height: '110px' }}>
      <defs>
        <linearGradient id="bg1" x1="0" x2="0" y1="0" y2="1">
          <stop offset="0%" stopColor="#7BC8EE" />
          <stop offset="100%" stopColor="#5BB8FD" />
        </linearGradient>
        <linearGradient id="bg2" x1="0" x2="0" y1="0" y2="1">
          <stop offset="0%" stopColor="#9DD9F4" />
          <stop offset="100%" stopColor="#7BC8EE" />
        </linearGradient>
      </defs>
      {/* Back row */}
      <g fill="url(#bg2)" opacity="0.7">
        <rect x="0" y="62" width="80" height="48" />
        <rect x="60" y="48" width="60" height="62" />
        <rect x="110" y="56" width="70" height="54" />
        <rect x="160" y="40" width="40" height="70" />
        <rect x="180" y="58" width="90" height="52" />
        <rect x="240" y="50" width="50" height="60" />
        <rect x="280" y="62" width="80" height="48" />
        <rect x="350" y="46" width="60" height="64" />
        <rect x="400" y="58" width="80" height="52" />
        <rect x="470" y="50" width="50" height="60" />
        <rect x="510" y="60" width="70" height="50" />
        <rect x="570" y="44" width="60" height="66" />
        <rect x="620" y="58" width="80" height="52" />
        <rect x="690" y="50" width="50" height="60" />
        <rect x="730" y="62" width="90" height="48" />
        <rect x="810" y="48" width="60" height="62" />
        <rect x="860" y="58" width="80" height="52" />
        <rect x="930" y="50" width="50" height="60" />
        <rect x="970" y="62" width="90" height="48" />
        <rect x="1050" y="44" width="60" height="66" />
        <rect x="1100" y="58" width="80" height="52" />
        <rect x="1170" y="50" width="50" height="60" />
        <rect x="1210" y="62" width="80" height="48" />
        <rect x="1280" y="46" width="60" height="64" />
        <rect x="1330" y="58" width="80" height="52" />
        <rect x="1400" y="50" width="50" height="60" />
      </g>
      {/* Front row darker */}
      <g fill="url(#bg1)">
        <rect x="0" y="78" width="40" height="32" />
        <rect x="40" y="70" width="80" height="40" />
        <rect x="120" y="84" width="60" height="26" />
        <rect x="180" y="74" width="80" height="36" />
        <rect x="260" y="80" width="60" height="30" />
        <rect x="320" y="68" width="100" height="42" />
        <rect x="420" y="80" width="50" height="30" />
        <rect x="470" y="74" width="80" height="36" />
        <rect x="550" y="84" width="60" height="26" />
        <rect x="610" y="70" width="100" height="40" />
        <rect x="710" y="80" width="50" height="30" />
        <rect x="760" y="74" width="80" height="36" />
        <rect x="840" y="68" width="100" height="42" />
        <rect x="940" y="80" width="50" height="30" />
        <rect x="990" y="74" width="80" height="36" />
        <rect x="1070" y="84" width="60" height="26" />
        <rect x="1130" y="70" width="100" height="40" />
        <rect x="1230" y="80" width="50" height="30" />
        <rect x="1280" y="74" width="100" height="36" />
        <rect x="1380" y="80" width="60" height="30" />
      </g>
      {/* Windows dots */}
      <g fill="#FFD93D" opacity="0.85">
        {Array.from({ length: 48 }).map((_, i) => (
          <rect key={i} x={20 + i * 30} y={86 + (i % 3) * 6} width="3" height="3" />
        ))}
      </g>
    </svg>
  );
}

// ============ Avatar ============
function Avatar({ color, label, size = 56, active = false }) {
  const cls = `avatar ${color}${active ? ' active' : ''}`;
  const sizeStr = typeof size === 'number' ? `${size}px` : size;
  const fontSize = typeof size === 'number' ? `${size * 0.4}px` : `calc(${size} * 0.4)`;

  const isImage = label && (label.startsWith('/') || label.includes('.png'));

  return (
    <div className={cls} style={{ width: sizeStr, height: sizeStr, fontSize, overflow: 'hidden', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
      {isImage ? (
        <img src={label} alt="icon" style={{ width: '85%', height: '85%', objectFit: 'contain' }} />
      ) : label}
    </div>
  );
}

// ============ Pawn ============
function Pawn({ color, icon, size = 1 }) {
  const isImage = icon && (icon.startsWith('/') || icon.includes('.png'));

  if (isImage) {
    return (
      <div style={{
        width: 48, height: 48,
        transform: `scale(${size})`,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        filter: 'drop-shadow(0 2px 4px rgba(0,0,0,0.3))'
      }}>
        <img src={icon} alt="pawn" style={{ width: '100%', height: '100%', objectFit: 'contain' }} />
      </div>
    );
  }

  return (
    <div className={`pawn ${color}`} style={{ transform: `scale(${size})` }}>
      <div className="head" />
      <div className="stem" />
      <div className="base" />
    </div>
  );
}

// ============ Dice ============
const DICE_FACES = {
  1: [4],
  2: [0, 8],
  3: [0, 4, 8],
  4: [0, 2, 6, 8],
  5: [0, 2, 4, 6, 8],
  6: [0, 2, 3, 5, 6, 8],
};
function Dice({ value, rolling, size = 72 }) {
  const dots = DICE_FACES[value] || [4];
  const sizeStr = typeof size === 'number' ? `${size}px` : size;
  return (
    <div className={`dice${rolling ? ' rolling' : ''}`} style={{
      width: sizeStr, height: sizeStr,
      ['--dice-size']: sizeStr,
    }}>
      <div className="dice-face" style={{
        width: '78%', height: '78%',
      }}>
        {Array.from({ length: 9 }).map((_, i) => (
          <div key={i} style={{ visibility: dots.includes(i) ? 'visible' : 'hidden', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
            <div className="dice-dot" style={{
              width: 'clamp(5px, calc(var(--dice-size) * 0.17), 12px)',
              height: 'clamp(5px, calc(var(--dice-size) * 0.17), 12px)',
            }} />
          </div>
        ))}
      </div>
    </div>
  );
}

// ============ Score Pill ============
function ScorePill({ player, active }) {
  return (
    <div className="score-pill">
      <Avatar color={player.color} label={player.icon} size={36} active={active} />
      <div style={{ display: 'flex', flexDirection: 'column', lineHeight: 1.05 }}>
        <span style={{ fontFamily: 'Fredoka', fontWeight: 600, fontSize: 13, color: 'var(--ink-soft)' }}>
          {player.name}
        </span>
        <span style={{ fontFamily: 'Fredoka', fontWeight: 700, fontSize: 17, color: 'var(--ink)' }}>
          {player.score} <span style={{ fontSize: 11, color: 'var(--ink-soft)', fontWeight: 500 }}>poin</span>
        </span>
      </div>
    </div>
  );
}

// ============ Tile icon (category) ============
function TileIcon({ type, size = 22 }) {
  const s = typeof size === 'string' ? size : `${size}px`;

  // Mapping to new public sticker images
  const StickerMap = {
    edukasi: '/book.png',
    fakta: '/fun-fact.png',
    tantangan: '/target.png',
    refleksi: '/thinking.png',
    kesempatan: '/dice-game.png',
    hukuman: '/shock.png',
    start: '/lets-go.png',
    finish: '/trophy.png',
    bonus: '/celebrating.png',
    penjara: '/not-accept.png'
  };

  const src = StickerMap[type];

  if (src) {
    return (
      <img
        src={src}
        alt={type}
        style={{
          width: '95%',
          height: '95%',
          objectFit: 'contain',
          filter: 'drop-shadow(0 2px 3px rgba(0,0,0,0.1))'
        }}
      />
    );
  }

  // Fallback to SVGs if image missing
  const Icons = {
    edukasi: (
      <svg viewBox="0 0 24 24" width={s} height={s} fill="none" stroke="white" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
        <path d="M3 8l9-4 9 4-9 4-9-4z" />
        <path d="M3 8v6c0 2 4 4 9 4s9-2 9-4V8" />
      </svg>
    ),
    fakta: (
      <svg viewBox="0 0 24 24" width={s} height={s} fill="none" stroke="white" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
        <circle cx="12" cy="12" r="9" />
        <path d="M12 8v4" /><path d="M12 16h.01" />
      </svg>
    ),
    tantangan: (
      <svg viewBox="0 0 24 24" width={s} height={s} fill="none" stroke="white" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
        <path d="M13 2L4 14h7l-1 8 9-12h-7l1-8z" />
      </svg>
    ),
    refleksi: (
      <svg viewBox="0 0 24 24" width={s} height={s} fill="none" stroke="white" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
        <path d="M21 12a9 9 0 1 1-3-6.7" />
        <path d="M14 7l4-1-1 4" />
      </svg>
    ),
    kesempatan: (
      <svg viewBox="0 0 24 24" width={s} height={s} fill="none" stroke="white" strokeWidth="2.6" strokeLinecap="round" strokeLinejoin="round">
        <path d="M9 9a3 3 0 1 1 6 0c0 2-3 2-3 5" />
        <circle cx="12" cy="18" r="0.8" fill="white" stroke="none" />
      </svg>
    ),
    hukuman: (
      <svg viewBox="0 0 24 24" width={s} height={s} fill="none" stroke="white" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
        <rect x="4" y="6" width="16" height="14" rx="2" />
        <path d="M8 6V4" /><path d="M16 6V4" />
        <path d="M8 11v6" /><path d="M12 11v6" /><path d="M16 11v6" />
      </svg>
    ),
    start: (
      <svg viewBox="0 0 24 24" width={s} height={s} fill="none" stroke="white" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
        <polygon points="5,3 21,12 5,21" fill="white" />
      </svg>
    ),
    finish: (
      <svg viewBox="0 0 24 24" width={s} height={s} fill="none" stroke="white" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
        <path d="M4 21V4" />
        <path d="M4 4h12l-2 4 2 4H4" fill="white" />
      </svg>
    ),
    penjara: (
      <svg viewBox="0 0 24 24" width={s} height={s} fill="none" stroke="white" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
        <circle cx="9" cy="15" r="3" /><circle cx="15" cy="15" r="3" />
        <path d="M9 12v0M15 12v0" />
        <path d="M3 9l4-5h10l4 5" />
      </svg>
    ),
    bonus: (
      <svg viewBox="0 0 24 24" width={s} height={s} fill="none" stroke="white" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
        <rect x="3" y="8" width="18" height="13" rx="1.5" />
        <path d="M3 12h18" /><path d="M12 8v13" />
        <path d="M7 8c0-2 2-3 3-2s2 2 2 2 1-1 2-2 3 0 3 2" />
      </svg>
    ),
  };
  return Icons[type] || null;
}

// ============ Chip ============
function Chip({ color, label, icon }) {
  return (
    <span className="chip">
      {color && <span className="chip-dot" style={{ background: color }} />}
      {icon}
      {label}
    </span>
  );
}

// ============ Section header ============
function SectionHeader({ title, sub, accent }) {
  return (
    <div style={{ marginBottom: 18 }}>
      <div className="h-title" style={{ fontSize: 28 }}>
        {accent && <span style={{ color: accent, marginRight: 8 }}>●</span>}
        {title}
      </div>
      {sub && <div style={{ color: 'var(--ink-soft)', fontSize: 14, marginTop: 4 }}>{sub}</div>}
    </div>
  );
}

// ============ Decorative monochrome backdrop pattern for tile ============
function TilePattern() {
  return (
    <div aria-hidden="true" style={{
      position: 'absolute', inset: 0, opacity: 0.12, pointerEvents: 'none',
      background: 'radial-gradient(circle at 30% 30%, white 0%, transparent 40%), radial-gradient(circle at 70% 80%, white 0%, transparent 40%)',
    }} />
  );
}

// expose
Object.assign(window, {
  ModibuLogo, CloudBG, Cloud, Skyline, Avatar, Pawn, Dice, ScorePill,
  TileIcon, Chip, SectionHeader, TilePattern,
});
