import chess

from ..base import BaseDetector
from ...context import MoveContext
from ...i18n import format_piece_square
from ...utils import is_piece_vulnerable


class HangingCaptureDetector(BaseDetector):
    """
    Детектор взятия висящей фигуры.

    Фигура висит, если:
    - Атакована и не защищена, ИЛИ
    - Может быть взята более дешёвой фигурой

    Детектор срабатывает, когда наш ход БЕРЁТ висящую фигуру.
    Это эксплуатация ошибки противника.
    """

    key = "hanging_capture"

    def __init__(self):
        self._captured_piece: chess.Piece | None = None
        self._captured_sq: int | None = None

    def detect(self, ctx: MoveContext) -> bool:
        """
        Проверяет, взяли ли мы висящую фигуру.
        """
        self._captured_piece = None
        self._captured_sq = None

        # Должно быть взятие
        if not ctx.is_capture:
            return False

        captured = ctx.captured_piece

        # Пешки и короли не считаются "висящими" в тактическом смысле
        if captured.piece_type in {chess.PAWN, chess.KING}:
            return False

        # Отыгрыш (рекапча) — не тактика
        # Если противник только что взял на этом поле, мы просто бьём обратно
        if self._is_recapture(ctx):
            return False

        # Проверяем, висела ли фигура ДО нашего хода
        if not is_piece_vulnerable(ctx.board_before, ctx.move.to_square):
            return False

        self._captured_piece = captured
        self._captured_sq = ctx.move.to_square
        return True

    def format_details(self, ctx: MoveContext, lang: str) -> str:
        if self._captured_piece is None or self._captured_sq is None:
            return ""
        return format_piece_square(self._captured_piece, self._captured_sq, lang)

    def get_arrows(self, ctx: MoveContext) -> list[tuple[int, int]]:
        if self._captured_sq is None:
            return []
        return [(self._captured_sq, self._captured_sq)]

    def _is_recapture(self, ctx: MoveContext) -> bool:
        """Проверяет, является ли ход отыгрышем на том же поле."""
        move_stack = ctx.board_before.move_stack
        if not move_stack:
            return False

        prev_move = move_stack[-1]
        if prev_move.to_square != ctx.move.to_square:
            return False

        # Предыдущий ход тоже должен быть взятием (не просто перемещением)
        ctx.board_before.pop()
        was_capture = ctx.board_before.is_capture(prev_move)
        ctx.board_before.push(prev_move)
        return was_capture
