import chess

from chess_detect import ChessDetector
from chess_detect.context import MoveContext
from chess_detect.detectors.tactics.hanging_capture import HangingCaptureDetector


class TestHangingCaptureDetector:
    """Тесты для детектора взятия висящей фигуры."""

    def test_capture_undefended_knight(self):
        """Взятие незащищённого коня."""
        # Чёрный конь на e5 не защищён, белая ладья берёт
        board = chess.Board("4k3/8/8/4n3/8/8/8/4K2R w - - 0 1")
        move = chess.Move.from_uci("h1e1")  # Re1? Не берёт коня

        # Ладья e5
        board = chess.Board("4k3/8/8/4n3/8/8/8/R3K3 w - - 0 1")
        move = chess.Move.from_uci("a1e1")  # Re1 не берёт

        # Ладья на a5, ход Rxe5
        board = chess.Board("4k3/8/8/R3n3/8/8/8/4K3 w - - 0 1")
        move = chess.Move.from_uci("a5e5")  # Rxe5 — берёт незащищённого коня

        ctx = MoveContext(board, move)
        detector = HangingCaptureDetector()

        assert detector.detect(ctx) is True

    def test_capture_defended_piece_by_lower_value(self):
        """Взятие защищённой фигуры более дешёвой."""
        # Чёрный ферзь на d5, защищён конём c7, но пешка e4 может взять
        board = chess.Board("4k3/2n5/8/3q4/4P3/8/8/4K3 w - - 0 1")
        move = chess.Move.from_uci("e4d5")  # exd5 — пешка берёт ферзя

        ctx = MoveContext(board, move)
        detector = HangingCaptureDetector()

        # Пешка (1) < Ферзь (9) — выгодное взятие висящей фигуры
        assert detector.detect(ctx) is True

    def test_capture_defended_piece_same_value_not_hanging(self):
        """Взятие защищённой фигуры той же ценности — не висящая."""
        # Чёрный конь на e5, защищён пешкой d6, белый конь берёт
        board = chess.Board("4k3/8/3p4/4n3/8/5N2/8/4K3 w - - 0 1")
        move = chess.Move.from_uci("f3e5")  # Nxe5 — конь берёт коня

        ctx = MoveContext(board, move)
        detector = HangingCaptureDetector()

        # Конь (3) = Конь (3), защищён — это размен, не висящая фигура
        assert detector.detect(ctx) is False

    def test_capture_pawn_not_hanging(self):
        """Взятие пешки не считается взятием висящей фигуры."""
        # Чёрная пешка на e5, не защищена
        board = chess.Board("4k3/8/8/4p3/8/5N2/8/4K3 w - - 0 1")
        move = chess.Move.from_uci("f3e5")  # Nxe5 — конь берёт пешку

        ctx = MoveContext(board, move)
        detector = HangingCaptureDetector()

        # Пешки не считаются "висящими" в тактическом смысле
        assert detector.detect(ctx) is False

    def test_no_capture_no_detection(self):
        """Без взятия — нет детекции."""
        board = chess.Board("4k3/8/8/4n3/8/8/8/R3K3 w - - 0 1")
        move = chess.Move.from_uci("a1a5")  # Ra5 — не берёт

        ctx = MoveContext(board, move)
        detector = HangingCaptureDetector()

        assert detector.detect(ctx) is False

    def test_recapture_not_hanging(self):
        """Отыгрыш — не висящая фигура. Конь съел коня, пешка бьёт обратно."""
        # Симулируем: белый конь взял чёрного коня на e5, пешка d6 бьёт обратно
        board = chess.Board("4k3/8/3p4/4n3/8/5N2/8/4K3 w - - 0 1")
        board.push(chess.Move.from_uci("f3e5"))  # Nxe5

        # Теперь ход чёрных — пешка бьёт обратно
        move = chess.Move.from_uci("d6e5")  # dxe5 — отыгрыш

        ctx = MoveContext(board, move)
        detector = HangingCaptureDetector()

        # Это отыгрыш (предыдущий ход был на то же поле) — не тактика
        assert detector.detect(ctx) is False


    def test_hanging_even_if_capturer_vulnerable(self):
        """Взятие висящей — тактика даже если берущую отберут (выигрыш материала)."""
        # Nxc1: конь берёт висящую ладью, конь на c1 тоже висит (Rxc1)
        # Но это всё равно выигрыш материала (5-3=+2)
        board = chess.Board("2r4r/1pP1kpp1/3p4/3Pp3/4P3/3P1NP1/4n1KP/2R2R2 b - - 0 31")
        move = chess.Move.from_uci("e2c1")  # Nxc1

        ctx = MoveContext(board, move)
        detector = HangingCaptureDetector()

        assert detector.detect(ctx) is True


class TestHangingCaptureIntegration:
    """Интеграционные тесты."""

    def test_analyze_detects_hanging_ru(self):
        """Детектор находит взятие висящей на русском."""
        detector = ChessDetector(lang="ru")

        pgn = """[FEN "4k3/8/8/R3n3/8/8/8/4K3 w - - 0 1"]

1. Rxe5"""

        result = detector.analyze(pgn)
        assert "Взятие висящей фигуры" in result

    def test_analyze_detects_hanging_en(self):
        """Детектор находит взятие висящей на английском."""
        detector = ChessDetector(lang="en")

        pgn = """[FEN "4k3/8/8/R3n3/8/8/8/4K3 w - - 0 1"]

1. Rxe5"""

        result = detector.analyze(pgn)
        assert "Hanging Capture" in result
