// atelier-screens-c.jsx — TargetsScreen: vulnerable piece scanner.
//
// Reads window.LESSON.vulnerability (computed by tools/vulnerability-analysis.js)
// and displays a board overlay + ranked list + factor breakdown. Two modes:
// Browse (see everything) and Exercise (click the weakest piece).
//
// Visual language matches Tension: 340 / 1fr / 340 grid, museum tones.

const { useState: useTS, useEffect: useTE, useMemo: useTM } = React;

const VULN_TONE = {
  stable: 'celadon',
  under_tension: 'brass',
  vulnerable: 'sienna',
  hanging: 'terracotta',
};

const VULN_COLOR_KEY = {
  stable: null,
  under_tension: 'brass',
  vulnerable: 'sienna',
  hanging: 'terracotta',
};

const PIECE_TO_GLYPH = {
  wP: '♙', wN: '♘', wB: '♗', wR: '♖', wQ: '♕', wK: '♔',
  bP: '♟', bN: '♞', bB: '♝', bR: '♜', bQ: '♛', bK: '♚',
};

function pieceTitle(code, square) {
  if (!code) return square;
  const color = code[0] === 'w' ? 'White' : 'Black';
  const kind = { P: 'pawn', N: 'knight', B: 'bishop', R: 'rook', Q: 'queen', K: 'king' }[code[1]] || code[1];
  return `${color} ${kind} on ${square}`;
}

// ── Board overlay: color-coded outlines per classification ─────────────
function VulnerabilityOverlay({ palette, byPiece, focusSquare, hoveredSquare, side, onSquareClick, size = 560 }) {
  const C = palette;
  const SQ = size / 8;

  // Build a list of decorations: one per piece classified above 'stable'.
  // The side filter is applied at the caller level (TargetsScreen builds
  // overlayByPiece with the inactive side flattened to 'stable').
  const decorations = Object.values(byPiece).filter((e) => e.classification !== 'stable');

  const colorFor = (cls) => {
    if (cls === 'hanging') return C.terracotta || C.sienna;
    if (cls === 'vulnerable') return C.sienna;
    if (cls === 'under_tension') return C.brass;
    return C.umberHair;
  };
  const fillFor = (cls) => {
    if (cls === 'hanging') return window.withAlpha(C.terracotta || C.sienna, 0.15);
    return 'transparent';
  };

  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} style={{ display: 'block' }}>
      {/* Board squares */}
      {[...Array(8)].flatMap((_, rank) => [...Array(8)].map((__, file) => {
        const sq = 'abcdefgh'[file] + (8 - rank);
        const isLight = (file + rank) % 2 === 0;
        return (
          <rect key={sq}
            x={file * SQ} y={rank * SQ}
            width={SQ} height={SQ}
            fill={isLight ? C.squareLight : C.squareDark || C.boneDeep}
            onClick={onSquareClick ? () => onSquareClick(sq) : undefined}
            style={{ cursor: onSquareClick ? 'pointer' : 'default' }}
          />
        );
      }))}

      {/* Pieces */}
      {Object.values(byPiece).map((entry) => {
        const file = entry.square.charCodeAt(0) - 'a'.charCodeAt(0);
        const rank = 8 - parseInt(entry.square[1], 10);
        const x = file * SQ + SQ / 2;
        const y = rank * SQ + SQ / 2 + SQ * 0.35;
        return (
          <text key={'p-' + entry.square}
            x={x} y={y}
            fontSize={SQ * 0.85}
            textAnchor="middle"
            fontFamily='"Noto Sans Symbols 2","Segoe UI Symbol",sans-serif'
            fill={entry.color === 'white' ? C.umber : C.umberSoft}
            pointerEvents="none"
          >{PIECE_TO_GLYPH[entry.piece] || '?'}</text>
        );
      })}

      {/* Classification outlines */}
      {decorations.map((entry) => {
        const file = entry.square.charCodeAt(0) - 'a'.charCodeAt(0);
        const rank = 8 - parseInt(entry.square[1], 10);
        const isFocus = entry.square === focusSquare;
        const isHover = entry.square === hoveredSquare;
        return (
          <rect key={'o-' + entry.square}
            x={file * SQ + 2} y={rank * SQ + 2}
            width={SQ - 4} height={SQ - 4}
            fill={fillFor(entry.classification)}
            stroke={colorFor(entry.classification)}
            strokeWidth={isFocus ? 3 : isHover ? 2 : 1.2}
            rx={2}
            pointerEvents="none"
          />
        );
      })}
    </svg>
  );
}

// ── Factor breakdown panel ────────────────────────────────────────────
function FactorPanel({ palette, entry }) {
  const C = palette;
  const T = window.COPY.targets;
  if (!entry) {
    return (
      <div style={{
        padding: '14px 16px',
        background: C.bone, borderRadius: 12,
        border: `0.6px dashed ${C.umberHair}`,
        fontFamily: window.ATELIER_TYPE.display, fontSize: 14, color: C.umberSoft,
      }}>
        Click a piece to see why it is — or is not — a target.
      </div>
    );
  }

  const classTone = VULN_COLOR_KEY[entry.classification];
  const palColor = classTone ? C[classTone] : C.umberSoft;

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
      <window.SectionHeading palette={C}
        kicker={pieceTitle(entry.piece, entry.square)}
        title={T.classLabels[entry.classification]} small />
      <div style={{
        padding: '12px 14px',
        background: window.withAlpha(palColor, 0.08),
        border: `0.6px solid ${palColor}`,
        borderRadius: 10,
        fontFamily: window.ATELIER_TYPE.display, fontSize: 14, lineHeight: 1.5,
        color: C.umberSoft,
      }}>
        {T.classBlurbs[entry.classification]}
      </div>

      {entry.factors && entry.factors.length > 0 && (
        <div style={{
          padding: '12px 14px',
          background: C.bone, borderRadius: 10, border: `0.6px solid ${C.umberHair}`,
        }}>
          <div style={{
            fontFamily: window.ATELIER_TYPE.ui, fontSize: 9, letterSpacing: 3,
            textTransform: 'uppercase', color: C.umberFaint, marginBottom: 8,
          }}>{T.factorsLabel}</div>
          <ul style={{ margin: 0, padding: 0, listStyle: 'none', display: 'flex', flexDirection: 'column', gap: 8 }}>
            {entry.factors.map((f, i) => (
              <li key={i} style={{
                fontFamily: window.ATELIER_TYPE.display, fontSize: 13, lineHeight: 1.45,
                color: C.umber,
              }}>
                <span style={{
                  display: 'inline-block', marginRight: 8,
                  fontFamily: window.ATELIER_TYPE.ui, fontSize: 10, color: C.umberFaint,
                }}>{String(i + 1).padStart(2, '0')}</span>
                {f.label}
              </li>
            ))}
          </ul>
        </div>
      )}

      <div style={{
        padding: '12px 14px',
        background: C.bone, borderRadius: 10, border: `0.6px solid ${C.umberHair}`,
      }}>
        <div style={{
          fontFamily: window.ATELIER_TYPE.ui, fontSize: 9, letterSpacing: 3,
          textTransform: 'uppercase', color: C.umberFaint, marginBottom: 6,
        }}>{T.attackersLabel(entry.attackers.length)}</div>
        {entry.attackers.length === 0 ? (
          <div style={{ fontFamily: window.ATELIER_TYPE.display, fontSize: 13, color: C.umberSoft }}>None</div>
        ) : (
          <ul style={{ margin: 0, padding: 0, listStyle: 'none' }}>
            {entry.attackers.map((a, i) => (
              <li key={i} style={{ fontFamily: window.ATELIER_TYPE.display, fontSize: 13, color: C.umber }}>
                {a.kind} on {a.from}
              </li>
            ))}
          </ul>
        )}
      </div>

      <div style={{
        padding: '12px 14px',
        background: C.bone, borderRadius: 10, border: `0.6px solid ${C.umberHair}`,
      }}>
        <div style={{
          fontFamily: window.ATELIER_TYPE.ui, fontSize: 9, letterSpacing: 3,
          textTransform: 'uppercase', color: C.umberFaint, marginBottom: 6,
        }}>{T.defendersLabel(entry.defenders.length)}</div>
        {entry.defenders.length === 0 ? (
          <div style={{ fontFamily: window.ATELIER_TYPE.display, fontSize: 13, color: C.umberSoft }}>None</div>
        ) : (
          <ul style={{ margin: 0, padding: 0, listStyle: 'none' }}>
            {entry.defenders.map((d, i) => {
              const unreliable = (entry.unreliableDefenders || []).find((u) => u.square === d.from);
              return (
                <li key={i} style={{
                  fontFamily: window.ATELIER_TYPE.display, fontSize: 13,
                  color: unreliable ? C.terracotta || C.sienna : C.umber,
                  textDecoration: unreliable ? 'line-through' : 'none',
                }}>
                  {d.kind} on {d.from}
                  {unreliable && (
                    <span style={{ marginLeft: 8, fontSize: 11, color: C.umberSoft, textDecoration: 'none' }}>
                      ({unreliable.reason === 'pinned_to_king' ? `pinned by ${unreliable.pinnedBy}` : 'overworked'})
                    </span>
                  )}
                </li>
              );
            })}
          </ul>
        )}
      </div>
    </div>
  );
}

// ── Main screen ────────────────────────────────────────────────────────
function TargetsScreen({ palette, tweaks, setRoute }) {
  const C = palette;
  const T = window.COPY.targets;

  // Bind to current lesson; updates when lessonLoaded fires.
  const [lesson, setLesson] = useTS(window.LESSON || null);
  useTE(() => {
    const handler = (e) => setLesson(e.detail);
    window.addEventListener('lessonLoaded', handler);
    return () => window.removeEventListener('lessonLoaded', handler);
  }, []);

  const vuln = lesson && lesson.vulnerability;
  const sideToMove = lesson && lesson.meta && lesson.meta.sideToMove ? lesson.meta.sideToMove : 'white';
  const enemyColor = sideToMove === 'white' ? 'black' : 'white';

  const [mode, setMode] = useTS('browse'); // 'browse' | 'exercise'
  const [sideFilter, setSideFilter] = useTS('attack'); // 'attack' (enemy pieces) | 'defend' (own)
  const [focusSquare, setFocusSquare] = useTS(null);
  const [hoveredSquare, setHoveredSquare] = useTS(null);

  // Exercise state
  const [guess, setGuess] = useTS(null);
  const [revealed, setRevealed] = useTS(false);

  // Reset when lesson changes
  useTE(() => {
    setFocusSquare(null);
    setGuess(null);
    setRevealed(false);
  }, [lesson && lesson.id]);

  // The "current side of interest" depends on the toggle.
  const viewedColor = sideFilter === 'attack' ? enemyColor : sideToMove;

  const sortedEntries = useTM(() => {
    if (!vuln || !vuln.byPiece) return [];
    return Object.values(vuln.byPiece)
      .filter((e) => e.color === viewedColor)
      .sort((a, b) => b.score - a.score);
  }, [vuln, viewedColor]);

  // Empty state
  if (!lesson || !vuln) {
    return (
      <div style={{ flex: 1, height: '100%', overflow: 'auto', background: C.bone, padding: 40 }}>
        <window.Topbar palette={C} kicker={T.topbarKicker} title={T.topbarTitle} rightSlot={null} />
        <div style={{ padding: 40, textAlign: 'center', color: C.umberSoft, fontFamily: window.ATELIER_TYPE.display, fontSize: 16 }}>
          {T.emptyState}
        </div>
      </div>
    );
  }

  const topTarget = vuln.topTargetByColor ? vuln.topTargetByColor[viewedColor] : null;
  const focusedEntry = focusSquare ? vuln.byPiece[focusSquare] : null;

  // ── Exercise flow ────────────────────────────────────────────────────
  const handleSquareClick = (sq) => {
    if (mode === 'exercise' && !revealed) {
      // Only allow clicking on pieces of the viewed color.
      const entry = vuln.byPiece[sq];
      if (!entry || entry.color !== viewedColor) return;
      setGuess(sq);
      setRevealed(true);
      setFocusSquare(sq);
    } else {
      setFocusSquare(sq);
    }
  };

  // Exercise feedback line
  const exerciseFeedback = (() => {
    if (mode !== 'exercise' || !revealed) return null;
    const guessEntry = guess && vuln.byPiece[guess];
    if (!topTarget) return T.exerciseEmpty;
    if (guess === topTarget) return T.exerciseCorrect(topTarget);
    if (guessEntry && (guessEntry.classification === 'vulnerable' || guessEntry.classification === 'under_tension')) {
      return T.exerciseClose(guess, topTarget);
    }
    return T.exerciseWrong(guess, topTarget);
  })();

  const exerciseFeedbackClass = (() => {
    if (mode !== 'exercise' || !revealed) return null;
    if (guess === topTarget) return 'celadon';
    return 'sienna';
  })();

  // Build a filtered byPiece map for the overlay (just the viewed color)
  const overlayByPiece = useTM(() => {
    const out = {};
    if (!vuln || !vuln.byPiece) return out;
    // Always show all pieces (otherwise the board would be missing pieces)
    // but only show overlays for the viewed color.
    for (const [sq, e] of Object.entries(vuln.byPiece)) {
      out[sq] = (mode === 'exercise' && !revealed)
        ? { ...e, classification: 'stable' }  // hide overlays until revealed
        : e.color === viewedColor
        ? e
        : { ...e, classification: 'stable' };
    }
    return out;
  }, [vuln, viewedColor, mode, revealed]);

  // ── Render ───────────────────────────────────────────────────────────
  return (
    <div style={{
      flex: 1, height: '100%', overflow: 'hidden', display: 'grid',
      gridTemplateColumns: '340px minmax(0, 1fr) 340px',
      background: C.bone,
    }}>
      {/* Left: ranking list */}
      <aside style={{
        padding: '24px 22px', borderRight: `0.6px solid ${C.umberHair}`,
        background: C.bone, overflow: 'auto',
        display: 'flex', flexDirection: 'column', gap: 16,
      }}>
        <window.SectionHeading palette={C} kicker={T.listKicker} title={T.listTitle} small />

        {/* Mode tabs */}
        <div style={{ display: 'flex', gap: 6 }}>
          {['browse', 'exercise'].map((m) => {
            const active = m === mode;
            return (
              <button key={m} onClick={() => { setMode(m); setRevealed(false); setGuess(null); setFocusSquare(null); }}
                style={{
                  appearance: 'none', cursor: 'pointer',
                  padding: '7px 14px', borderRadius: 99,
                  border: `0.6px solid ${active ? C.umber : C.umberHair}`,
                  background: active ? C.cream : 'transparent',
                  color: active ? C.umber : C.umberSoft,
                  fontFamily: window.ATELIER_TYPE.ui,
                  fontSize: 10, letterSpacing: 1.5, textTransform: 'uppercase',
                }}>
                {m === 'browse' ? T.modeBrowse : T.modeExercise}
              </button>
            );
          })}
        </div>

        {/* Side toggle */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
          <div style={{
            fontFamily: window.ATELIER_TYPE.ui, fontSize: 9, letterSpacing: 3,
            textTransform: 'uppercase', color: C.umberFaint,
          }}>{T.sideToggleLabel}</div>
          <div style={{ display: 'flex', gap: 6 }}>
            {['attack', 'defend'].map((s) => {
              const active = s === sideFilter;
              return (
                <button key={s} onClick={() => { setSideFilter(s); setFocusSquare(null); setRevealed(false); setGuess(null); }}
                  style={{
                    appearance: 'none', cursor: 'pointer', flex: 1,
                    padding: '7px 10px', borderRadius: 8,
                    border: `0.6px solid ${active ? C.umber : C.umberHair}`,
                    background: active ? C.cream : 'transparent',
                    color: active ? C.umber : C.umberSoft,
                    fontFamily: window.ATELIER_TYPE.ui,
                    fontSize: 10, letterSpacing: 1, textTransform: 'uppercase',
                  }}>
                  {T.sideLabels[s]}
                </button>
              );
            })}
          </div>
        </div>

        {/* Ranking list (browse mode only) */}
        {mode === 'browse' && (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
            {sortedEntries.length === 0 && (
              <div style={{ fontFamily: window.ATELIER_TYPE.display, fontSize: 13, color: C.umberSoft }}>
                No pieces on this side.
              </div>
            )}
            {sortedEntries.map((e) => {
              const active = focusSquare === e.square;
              const tone = VULN_COLOR_KEY[e.classification];
              return (
                <button key={e.square}
                  onClick={() => setFocusSquare(e.square)}
                  onMouseEnter={() => setHoveredSquare(e.square)}
                  onMouseLeave={() => setHoveredSquare(null)}
                  style={{
                    appearance: 'none', textAlign: 'left', cursor: 'pointer',
                    background: active ? C.cream : 'transparent',
                    border: `0.6px solid ${active ? (tone ? C[tone] : C.umber) : C.umberHair}`,
                    borderRadius: 10, padding: '10px 12px',
                    display: 'flex', alignItems: 'center', gap: 10,
                  }}>
                  <span style={{
                    fontFamily: '"Noto Sans Symbols 2","Segoe UI Symbol",sans-serif',
                    fontSize: 20, color: C.umber,
                  }}>{PIECE_TO_GLYPH[e.piece]}</span>
                  <span style={{ flex: 1 }}>
                    <span style={{
                      display: 'block',
                      fontFamily: window.ATELIER_TYPE.display, fontSize: 14, color: C.umber,
                    }}>{e.square.toUpperCase()}</span>
                    <span style={{
                      display: 'block',
                      fontFamily: window.ATELIER_TYPE.ui, fontSize: 9, letterSpacing: 1.5,
                      textTransform: 'uppercase', color: tone ? C[tone] : C.umberFaint,
                    }}>{T.classLabels[e.classification]}</span>
                  </span>
                  <span style={{
                    fontFamily: window.ATELIER_TYPE.display, fontSize: 16,
                    color: tone ? C[tone] : C.umberSoft,
                  }}>{e.score}</span>
                </button>
              );
            })}
          </div>
        )}

        {/* Exercise prompt */}
        {mode === 'exercise' && (
          <div style={{
            padding: '14px 16px',
            background: C.cream, borderRadius: 10,
            border: `0.6px solid ${C.umberHair}`,
            display: 'flex', flexDirection: 'column', gap: 8,
          }}>
            <div style={{
              fontFamily: window.ATELIER_TYPE.ui, fontSize: 9, letterSpacing: 3,
              textTransform: 'uppercase', color: C.umberFaint,
            }}>{T.exerciseKicker}</div>
            <div style={{
              fontFamily: window.ATELIER_TYPE.display, fontStyle: 'italic',
              fontSize: 18, color: C.umber, lineHeight: 1.25,
            }}>{T.exerciseTitle}</div>
            <div style={{
              fontFamily: window.ATELIER_TYPE.display, fontSize: 13, color: C.umberSoft,
            }}>{T.exerciseSubtitle}</div>
          </div>
        )}

        {/* Exercise feedback */}
        {mode === 'exercise' && exerciseFeedback && (
          <div style={{
            padding: '14px 16px',
            background: exerciseFeedbackClass === 'celadon'
              ? window.withAlpha(C.celadon, 0.15)
              : window.withAlpha(C.sienna, 0.1),
            border: `0.6px solid ${exerciseFeedbackClass === 'celadon' ? C.celadon : C.sienna}`,
            borderRadius: 10,
            fontFamily: window.ATELIER_TYPE.display, fontSize: 14, lineHeight: 1.5,
            color: C.umber,
          }}>{exerciseFeedback}</div>
        )}

        {/* How-to */}
        <div style={{
          padding: '14px 16px',
          background: C.cream, borderRadius: 10,
          border: `0.6px dashed ${C.umberHair}`,
        }}>
          <div style={{
            fontFamily: window.ATELIER_TYPE.ui, fontSize: 9, letterSpacing: 3,
            textTransform: 'uppercase', color: C.umberFaint, marginBottom: 8,
          }}>{T.howToReadTitle}</div>
          <p style={{ margin: 0, fontFamily: window.ATELIER_TYPE.display, fontSize: 12, lineHeight: 1.5, color: C.umberSoft }}>
            {T.howToReadBody}
          </p>
        </div>
      </aside>

      {/* Middle: board */}
      <div style={{ display: 'flex', flexDirection: 'column' }}>
        <window.Topbar palette={C} kicker={T.topbarKicker} title={T.topbarTitle} rightSlot={null} />
        <div style={{
          flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center',
          padding: 24,
          background: `radial-gradient(120% 80% at 50% -10%, ${window.withAlpha(C.brassLight, 0.35)}, transparent 60%)`,
        }}>
          <div style={{
            background: C.boneDeep, padding: 14, borderRadius: 8,
            boxShadow: '0 30px 50px -28px rgba(42,34,27,0.45)',
          }}>
            <VulnerabilityOverlay
              palette={C}
              byPiece={overlayByPiece}
              focusSquare={focusSquare}
              hoveredSquare={hoveredSquare}
              side={sideFilter}
              onSquareClick={handleSquareClick}
              size={520}
            />
          </div>
        </div>
      </div>

      {/* Right: factor breakdown */}
      <aside style={{
        padding: '24px 22px', borderLeft: `0.6px solid ${C.umberHair}`,
        background: C.cream, overflow: 'auto',
      }}>
        <FactorPanel palette={C} entry={focusedEntry} />
      </aside>
    </div>
  );
}

Object.assign(window, { TargetsScreen });
