"""Textual widget that renders a chess board with Rich styling."""

from __future__ import annotations

import chess
from rich.style import Style
from rich.text import Text
from textual.reactive import reactive
from textual.widget import Widget

PIECE_SYMBOLS = {
    (chess.PAWN, chess.WHITE): "\u265f",
    (chess.KNIGHT, chess.WHITE): "\u265e",
    (chess.BISHOP, chess.WHITE): "\u265d",
    (chess.ROOK, chess.WHITE): "\u265c",
    (chess.QUEEN, chess.WHITE): "\u265b",
    (chess.KING, chess.WHITE): "\u265a",
    (chess.PAWN, chess.BLACK): "\u265f",
    (chess.KNIGHT, chess.BLACK): "\u265e",
    (chess.BISHOP, chess.BLACK): "\u265d",
    (chess.ROOK, chess.BLACK): "\u265c",
    (chess.QUEEN, chess.BLACK): "\u265b",
    (chess.KING, chess.BLACK): "\u265a",
}

LIGHT_SQUARE = Style(bgcolor="rgb(210,180,140)")
DARK_SQUARE = Style(bgcolor="rgb(140,100,70)")
HIGHLIGHT_LIGHT = Style(bgcolor="rgb(240,230,150)")
HIGHLIGHT_DARK = Style(bgcolor="rgb(200,190,110)")
WHITE_PIECE = Style(color="white", bold=True)
BLACK_PIECE = Style(color="rgb(40,40,40)")

_PIECE_VALUE_ORDER: list[chess.PieceType] = [
    chess.QUEEN, chess.ROOK, chess.BISHOP, chess.KNIGHT, chess.PAWN,
]

_STARTING_COUNTS: dict[chess.PieceType, int] = {
    chess.PAWN: 8, chess.KNIGHT: 2, chess.BISHOP: 2,
    chess.ROOK: 2, chess.QUEEN: 1, chess.KING: 1,
}


def compute_captured(board: chess.Board) -> tuple[list[chess.PieceType], list[chess.PieceType]]:
    """Return (white_captured, black_captured) piece-type lists."""
    white_captured: list[chess.PieceType] = []
    black_captured: list[chess.PieceType] = []
    for pt in _PIECE_VALUE_ORDER:
        starting = _STARTING_COUNTS[pt]
        white_captured.extend([pt] * max(0, starting - len(board.pieces(pt, chess.WHITE))))
        black_captured.extend([pt] * max(0, starting - len(board.pieces(pt, chess.BLACK))))
    return white_captured, black_captured


class BoardWidget(Widget):
    """Renders a chess board with Unicode pieces — 3 chars wide per cell."""

    # 3 chars/cell × 8 + 4 gutter = 28 wide, 1 line/rank × 8 + 2 labels = 10
    DEFAULT_CSS = """
    BoardWidget {
        width: 28;
        height: 10;
        overflow: hidden hidden;
    }
    """

    board_fen: reactive[str] = reactive(chess.STARTING_FEN)
    perspective: reactive[bool] = reactive(True)
    highlight_from: reactive[int] = reactive(-1)
    highlight_to: reactive[int] = reactive(-1)

    def render(self) -> Text:
        board = chess.Board(self.board_fen)
        highlighted = {self.highlight_from, self.highlight_to}

        if self.perspective:
            ranks = range(7, -1, -1)
            files = range(8)
        else:
            ranks = range(8)
            files = range(7, -1, -1)

        file_labels = [chess.FILE_NAMES[f] for f in files]
        result = Text()

        # Top file labels.
        result.append("  ")
        for label in file_labels:
            result.append(f" {label} ")
        result.append("\n")

        for rank in ranks:
            rank_label = str(rank + 1)
            result.append(f"{rank_label} ")

            for file in files:
                square = chess.square(file, rank)
                is_light = (file + rank) % 2 == 1
                if square in highlighted and square != -1:
                    bg = HIGHLIGHT_LIGHT if is_light else HIGHLIGHT_DARK
                else:
                    bg = LIGHT_SQUARE if is_light else DARK_SQUARE

                piece = board.piece_at(square)
                if piece is not None:
                    symbol = PIECE_SYMBOLS[(piece.piece_type, piece.color)]
                    ps = WHITE_PIECE if piece.color == chess.WHITE else BLACK_PIECE
                    result.append(f" {symbol} ", style=ps + bg)
                else:
                    result.append("   ", style=bg)

            result.append(f" {rank_label}\n")

        result.append("  ")
        for label in file_labels:
            result.append(f" {label} ")

        return result
