/* Extras.jsx — BootScreen, StatsModal, PalettePicker. Exports to window. */
const { useEffect: useEx, useState: useSx } = React;

function PixelLogo({ size }) {
  size = size || 64;
  const fills = [[1,0],[3,0],[0,1],[1,1],[2,1],[3,1],[4,1],[0,2],[1,2],[2,2],[3,2],[4,2],[1,3],[2,3],[3,3],[2,4]];
  return (
    <svg width={size} height={size} viewBox="0 0 5 5" shapeRendering="crispEdges" style={{ display: "block" }}>
      {fills.map(([x, y], i) => <rect key={i} x={x} y={y} width="1" height="1" fill="var(--accent)" />)}
    </svg>
  );
}

function BootScreen({ onStart }) {
  useEx(() => {
    const go = () => onStart();
    window.addEventListener("keydown", go, { once: true });
    return () => window.removeEventListener("keydown", go);
  }, [onStart]);
  return (
    <div className="boot" onClick={onStart}>
      <div className="boot-inner">
        <div className="boot-logo"><PixelLogo size={92} /></div>
        <h1 className="boot-title">NONOGRAM<span className="ac"> LAB</span></h1>
        <div className="boot-sub">picture-logic puzzles</div>
        <div className="boot-start">PRESS&nbsp;START</div>
        <div className="boot-foot">© 2026 · insert coin</div>
      </div>
    </div>
  );
}

function StatTile({ num, label }) {
  return <div className="stat-tile"><div className="stat-num">{num}</div><div className="stat-lab">{label}</div></div>;
}

function StatsModal({ stats, puzzles, solvedMap, onClose }) {
  const solvedCount = puzzles.filter((p) => solvedMap[p.id] != null).length;
  const fastest = stats.fastestMs != null ? Engine.fmtTime(stats.fastestMs) : "—";
  const total = Engine.fmtTime(stats.totalMs || 0);
  return (
    <div className="modal-scrim" onClick={onClose}>
      <div className="stats-card" onClick={(e) => e.stopPropagation()}>
        <div className="modal-head">
          <span className="modal-title">Player Card</span>
          <button className="modal-x" onClick={onClose}>✕</button>
        </div>
        <div className="stat-grid">
          <StatTile num={solvedCount + "/" + puzzles.length} label="collection" />
          <StatTile num={stats.streak || 0} label="daily streak" />
          <StatTile num={stats.bestStreak || 0} label="best streak" />
          <StatTile num={stats.plays || 0} label="total solves" />
          <StatTile num={fastest} label="fastest" />
          <StatTile num={total} label="time played" />
        </div>
        <div className="collection-label">Collection</div>
        <div className="collection">
          {puzzles.map((p) => {
            const solved = solvedMap[p.id] != null;
            return (
              <div key={p.id} className={"coll-cell" + (solved ? " on" : "")} title={solved ? p.tag : "locked"}>
                {solved ? (
                  <div className="coll-grid" style={{ gridTemplateColumns: `repeat(${p.cols},1fr)`, gridTemplateRows: `repeat(${p.rows},1fr)` }}>
                    {p.colorSolution.map((row, r) => row.map((col, c) => <span key={r + "-" + c} style={{ background: col === "transparent" ? "transparent" : col }} />))}
                  </div>
                ) : <span className="coll-q">?</span>}
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}

function LibTile({ p, solved, best, active, onClick }) {
  return (
    <button className={"lib-tile" + (active ? " active" : "")} onClick={onClick} title={solved ? p.tag : "unsolved"}>
      <div className="lib-tile-thumb">
        {solved ? (
          <div className="grid" style={{ gridTemplateColumns: `repeat(${p.cols},1fr)`, gridTemplateRows: `repeat(${p.rows},1fr)` }}>
            {p.colorSolution.map((row, r) => row.map((col, c) => <span key={r + "-" + c} style={{ background: col === "transparent" ? "transparent" : col }} />))}
          </div>
        ) : <span className="lib-tile-q">?</span>}
      </div>
      <div className="lib-tile-body">
        <div className="lib-tile-name">{p.name}</div>
        <div className="lib-tile-meta">
          <span>{p.rows}×{p.cols}</span>
          {solved ? <span className="lib-tile-best">{Engine.fmtTime(best)}</span> : <span className="lib-tile-lock">○ unsolved</span>}
        </div>
      </div>
    </button>
  );
}

function LibraryModal({ puzzles, currentId, solvedMap, onSelect, onClose }) {
  const TIERS = [
    { key: "Warm-up", label: "Warm-up" },
    { key: "Easy", label: "Easy" },
    { key: "Medium", label: "Medium" },
    { key: "Tricky", label: "Tricky" },
    { key: "Challenge", label: "Challenge" },
    { key: "Color", label: "Color" },
  ];
  const tierOf = (p) => (p.colored ? "Color" : (p.level || "Easy"));
  const groups = TIERS
    .map((t) => ({ ...t, items: puzzles.filter((p) => tierOf(p) === t.key) }))
    .filter((g) => g.items.length);
  const curObj = puzzles.find((p) => p.id === currentId);
  const curTier = curObj ? tierOf(curObj) : (groups[0] && groups[0].key);
  const [tab, setTab] = useSx(curTier || (groups[0] && groups[0].key));
  const active = groups.find((g) => g.key === tab) || groups[0];
  const solvedTotal = puzzles.filter((p) => solvedMap[p.id] != null).length;
  const pctTotal = Math.round((solvedTotal / puzzles.length) * 100);
  const shuffle = () => {
    const pool = puzzles.filter((p) => solvedMap[p.id] == null);
    const list = pool.length ? pool : puzzles;
    const pick = list[Math.floor(Math.random() * list.length)];
    if (pick) onSelect(pick.id);
  };
  useEx(() => {
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [onClose]);
  return (
    <div className="modal-scrim" onClick={onClose}>
      <div className="lib-modal-card" onClick={(e) => e.stopPropagation()}>
        <div className="lib-modal-head">
          <span className="lib-modal-title">Puzzle Library</span>
          <div className="lib-modal-prog">
            <div className="bar"><span style={{ width: pctTotal + "%" }} /></div>
            <span className="pct">{solvedTotal}/{puzzles.length} solved</span>
          </div>
          <button className="lib-modal-x" onClick={onClose} aria-label="Close">✕</button>
        </div>
        <div className="lib-tabs">
          {groups.map((g) => {
            const s = g.items.filter((p) => solvedMap[p.id] != null).length;
            const done = s === g.items.length;
            return (
              <button key={g.key} className={"lib-tab" + (g.key === tab ? " on" : "") + (done ? " done" : "")} onClick={() => setTab(g.key)}>
                {g.label}<span className="tcount">{s}/{g.items.length}</span>
              </button>
            );
          })}
        </div>
        <div className="lib-grid-wrap">
          <div className="lib-grid">
            {active.items.map((p) => {
              const best = solvedMap[p.id];
              return <LibTile key={p.id} p={p} solved={best != null} best={best} active={p.id === currentId} onClick={() => onSelect(p.id)} />;
            })}
          </div>
        </div>
        <div className="lib-modal-foot">
          <span className="lib-foot-hint">Pictures stay hidden until you solve them.</span>
          <button className="lib-shuffle-btn" onClick={shuffle}>
            <svg viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" strokeWidth="1.4" strokeLinecap="square" strokeLinejoin="miter"><path d="M2 4 H6 L13 12" /><path d="M2 12 H6 L13 4" /><path d="M10.5 4 H14 V7" /><path d="M10.5 12 H14 V9" /></svg>
            Random unsolved
          </button>
        </div>
      </div>
    </div>
  );
}

function PalettePicker({ palette, value, onChange, withErase, label }) {
  return (
    <div className="palette">
      {label && <span className="palette-label">{label}</span>}
      {palette.map((hex, i) => {
        const idx = i + 1;
        return (
          <button key={i} className={"swatch" + (value === idx ? " on" : "")} style={{ background: hex }}
            onClick={() => onChange(idx)} aria-label={"color " + idx} />
        );
      })}
      {withErase && (
        <button className={"swatch erase" + (value === 0 ? " on" : "")} onClick={() => onChange(0)} aria-label="erase">✕</button>
      )}
    </div>
  );
}

Object.assign(window, { PixelLogo, BootScreen, StatsModal, PalettePicker, LibraryModal, LibTile });
