from __future__ import annotations

from pathlib import Path
from typing import TYPE_CHECKING

import chess

from textual.app import App, ComposeResult
from textual.binding import Binding

if TYPE_CHECKING:
    pass


class ChessApp(App):
    """Chess CLI — Textual TUI application."""

    CSS_PATH = Path("styles/app.tcss")
    TITLE = "Chess CLI"

    BINDINGS = [
        Binding("ctrl+c", "quit", "Quit", show=False),
    ]

    def __init__(
        self,
        start_screen: str = "menu",
        color: chess.Color | None = None,
        difficulty: str = "intermediate",
        pgn_file: str | None = None,
        threads: int = 1,
        hash_mb: int = 16,
        move_time: float | None = None,
        lichess: bool = False,
        lichess_bot: str | None = None,
        lichess_time: str = "10+0",
    ) -> None:
        super().__init__()
        self.start_screen = start_screen
        self.initial_color = color
        self.initial_difficulty = difficulty
        self.pgn_file = pgn_file
        self.initial_threads = threads
        self.initial_hash_mb = hash_mb
        self.initial_move_time = move_time
        self.lichess = lichess
        self.lichess_bot_name = lichess_bot
        self.lichess_time = lichess_time

    def on_mount(self) -> None:
        if self.start_screen == "game" and self.initial_color is not None:
            from chess_cli.tui.screens.game import GameScreen

            if self.lichess:
                self._start_lichess_game()
            else:
                self.push_screen(GameScreen(
                    color=self.initial_color,
                    difficulty=self.initial_difficulty,
                    threads=self.initial_threads,
                    hash_mb=self.initial_hash_mb,
                    move_time=self.initial_move_time,
                ))
        elif self.start_screen == "analyze" and self.pgn_file:
            self._start_analyze()
        else:
            from chess_cli.tui.screens.menu import MenuScreen
            self.push_screen(MenuScreen())

    def _start_lichess_game(self) -> None:
        """Start a Lichess game from CLI --lichess flag."""
        from chess_cli.settings import load_settings
        from chess_cli.lichess import LichessClient, BotInfo
        from chess_cli.tui.screens.game import GameScreen
        from chess_cli.tui.screens.bot_select import BotSelectScreen

        settings = load_settings()
        if not settings.lichess_api_token:
            self.notify(
                "No Lichess API token set. Run: mike-chess token <token>",
                severity="error",
            )
            from chess_cli.tui.screens.menu import MenuScreen
            self.push_screen(MenuScreen())
            return

        client = LichessClient(token=settings.lichess_api_token)

        # Parse time control string like "10+0"
        parts = self.lichess_time.split("+")
        try:
            clock_limit = int(parts[0]) * 60
            clock_increment = int(parts[1]) if len(parts) > 1 else 0
        except (ValueError, IndexError):
            clock_limit, clock_increment = 600, 0

        if self.lichess_bot_name:
            # Direct challenge — skip bot selection
            bot = BotInfo(
                username=self.lichess_bot_name,
                rating=0,
                title="BOT",
                online=True,
                description="",
            )
            self.push_screen(GameScreen(
                color=self.initial_color,
                lichess_client=client,
                lichess_bot=bot,
                clock_limit=clock_limit,
                clock_increment=clock_increment,
            ))
        else:
            # Show bot selection
            def on_bot_selected(bot_info) -> None:
                if bot_info is None:
                    client.close()
                    from chess_cli.tui.screens.menu import MenuScreen
                    self.push_screen(MenuScreen())
                    return
                self.push_screen(GameScreen(
                    color=self.initial_color,
                    lichess_client=client,
                    lichess_bot=bot_info,
                    clock_limit=clock_limit,
                    clock_increment=clock_increment,
                ))

            self.push_screen(BotSelectScreen(client), callback=on_bot_selected)

    def _start_analyze(self) -> None:
        """Start analysis of a PGN file."""
        import chess.pgn as pgn_mod
        from chess_cli.engine import EnginePlayer, EngineNotFoundError
        from chess_cli.tui.screens.analysis import AnalysisScreen

        try:
            with open(self.pgn_file) as f:
                pgn_game = pgn_mod.read_game(f)
        except FileNotFoundError:
            self.notify(f"File not found: {self.pgn_file}", severity="error")
            from chess_cli.tui.screens.menu import MenuScreen
            self.push_screen(MenuScreen())
            return
        except Exception as e:
            self.notify(f"Error reading PGN: {e}", severity="error")
            from chess_cli.tui.screens.menu import MenuScreen
            self.push_screen(MenuScreen())
            return

        if pgn_game is None:
            self.notify("No game found in PGN file.", severity="error")
            from chess_cli.tui.screens.menu import MenuScreen
            self.push_screen(MenuScreen())
            return

        try:
            engine = EnginePlayer(difficulty="maximum")
        except EngineNotFoundError as e:
            self.notify(str(e), severity="error")
            from chess_cli.tui.screens.menu import MenuScreen
            self.push_screen(MenuScreen())
            return

        self.push_screen(AnalysisScreen(pgn_game=pgn_game, engine=engine))
