/* ============================================================
   Minesweeper — classic Win95 rules for ATHARV.OS
   Beginner 9×9/10 · Intermediate 16×16/40 · Expert 30×16/99
   First click is always safe. Right-click (or long-press) flags.
   Zero-build: loaded as text/babel, exposed as a global.
============================================================ */

const MS_LEVELS = {
  beginner:     { cols: 9,  rows: 9,  mines: 10, label: 'Beginner' },
  intermediate: { cols: 16, rows: 16, mines: 40, label: 'Intermediate' },
  expert:       { cols: 30, rows: 16, mines: 99, label: 'Expert' },
};
const MS_NUM_COLORS = ['', '#0000FF', '#008000', '#FF0000', '#000080', '#800000', '#008080', '#000000', '#808080'];
// Bigger cells on touch viewports — 22px is too small a tap target.
const MS_CELL = (typeof window !== 'undefined' && window.matchMedia && window.matchMedia('(max-width: 900px)').matches) ? 30 : 22;
const MS_FONT = MS_CELL > 24 ? 16 : 13;

function msNeighbors(i, cols, rows) {
  const x = i % cols, y = Math.floor(i / cols), out = [];
  for (let dy = -1; dy <= 1; dy++) for (let dx = -1; dx <= 1; dx++) {
    if (!dx && !dy) continue;
    const nx = x + dx, ny = y + dy;
    if (nx >= 0 && nx < cols && ny >= 0 && ny < rows) out.push(ny * cols + nx);
  }
  return out;
}

function msFreshBoard(n) {
  return Array.from({ length: n }, () => ({ mine: false, adj: 0, open: false, flag: false }));
}

function Minesweeper() {
  const [levelKey, setLevelKey] = React.useState('beginner');
  const L = MS_LEVELS[levelKey];
  const total = L.cols * L.rows;

  const [board, setBoard] = React.useState(() => msFreshBoard(MS_LEVELS.beginner.cols * MS_LEVELS.beginner.rows));
  const [state, setState] = React.useState('idle');   // idle | playing | won | lost
  const [face, setFace] = React.useState('🙂');
  const [time, setTime] = React.useState(0);
  const longPress = React.useRef({ timer: null, fired: false });

  const reset = (key) => {
    const k = key || levelKey;
    setLevelKey(k);
    setBoard(msFreshBoard(MS_LEVELS[k].cols * MS_LEVELS[k].rows));
    setState('idle');
    setFace('🙂');
    setTime(0);
  };

  React.useEffect(() => {
    if (state !== 'playing') return;
    const t = setInterval(() => setTime(s => Math.min(999, s + 1)), 1000);
    return () => clearInterval(t);
  }, [state]);

  const plantMines = (b, safe) => {
    // First click safe: exclude the clicked cell and its neighbors.
    const banned = new Set([safe, ...msNeighbors(safe, L.cols, L.rows)]);
    let placed = 0;
    while (placed < L.mines) {
      const i = Math.floor(Math.random() * total);
      if (banned.has(i) || b[i].mine) continue;
      b[i].mine = true;
      placed++;
    }
    for (let i = 0; i < total; i++) {
      b[i].adj = msNeighbors(i, L.cols, L.rows).filter(j => b[j].mine).length;
    }
  };

  const floodOpen = (b, start) => {
    const stack = [start];
    while (stack.length) {
      const i = stack.pop();
      const c = b[i];
      if (c.open || c.flag) continue;
      c.open = true;
      if (!c.mine && c.adj === 0) {
        msNeighbors(i, L.cols, L.rows).forEach(j => { if (!b[j].open && !b[j].flag) stack.push(j); });
      }
    }
  };

  const openCell = (i) => {
    if (state === 'won' || state === 'lost') return;
    const b = board.map(c => ({ ...c }));
    if (state === 'idle') { plantMines(b, i); setState('playing'); }
    const c = b[i];
    if (c.open || c.flag) return;
    if (c.mine) {
      b.forEach(x => { if (x.mine) x.open = true; });
      c.blew = true;
      setBoard(b);
      setState('lost');
      setFace('😵');
      if (window.sfx && window.sfx.ding) window.sfx.ding();
      return;
    }
    floodOpen(b, i);
    setBoard(b);
    const openCount = b.filter(x => x.open).length;
    if (openCount === total - L.mines) {
      b.forEach(x => { if (x.mine) x.flag = true; });
      setBoard(b);
      setState('won');
      setFace('😎');
      if (window.sfx && window.sfx.tada) window.sfx.tada();
    }
  };

  const toggleFlag = (i) => {
    if (state === 'won' || state === 'lost') return;
    const b = board.map(c => ({ ...c }));
    const c = b[i];
    if (c.open) return;
    c.flag = !c.flag;
    setBoard(b);
  };

  const flags = board.filter(c => c.flag).length;
  const minesLeft = Math.max(-99, L.mines - flags);
  const led = (n) => String(Math.max(0, n)).padStart(3, '0');

  const ledStyle = {
    background: '#000', color: '#FF0000', fontFamily: 'Fixedsys, Consolas, monospace',
    fontSize: 20, fontWeight: 700, padding: '1px 4px', letterSpacing: 2,
    border: '1px solid', borderColor: '#808080 #FFF #FFF #808080', minWidth: 52, textAlign: 'center',
  };

  return (
    <div style={{ display: 'flex', flexDirection: 'column', flex: 1, minHeight: 0 }}>
      <div className="menubar">
        {Object.keys(MS_LEVELS).map(k => (
          <button key={k} style={{ fontWeight: levelKey === k ? 700 : 400 }} onClick={() => reset(k)}>
            {MS_LEVELS[k].label}
          </button>
        ))}
      </div>
      <div style={{ flex: 1, minHeight: 0, overflow: 'auto', padding: 8, background: 'var(--w95-gray, #C0C0C0)' }}>
        <div className="sunken" style={{ display: 'inline-block', padding: 8, background: 'var(--w95-gray, #C0C0C0)' }}>
          {/* Header: mines LED · face · timer LED */}
          <div className="sunken" style={{
            display: 'flex', alignItems: 'center', justifyContent: 'space-between',
            padding: '4px 6px', marginBottom: 8, gap: 8,
          }}>
            <span style={ledStyle}>{led(minesLeft)}</span>
            <button
              className="btn"
              style={{ minWidth: 34, width: 34, height: 30, padding: 0, fontSize: 16 }}
              aria-label="New game"
              onClick={() => reset()}
            >{face}</button>
            <span style={ledStyle}>{led(time)}</span>
          </div>
          {/* Board */}
          <div
            style={{
              display: 'grid',
              gridTemplateColumns: `repeat(${L.cols}, ${MS_CELL}px)`,
              gridAutoRows: `${MS_CELL}px`,
              userSelect: 'none',
            }}
            onMouseDown={() => { if (state === 'idle' || state === 'playing') setFace('😮'); }}
            onMouseUp={() => { if (state === 'idle' || state === 'playing') setFace('🙂'); }}
            onMouseLeave={() => { if (state === 'idle' || state === 'playing') setFace('🙂'); }}
          >
            {board.map((c, i) => {
              const open = c.open;
              const cellStyle = {
                width: MS_CELL, height: MS_CELL,
                fontSize: MS_FONT, fontWeight: 700, lineHeight: `${MS_CELL - 4}px`, textAlign: 'center',
                cursor: state === 'won' || state === 'lost' ? 'default' : 'pointer',
                boxSizing: 'border-box',
                ...(open
                  ? { border: '1px solid #808080', borderWidth: '1px 0 0 1px', background: c.blew ? '#FF0000' : '#C0C0C0', color: MS_NUM_COLORS[c.adj] || '#000' }
                  : { border: '2px solid', borderColor: '#FFFFFF #808080 #808080 #FFFFFF', background: '#C0C0C0' }),
              };
              return (
                <div
                  key={i}
                  style={cellStyle}
                  onClick={() => { if (longPress.current.fired) { longPress.current.fired = false; return; } openCell(i); }}
                  onContextMenu={(e) => { e.preventDefault(); toggleFlag(i); }}
                  onTouchStart={() => {
                    longPress.current.fired = false;
                    longPress.current.timer = setTimeout(() => { longPress.current.fired = true; toggleFlag(i); }, 350);
                  }}
                  onTouchEnd={() => clearTimeout(longPress.current.timer)}
                  onTouchMove={() => clearTimeout(longPress.current.timer)}
                >
                  {open
                    ? (c.mine ? '💣' : (c.adj || ''))
                    : (c.flag ? '🚩' : '')}
                </div>
              );
            })}
          </div>
        </div>
      </div>
      <div className="statusbar">
        <div className="scell flex">
          {state === 'won' ? 'You win! 😎' : state === 'lost' ? 'Boom. Click the face to retry.' : `${L.label} — ${L.mines} mines`}
        </div>
        <div className="scell">Right-click / long-press to flag</div>
      </div>
    </div>
  );
}

Object.assign(window, { Minesweeper });
