/* ui.jsx — shared presentational components. Exports to window. */
const { useState, useEffect, useRef } = React;

/* ---- Logo: a rounded die face (5 pips) ---- */
function Logo({ size = 28 }) {
  const pip = (cx, cy) => <circle cx={cx} cy={cy} r="2.4" fill="currentColor" />;
  return (
    <svg className="logo" width={size} height={size} viewBox="0 0 28 28" style={{ color: "var(--accent)" }}>
      <rect x="1.5" y="1.5" width="25" height="25" rx="7.5" fill="var(--accent-50)" stroke="var(--accent)" strokeWidth="1.6" />
      <g style={{ color: "var(--accent)" }}>
        {pip(8, 8)}{pip(20, 8)}{pip(14, 14)}{pip(8, 20)}{pip(20, 20)}
      </g>
    </svg>
  );
}

/* ---- Face glyph for a poker-die face ---- */
function Face({ face, k }) {
  return <span className={"face-glyph" + (k ? " k" : "")}>{face}</span>;
}

/* ---- Minimal line icons ---- */
function Icon({ name, size = 18 }) {
  const p = {
    width: size, height: size, viewBox: "0 0 24 24", fill: "none",
    stroke: "currentColor", strokeWidth: 1.9, strokeLinecap: "round", strokeLinejoin: "round",
  };
  const paths = {
    arrow: <path d="M5 12h14M13 6l6 6-6 6" />,
    back: <path d="M19 12H5M11 6l-6 6 6 6" />,
    plus: <path d="M12 5v14M5 12h14" />,
    minus: <path d="M5 12h14" />,
    check: <path d="M5 13l4 4L19 7" />,
    x: <path d="M6 6l12 12M18 6L6 18" />,
    play: <path d="M7 5l12 7-12 7z" />,
    crown: <path d="M4 18h16M3 7l4 5 5-7 5 7 4-5-2 11H5z" />,
    users: <g><circle cx="9" cy="8" r="3.2" /><path d="M3 19a6 6 0 0112 0M16 6a3 3 0 010 6M22 19a6 6 0 00-5-5.9" /></g>,
    grid: <g><rect x="4" y="4" width="7" height="7" rx="1.5" /><rect x="13" y="4" width="7" height="7" rx="1.5" /><rect x="4" y="13" width="7" height="7" rx="1.5" /><rect x="13" y="13" width="7" height="7" rx="1.5" /></g>,
    dice: <g><rect x="4" y="4" width="16" height="16" rx="4" /><circle cx="9" cy="9" r="1.2" fill="currentColor" /><circle cx="15" cy="15" r="1.2" fill="currentColor" /><circle cx="15" cy="9" r="1.2" fill="currentColor" /><circle cx="9" cy="15" r="1.2" fill="currentColor" /></g>,
    book: <path d="M4 5a2 2 0 012-2h13v16H6a2 2 0 00-2 2zM19 3v18" />,
    info: <g><circle cx="12" cy="12" r="9" /><path d="M12 11v5M12 8h.01" /></g>,
    trash: <path d="M4 7h16M9 7V5a1 1 0 011-1h4a1 1 0 011 1v2M6 7l1 13h10l1-13" />,
    chevron: <path d="M9 6l6 6-6 6" />,
    flag: <path d="M5 21V4M5 4h12l-2 4 2 4H5" />,
    racket:  <g><ellipse cx="9" cy="9.5" rx="5.5" ry="6.5" /><line x1="13" y1="15" x2="19" y2="21" strokeWidth="2.4" /></g>,
    dart:    <path d="M21 3L3 21M14 10l-4 4M9 15l-5 5M16 8l2-6 5 5-7 1z" />,
    bowling: <g><circle cx="12" cy="12" r="9" /><circle cx="9.5" cy="10.5" r="1.2" fill="currentColor" /><circle cx="12" cy="8" r="1.2" fill="currentColor" /><circle cx="14.5" cy="11" r="1.2" fill="currentColor" /></g>,
    cards:   <g><rect x="4" y="5" width="10" height="14" rx="2" /><rect x="10" y="8" width="10" height="14" rx="2" fill="none" /></g>,
    train:   <path d="M6 4h12a2 2 0 012 2v10a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2zM8 18l-2 3M16 18l2 3M12 12m-4-4h8M4 12h16" />,
    trophy:  <path d="M8 21h8M12 17v4M17 3H7l1 8a4 4 0 008 0l1-8zM5 3H3v3a4 4 0 004 4M19 3h2v3a4 4 0 01-4 4" />,
    sparkle: <path d="M12 3l1.8 5.2L19 10l-5.2 1.8L12 17l-1.8-5.2L5 10l5.2-1.8z" />,
    search: <g><circle cx="11" cy="11" r="7" /><path d="M20 20l-3.5-3.5" /></g>,
  };
  return <svg className="ic" {...p}>{paths[name]}</svg>;
}

function Avatar({ name, size = "" , idx = 0 }) {
  const initials = (name || "?").trim().slice(0, 1).toUpperCase();
  const hues = [285, 200, 152, 25, 320, 95, 250, 60];
  const h = hues[idx % hues.length];
  return (
    <span className={"avatar " + size} style={{ background: `oklch(0.58 0.16 ${h})` }}>{initials}</span>
  );
}

function Toast({ msg }) {
  if (!msg) return null;
  return <div className="toast">{msg}</div>;
}

/* DE / EN segmented language switch */
/* NumPad — numeric input without keyboard. */
function NumPad({ value, onChange, allowNegative }) {
  const rows = [['7','8','9'],['4','5','6'],['1','2','3'],['del','0', allowNegative ? 'neg' : 'clr']];
  function press(k) {
    if (k === 'del') { onChange(value.slice(0,-1) || ''); return; }
    if (k === 'neg') { onChange(value.startsWith('-') ? value.slice(1) : '-' + (value||'0')); return; }
    if (k === 'clr') { onChange(''); return; }
    if (value === '0' || value === '') onChange(k);
    else onChange(value + k);
  }
  return (
    <div style={{ display:'flex', flexDirection:'column', gap:6, marginBottom:4 }}>
      <div style={{ background:'var(--surface-2)', borderRadius:'var(--r)', padding:'10px 14px',
        fontFamily:'var(--font-display)', fontWeight:700, fontSize:26, textAlign:'right', minHeight:50,
        letterSpacing:'-0.02em', color:'var(--ink)', border:'1px solid var(--line)' }}>{value || '0'}</div>
      {rows.map((row, ri) => (
        <div key={ri} style={{ display:'grid', gridTemplateColumns:'repeat(3,1fr)', gap:6 }}>
          {row.map(k => (
            <button key={k} className="btn"
              style={{ height:50, fontSize: (k==='del'||k==='neg'||k==='clr') ? 16 : 20, fontWeight:700,
                background: k==='del'||k==='clr' ? 'var(--surface-2)' : undefined }}
              onClick={() => press(k)}>
              {k==='del' ? '⌫' : k==='neg' ? '±' : k==='clr' ? 'C' : k}
            </button>
          ))}
        </div>
      ))}
    </div>
  );
}

/* Universal rules modal — looks up window.GAME_RULES[gameId] */
function GameRulesModal({ gameId, lang, onClose }) {
  const rules = window.GAME_RULES?.[gameId];
  const bullets = rules ? (lang === "en" ? rules.en : rules.de) : null;
  if (!bullets) return null;
  return (
    <div className="scrim" onClick={onClose}>
      <div className="modal wide" onClick={(e) => e.stopPropagation()} style={{ maxHeight: "86vh", overflowY: "auto" }}>
        <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 16 }}>
          <Icon name="book" size={20} /><h3>{t("game." + gameId + ".name")}</h3>
          <button className="iconbtn" style={{ marginLeft: "auto", width: 32, height: 32 }} onClick={onClose}><Icon name="x" size={16} /></button>
        </div>
        <ul style={{ paddingLeft: 20, display: "flex", flexDirection: "column", gap: 12, margin: 0 }}>
          {bullets.map((b, i) => (
            <li key={i} style={{ fontSize: 14.5, lineHeight: 1.6, color: "var(--ink-2)" }}>{b}</li>
          ))}
        </ul>
        <button className="btn ghost block" style={{ marginTop: 18 }} onClick={onClose}>{t("res.close")}</button>
      </div>
    </div>
  );
}

function LangToggle({ lang, onChange }) {
  return (
    <div className="lang-toggle" role="group" aria-label="Language">
      {["de", "en"].map((l) => (
        <button key={l} className={"lt-opt" + (lang === l ? " on" : "")} onClick={() => onChange(l)} aria-pressed={lang === l}>
          {l.toUpperCase()}
        </button>
      ))}
    </div>
  );
}

/* generic stepper */
function Stepper({ value, min = 1, max = 9, onChange }) {
  return (
    <div className="stepper">
      <button onClick={() => onChange(Math.max(min, value - 1))} disabled={value <= min}>−</button>
      <span className="val">{value}</span>
      <button onClick={() => onChange(Math.min(max, value + 1))} disabled={value >= max}>+</button>
    </div>
  );
}

Object.assign(window, { Logo, Face, Icon, Avatar, Toast, LangToggle, Stepper, GameRulesModal, NumPad });
