/* Chessboard component — SVG pieces, flippable, arrow overlay */

const PIECE_PATHS = {
  // Simplified Merida-ish piece silhouettes using compact SVG.
  // Each returns an <svg> string; rendered via data URL so CSS filter works.
  K: "k", Q: "q", R: "r", B: "b", N: "n", P: "p",
};

// We embed Wikimedia Commons style Cburnett-free piece SVGs inline.
// These are simplified vector silhouettes authored here (not copied).
function pieceSVG(letter, isWhite) {
  const fill = isWhite ? "#F8F2E3" : "#1A1511";
  const stroke = isWhite ? "#1A1511" : "#F8F2E3";
  const sw = 2.2;
  const common = `stroke="${stroke}" stroke-width="${sw}" stroke-linejoin="round" stroke-linecap="round" fill="${fill}"`;
  const L = letter.toLowerCase();
  let body = "";
  if (L === "p") {
    body = `
      <circle cx="22.5" cy="13" r="5.2" ${common}/>
      <path d="M14 36 Q14 27 22.5 23 Q31 27 31 36 Z" ${common}/>
      <path d="M10 41 Q22.5 36 35 41 L35 38 Q22.5 33 10 38 Z" ${common}/>
      <path d="M8 43 L37 43 L37 41 L8 41 Z" ${common}/>`;
  } else if (L === "n") {
    body = `
      <path d="M12 42 L35 42 L35 39 Q35 34 33 32 Q38 25 32 17
        Q29 12 24 10 Q22 7 22 4 L20 7 Q18 6 17 6 L18 10
        Q11 13 9 22 Q11 22 13 20 Q11 26 14 28 Q14 31 12 33 Q12 37 12 42 Z" ${common}/>
      <circle cx="18.5" cy="18" r="1.3" fill="${stroke}"/>`;
  } else if (L === "b") {
    body = `
      <circle cx="22.5" cy="9" r="3" ${common}/>
      <path d="M14 30 Q14 20 22.5 15 Q31 20 31 30 Q27 33 22.5 33 Q18 33 14 30 Z" ${common}/>
      <path d="M11 38 Q22.5 34 34 38 L34 36 Q22.5 32 11 36 Z" ${common}/>
      <path d="M9 42 L36 42 L36 40 L9 40 Z" ${common}/>
      <path d="M20 22 L25 22 M22.5 20 L22.5 24" stroke="${stroke}" stroke-width="1.6"/>`;
  } else if (L === "r") {
    body = `
      <path d="M10 10 L13 10 L13 13 L17 13 L17 10 L20 10 L20 13 L25 13 L25 10 L28 10 L28 13 L32 13 L32 10 L35 10
        L35 17 L33 19 L33 30 L36 33 L36 37 L9 37 L9 33 L12 30 L12 19 L10 17 Z" ${common}/>
      <path d="M12 37 L33 37 L33 39 L36 39 L36 42 L9 42 L9 39 L12 39 Z" ${common}/>`;
  } else if (L === "q") {
    body = `
      <path d="M8 14 L11 22 L14 12 L17 22 L22.5 11 L28 22 L31 12 L34 22 L37 14
        L35 28 L32 30 L32 34 L13 34 L13 30 L10 28 Z" ${common}/>
      <path d="M11 36 Q22.5 33 34 36 L34 38 L11 38 Z" ${common}/>
      <path d="M9 40 L36 40 L36 42 L9 42 Z" ${common}/>
      <circle cx="8" cy="14" r="1.6" ${common}/>
      <circle cx="14" cy="11" r="1.6" ${common}/>
      <circle cx="22.5" cy="9" r="1.8" ${common}/>
      <circle cx="31" cy="11" r="1.6" ${common}/>
      <circle cx="37" cy="14" r="1.6" ${common}/>`;
  } else if (L === "k") {
    body = `
      <path d="M22.5 5 L22.5 12 M19 8 L26 8" stroke="${stroke}" stroke-width="2.4" stroke-linecap="round" fill="none"/>
      <path d="M14 30 Q11 26 13 22 Q16 18 22.5 19 Q29 18 32 22 Q34 26 31 30
        Q28 34 22.5 34 Q17 34 14 30 Z" ${common}/>
      <path d="M11 36 Q22.5 32 34 36 L34 38 L11 38 Z" ${common}/>
      <path d="M9 40 L36 40 L36 42 L9 42 Z" ${common}/>`;
  }
  return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 45 45">${body}</svg>`;
}

const pieceCache = {};
function piecePath(ch) {
  if (pieceCache[ch]) return pieceCache[ch];
  const isWhite = ch === ch.toUpperCase();
  const svg = pieceSVG(ch.toUpperCase(), isWhite);
  const enc = "data:image/svg+xml;utf8," + encodeURIComponent(svg);
  pieceCache[ch] = enc;
  return enc;
}

function Chessboard({ fen, highlight = [], from = null, to = null, flip = false, showCoords = true, arrow = null }) {
  const board = fenToBoard(fen || "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
  const files = flip ? ["h","g","f","e","d","c","b","a"] : ["a","b","c","d","e","f","g","h"];
  const ranks = flip ? [1,2,3,4,5,6,7,8] : [8,7,6,5,4,3,2,1];
  const sqs = [];
  ranks.forEach((r, ri) => {
    files.forEach((f, fi) => {
      const sq = f + r;
      const isLight = (ri + fi) % 2 === 0;
      // data order: flip inverts
      const origRank = flip ? (ri) : (7 - ri); // index in board array (rank 8 = 0)
      const origFile = flip ? (7 - fi) : fi;
      const piece = board[origRank][origFile];
      const classes = ["sq", isLight ? "l" : "d"];
      if (highlight.includes(sq)) classes.push("hi");
      if (from === sq) classes.push("from");
      if (to === sq) classes.push("hi");
      sqs.push(
        <div key={sq} className={classes.join(" ")} data-sq={sq}>
          {showCoords && fi === 0 && <span className="coord r">{r}</span>}
          {showCoords && ri === 7 && <span className="coord f">{f}</span>}
          {piece && (
            <div className="piece" style={{ backgroundImage: `url('${piecePath(piece)}')` }} />
          )}
        </div>
      );
    });
  });

  // arrow: {from, to, color}
  let arrowEl = null;
  if (arrow && arrow.from && arrow.to) {
    const fIdx = files.indexOf(arrow.from[0]);
    const rIdx = ranks.indexOf(parseInt(arrow.from[1]));
    const tIdx = files.indexOf(arrow.to[0]);
    const trIdx = ranks.indexOf(parseInt(arrow.to[1]));
    if (fIdx >= 0 && tIdx >= 0 && rIdx >= 0 && trIdx >= 0) {
      const x1 = (fIdx + 0.5) * 12.5;
      const y1 = (rIdx + 0.5) * 12.5;
      const x2 = (tIdx + 0.5) * 12.5;
      const y2 = (trIdx + 0.5) * 12.5;
      const color = arrow.color || "var(--accent)";
      arrowEl = (
        <svg className="cb-arrow-layer" viewBox="0 0 100 100" preserveAspectRatio="none">
          <defs>
            <marker id="arrowhead" markerWidth="4" markerHeight="4" refX="2" refY="2" orient="auto">
              <polygon points="0 0, 4 2, 0 4" fill={color} />
            </marker>
          </defs>
          <line x1={x1} y1={y1} x2={x2} y2={y2}
            stroke={color} strokeWidth="1.6" strokeLinecap="round"
            markerEnd="url(#arrowhead)" opacity="0.85" />
        </svg>
      );
    }
  }

  return (
    <div className="cb">
      {sqs}
      {arrowEl}
    </div>
  );
}

function MiniBoard({ fen }) {
  return (
    <div className="mini" style={{width:"100%",height:"100%"}}>
      <Chessboard fen={fen} showCoords={false} />
    </div>
  );
}

/* Chessground-based interactive board — uses Lichess's own board library loaded
   via ESM CDN. Falls back to the static SVG board above if chessground isn't ready yet. */
function ChessgroundBoard({ fen, flip, lastMove, onMove }) {
  const hostRef = React.useRef(null);
  const cgRef = React.useRef(null);
  const chessRef = React.useRef(null);

  React.useEffect(() => {
    if (!hostRef.current || !window.Chessground || !window.Chess) return;
    const chess = new window.Chess();
    try { chess.load(toFullFen(fen)); } catch (e) { /* ignore invalid fen */ }
    chessRef.current = chess;

    const cg = window.Chessground(hostRef.current, {
      fen: toFullFen(fen),
      orientation: flip ? 'black' : 'white',
      turnColor: chess.turn() === 'w' ? 'white' : 'black',
      movable: {
        free: false,
        color: chess.turn() === 'w' ? 'white' : 'black',
        dests: legalDests(chess),
        showDests: true,
        events: {
          after: (from, to) => {
            const c = chessRef.current;
            let res;
            try { res = c.move({ from, to, promotion: 'q' }); } catch { return; }
            if (!res) return;
            const newFen = c.fen();
            cg.set({
              fen: newFen,
              turnColor: c.turn() === 'w' ? 'white' : 'black',
              movable: {
                color: c.turn() === 'w' ? 'white' : 'black',
                dests: legalDests(c),
              },
              lastMove: [from, to],
            });
            if (onMove) onMove({ from, to, san: res.san, fen: newFen });
          },
        },
      },
      highlight: { lastMove: true, check: true },
      animation: { enabled: true, duration: 180 },
      lastMove: lastMove || undefined,
      drawable: { enabled: true, visible: true },
    });
    cgRef.current = cg;

    return () => { cg.destroy(); cgRef.current = null; };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // Update when fen prop changes externally (nav buttons, tree click)
  React.useEffect(() => {
    if (!cgRef.current || !chessRef.current) return;
    const full = toFullFen(fen);
    try { chessRef.current.load(full); } catch { return; }
    cgRef.current.set({
      fen: full,
      turnColor: chessRef.current.turn() === 'w' ? 'white' : 'black',
      movable: {
        color: chessRef.current.turn() === 'w' ? 'white' : 'black',
        dests: legalDests(chessRef.current),
      },
      lastMove: lastMove || undefined,
    });
  }, [fen, lastMove]);

  React.useEffect(() => {
    if (!cgRef.current) return;
    cgRef.current.set({ orientation: flip ? 'black' : 'white' });
  }, [flip]);

  return <div ref={hostRef} className="cg-host" />;
}

function toFullFen(fen) {
  if (!fen) return 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1';
  const parts = fen.split(' ');
  while (parts.length < 4) parts.push('-');
  if (parts.length === 4) parts.push('0');
  if (parts.length === 5) parts.push('1');
  return parts.join(' ');
}

function legalDests(chess) {
  const dests = new Map();
  const moves = chess.moves({ verbose: true });
  for (const m of moves) {
    if (!dests.has(m.from)) dests.set(m.from, []);
    dests.get(m.from).push(m.to);
  }
  return dests;
}

Object.assign(window, { Chessboard, MiniBoard, ChessgroundBoard, toFullFen });
