/* global React */

// =====================================================================
// Scroll Gambit chess module — dynamic board built from the user's
// piece sprites. One coordinate system (a8 top-left, h1 bottom-right).
// =====================================================================

// ---- Piece sprite map ----
const PIECE_SRC = {
  wP: 'assets/piece-w-pawn.png',
  wN: 'assets/piece-w-knight.png',
  wB: 'assets/piece-w-bishop.png',
  wR: 'assets/piece-w-rook.png',
  wQ: 'assets/piece-w-queen.png',
  wK: 'assets/piece-w-king.png',
  bP: 'assets/piece-b-pawn.png',
  bN: 'assets/piece-b-knight.png',
  bB: 'assets/piece-b-bishop.png',
  bR: 'assets/piece-b-rook.png',
  bQ: 'assets/piece-b-queen.png',
  bK: 'assets/piece-b-king.png',
};

function pieceSrc(code) {
  // code like 'wK' or 'bN'
  if (typeof window !== 'undefined' && window.__resources) {
    const key = 'piece' + code; // e.g. piecewK
    if (window.__resources[key]) return window.__resources[key];
  }
  return PIECE_SRC[code];
}

function PieceImage({ kind, size = 64, style = {} }) {
  // kind can be 'wN' or just 'N' (defaults to white).
  const code = kind.length === 1 ? 'w' + kind : kind;
  const src = pieceSrc(code);
  if (!src) return null;
  return (
    <img
      src={src}
      alt=""
      draggable={false}
      style={{
        width: size,
        height: size,
        display: 'block',
        userSelect: 'none',
        objectFit: 'contain',
        ...style,
      }}
    />
  );
}

// ---- Position helpers ----
function makePosition(map) {
  // map: { 'e4': 'wP', 'd5': 'bN', ... }
  const out = Array(64).fill('');
  for (const [sq, p] of Object.entries(map)) {
    const file = sq.charCodeAt(0) - 97;
    const rank = parseInt(sq[1], 10);
    out[(8 - rank) * 8 + file] = p;
  }
  return out;
}

function sqToIndex(sq) {
  const file = sq.charCodeAt(0) - 97;
  const rank = parseInt(sq[1], 10);
  return (8 - rank) * 8 + file;
}

function indexToSq(i) {
  const file = i % 8;
  const rank = 8 - Math.floor(i / 8);
  return 'abcdefgh'[file] + rank;
}

// ---- Positions ----
const STARTING_POSITION = makePosition({
  a8: 'bR', b8: 'bN', c8: 'bB', d8: 'bQ', e8: 'bK', f8: 'bB', g8: 'bN', h8: 'bR',
  a7: 'bP', b7: 'bP', c7: 'bP', d7: 'bP', e7: 'bP', f7: 'bP', g7: 'bP', h7: 'bP',
  a2: 'wP', b2: 'wP', c2: 'wP', d2: 'wP', e2: 'wP', f2: 'wP', g2: 'wP', h2: 'wP',
  a1: 'wR', b1: 'wN', c1: 'wB', d1: 'wQ', e1: 'wK', f1: 'wB', g1: 'wN', h1: 'wR',
});

// "Find the fork" — white to move, Nxf7! (knight forks Q on d8 and R on f8)
const FORK_POSITION = makePosition({
  a8: 'bR', d8: 'bQ', f8: 'bR', g8: 'bK', c8: 'bB',
  e7: 'bB', f6: 'bN', c6: 'bN',
  a7: 'bP', b7: 'bP', c7: 'bP', d7: 'bP', e6: 'bP', f7: 'bP', g7: 'bP', h7: 'bP',
  c4: 'wB', e5: 'wN', c3: 'wN',
  a2: 'wP', b2: 'wP', c2: 'wP', d4: 'wP', e4: 'wP', f2: 'wP', g2: 'wP', h2: 'wP',
  a1: 'wR', c1: 'wB', d1: 'wQ', f1: 'wR', g1: 'wK',
});

// Knight on e5 can go to: c4(own bishop), d3, c6(capture), d7(capture),
// f7(WINNING capture), g6, g4, f3. Filter own-side blocks → 7 legal moves.
const FORK_E5_KNIGHT_MOVES = ['d3', 'c6!', 'd7!', 'f7!', 'g6', 'g4', 'f3'];
const FORK_SOLUTION = { from: 'e5', to: 'f7' };

// =====================================================================
// Chessboard — branded ivory + electric-blue squares, piece sprites on
// top. Optional click hotspots and move/highlight overlays.
// =====================================================================
function Chessboard({
  position,
  size = 360,
  onSquareClick,
  selected,
  candidateMoves = [],
  highlightFrom,
  highlightTo,
  selectable,        // optional set of square names that should look clickable
  showCoords = true,
}) {
  const sq = size / 8;

  function squareName(file, row) {
    // row 0 = top = rank 8
    const rank = 8 - row;
    return 'abcdefgh'[file] + rank;
  }

  return (
    <div
      style={{
        width: size,
        height: size,
        borderRadius: 14,
        overflow: 'hidden',
        position: 'relative',
        boxShadow:
          '0 30px 60px -20px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,255,255,0.06), 0 0 0 6px rgba(255,255,255,0.02)',
        userSelect: 'none',
      }}
    >
      {Array.from({ length: 64 }).map((_, i) => {
        const row = Math.floor(i / 8);
        const col = i % 8;
        const light = (row + col) % 2 === 0;
        const name = squareName(col, row);
        const piece = position[i];
        const isSelected = name === selected;
        const isHighlightFrom = name === highlightFrom;
        const isHighlightTo = name === highlightTo;
        const move = candidateMoves.find(
          (m) => (m.endsWith('!') ? m.slice(0, -1) : m) === name
        );
        const isCapture = move && move.endsWith('!');
        const isMove = !!move;
        const isHinted = selectable && selectable.has(name);

        const handleClick = onSquareClick ? () => onSquareClick(name) : undefined;

        return (
          <div
            key={i}
            onClick={handleClick}
            style={{
              position: 'absolute',
              left: col * sq,
              top: row * sq,
              width: sq,
              height: sq,
              background: light ? '#f3ebd2' : '#2a6df8',
              display: 'flex',
              alignItems: 'center',
              justifyContent: 'center',
              cursor: handleClick ? 'pointer' : 'default',
            }}
          >
            {/* From / to last-move tint */}
            {(isHighlightFrom || isHighlightTo) && (
              <div
                style={{
                  position: 'absolute',
                  inset: 0,
                  background: isHighlightTo
                    ? 'rgba(255, 210, 74, 0.42)'
                    : 'rgba(255, 210, 74, 0.32)',
                  pointerEvents: 'none',
                }}
              />
            )}

            {/* Hinted (clickable cue) outline */}
            {isHinted && !isSelected && (
              <div
                style={{
                  position: 'absolute',
                  inset: '6%',
                  borderRadius: 4,
                  boxShadow: '0 0 0 2.5px rgba(255, 210, 74, 0.65), 0 0 14px rgba(255, 210, 74, 0.45)',
                  pointerEvents: 'none',
                  animation: 'sg-piece-pulse 1.7s ease-in-out infinite',
                }}
              />
            )}

            {/* Selected outline */}
            {isSelected && (
              <div
                style={{
                  position: 'absolute',
                  inset: 0,
                  boxShadow: 'inset 0 0 0 4px #ffd24a',
                  background: 'rgba(255, 210, 74, 0.16)',
                  pointerEvents: 'none',
                }}
              />
            )}

            {/* Piece */}
            {piece && (
              <div style={{ position: 'relative', zIndex: 1, width: '102%', height: '102%' }}>
                <PieceImage kind={piece} size="100%" style={{ width: '100%', height: '100%' }} />
              </div>
            )}

            {/* Candidate move markers — rendered ABOVE pieces */}
            {isMove && !isCapture && (
              <div
                style={{
                  position: 'absolute',
                  width: '28%',
                  height: '28%',
                  borderRadius: '50%',
                  background: 'rgba(20, 25, 60, 0.42)',
                  pointerEvents: 'none',
                  zIndex: 2,
                }}
              />
            )}
            {isMove && isCapture && (
              <div
                style={{
                  position: 'absolute',
                  inset: '5%',
                  borderRadius: 6,
                  border: '3px solid rgba(20, 25, 60, 0.7)',
                  boxSizing: 'border-box',
                  pointerEvents: 'none',
                  zIndex: 2,
                }}
              />
            )}

            {/* Rank / file coordinates */}
            {showCoords && col === 0 && (
              <span
                style={{
                  position: 'absolute',
                  top: 2,
                  left: 4,
                  fontSize: Math.max(8, sq * 0.09),
                  fontWeight: 700,
                  color: light ? 'rgba(10,15,40,0.4)' : 'rgba(255,255,255,0.55)',
                  fontFamily: 'ui-monospace, monospace',
                  pointerEvents: 'none',
                }}
              >
                {8 - row}
              </span>
            )}
            {showCoords && row === 7 && (
              <span
                style={{
                  position: 'absolute',
                  bottom: 1,
                  right: 4,
                  fontSize: Math.max(8, sq * 0.09),
                  fontWeight: 700,
                  color: light ? 'rgba(10,15,40,0.4)' : 'rgba(255,255,255,0.55)',
                  fontFamily: 'ui-monospace, monospace',
                  pointerEvents: 'none',
                }}
              >
                {'abcdefgh'[col]}
              </span>
            )}
          </div>
        );
      })}
      <style>{`
        @keyframes sg-piece-pulse {
          0%, 100% { opacity: 1; }
          50% { opacity: 0.45; }
        }
      `}</style>
    </div>
  );
}

Object.assign(window, {
  Chessboard,
  PieceImage,
  makePosition,
  sqToIndex,
  indexToSq,
  pieceSrc,
  STARTING_POSITION,
  FORK_POSITION,
  FORK_E5_KNIGHT_MOVES,
  FORK_SOLUTION,
});
