import chess

from chess_detect import ChessDetector
from chess_detect.context import MoveContext
from chess_detect.detectors.tactics.discovered_check import DiscoveredCheckDetector


class TestDiscoveredCheckDetector:
    """Тесты для детектора вскрытого шаха."""

    def test_discovered_check_with_capture(self):
        """Вскрытый шах со взятием — да."""
        # Конь на d4 блокирует ладью d1 -> d8 (шах)
        # Конь берёт пешку на e6, открывая ладью
        board = chess.Board("3k4/8/4p3/8/3N4/8/8/3RK3 w - - 0 1")
        move = chess.Move.from_uci("d4e6")  # Nxe6+ вскрытый шах со взятием

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

        assert detector.detect(ctx) is True

    def test_discovered_check_attacks_more_valuable(self):
        """Вскрытый шах с атакой на более ценную фигуру — да."""
        # Конь уходит и открывает ладью для шаха
        # Конь нападает на ферзя
        board = chess.Board("3k4/8/8/5q2/3N4/8/8/3RK3 w - - 0 1")
        move = chess.Move.from_uci("d4e6")  # Ne6+ нападает на ферзя f5? Нет

        # Конь с e6 атакует: c5, c7, d4, d8, f4, f8, g5, g7
        # Не атакует f5

        # Нужна позиция где конь атакует ферзя
        # Конь на d4 идёт на f5, атакуя ферзя на g7
        board = chess.Board("3k4/6q1/8/8/3N4/8/8/3RK3 w - - 0 1")
        move = chess.Move.from_uci("d4f5")  # Nf5+ атакует g7 (ферзь)

        # Но d4 не блокирует d1-d8... ладья уже шахует?
        # Нет, d4 блокирует. После Nf5 ладья шахует.

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

        assert detector.detect(ctx) is True

    def test_discovered_check_attacks_hanging_piece(self):
        """Вскрытый шах с атакой на висящую фигуру — да."""
        # Конь уходит, открывает шах, нападает на незащищённого слона
        board = chess.Board("3k4/8/5b2/8/3N4/8/8/3RK3 w - - 0 1")
        move = chess.Move.from_uci("d4e6")  # Ne6+ атакует слона? Нет

        # Конь с e6 атакует: c5, c7, d4, d8, f4, f8, g5, g7
        # f6 — слон, не атакован с e6

        # Позиция: конь идёт на g5, атакуя слона на f7
        board = chess.Board("3k4/5b2/8/8/3N4/8/8/3RK3 w - - 0 1")
        move = chess.Move.from_uci("d4f5")  # Nf5 атакует f7? Нет

        # Конь с f5 атакует: d4, d6, e3, e7, g3, g7, h4, h6
        # Не атакует f7

        # Конь на d4 идёт на e6, атакуя слона на g7
        board = chess.Board("3k4/6b1/8/8/3N4/8/8/3RK3 w - - 0 1")
        move = chess.Move.from_uci("d4e6")  # Ne6+ атакует g7

        # Конь с e6 атакует: c5, c7, d4, d8, f4, f8, g5, g7
        # g7 — слон, висит!

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

        assert detector.detect(ctx) is True

    def test_discovered_check_attacks_defended_cheap_piece_not(self):
        """Вскрытый шах с атакой на защищённую дешёвую фигуру — нет."""
        # Конь уходит, шах, но нападает на защищённую пешку
        board = chess.Board("3k4/1p6/p7/8/3N4/8/8/3RK3 w - - 0 1")
        # Пешка a6 защищена пешкой b7
        move = chess.Move.from_uci("d4c6")  # Nc6+ атакует?

        # Конь с c6 атакует: a5, a7, b4, b8, d4, d8, e5, e7
        # a7 — пешка? Нет, пешка на a6. Не атакует a6.

        # Новая позиция: конь атакует защищённую пешку
        board = chess.Board("3k4/2p5/8/8/3N4/8/8/3RK3 w - - 0 1")
        # Добавим защитника пешке c7
        board = chess.Board("3k4/1pp5/8/8/3N4/8/8/3RK3 w - - 0 1")
        # Пешка c7 защищена пешкой b7
        move = chess.Move.from_uci("d4e6")  # Ne6+ атакует c7

        # Конь с e6 атакует: c5, c7, d4, d8, f4, f8, g5, g7
        # c7 — пешка, защищена b7

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

        # Пешка защищена и дешевле коня — не выгодно
        assert detector.detect(ctx) is False

    def test_discovered_check_to_nowhere_not(self):
        """Вскрытый шах без полезной атаки — нет."""
        # Конь уходит на пустое поле, ничего не атакует
        board = chess.Board("3k4/8/8/8/3N4/8/8/3RK3 w - - 0 1")
        move = chess.Move.from_uci("d4f3")  # Nf3+ (просто уходит)

        # Конь с f3 атакует: d2, d4, e1, e5, g1, g5, h2, h4
        # e1 — свой король, остальное пусто

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

        assert detector.detect(ctx) is False

    def test_regular_check_not_discovered(self):
        """Обычный шах (не вскрытый) — нет."""
        # Конь сам даёт шах, не вскрытый
        board = chess.Board("4k3/8/8/8/8/5N2/8/4K3 w - - 0 1")
        move = chess.Move.from_uci("f3g5")  # Ng5+ обычный шах

        # Конь с g5 атакует: e4, e6, f3, f7, h3, h7
        # e6 — путь к королю? Нет, король на e8
        # Это не шах вообще

        # Правильная позиция для обычного шаха
        board = chess.Board("4k3/8/5N2/8/8/8/8/4K3 w - - 0 1")
        move = chess.Move.from_uci("f6g8")  # Ng8+

        # Конь с g8 атакует: e7, f6, h6
        # e7 — рядом с королём e8? Конь не шахует с g8
        # Конь шахует если атакует короля

        # Конь на d6 шахует короля на e8
        board = chess.Board("4k3/8/3N4/8/8/8/8/4K3 w - - 0 1")
        # Конь уже шахует, это не ход

        # Конь с e6 на d8 или f8? Там нельзя
        # Конь на c5 идёт на d7+
        board = chess.Board("4k3/8/8/2N5/8/8/8/4K3 w - - 0 1")
        move = chess.Move.from_uci("c5d7")  # Nd7+ обычный шах

        # Конь с d7 атакует: b6, b8, c5, e5, f6, f8
        # Не атакует e8... Конь d7 не шахует e8

        # Правильно: конь идёт на поле откуда шахует
        board = chess.Board("4k3/8/8/8/2N5/8/8/4K3 w - - 0 1")
        move = chess.Move.from_uci("c4d6")  # Nd6+ шах

        # Конь с d6 атакует: b5, b7, c4, c8, e4, e8, f5, f7
        # e8 — король! Обычный шах, не вскрытый

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

        assert detector.detect(ctx) is False


class TestDiscoveredCheckIntegration:
    """Интеграционные тесты вскрытого шаха."""

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

        # Вскрытый шах со взятием
        pgn = """[FEN "3k4/8/4p3/8/3N4/8/8/3RK3 w - - 0 1"]

1. Nxe6+"""

        result = detector.analyze(pgn)
        assert "Вскрытый шах" in result

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

        pgn = """[FEN "3k4/8/4p3/8/3N4/8/8/3RK3 w - - 0 1"]

1. Nxe6+"""

        result = detector.analyze(pgn)
        assert "Discovered Check" in result
