"""Tests for the Textual TUI application using the built-in async test pilot."""

from __future__ import annotations

from textual.widgets import Button

from cde_onboard.app import OnboardApp
from cde_onboard.screens.lesson import LessonScreen
from cde_onboard.screens.lesson_menu import LessonMenuScreen
from cde_onboard.screens.welcome import WelcomeScreen


class TestAppLaunch:
    """Tests for initial application launch."""

    async def test_app_launches(self) -> None:
        """The application starts without errors."""
        async with OnboardApp().run_test() as pilot:
            assert pilot.app is not None
            assert pilot.app.title == "ONA Onboarding"

    async def test_app_shows_welcome_screen(self) -> None:
        """The app pushes the WelcomeScreen on mount by default."""
        async with OnboardApp().run_test() as pilot:
            assert isinstance(pilot.app.screen, WelcomeScreen)

    async def test_app_has_quit_binding(self) -> None:
        """The app has a 'q' key binding for quit."""
        async with OnboardApp().run_test() as pilot:
            bindings = [b.key for b in pilot.app.BINDINGS]
            assert "q" in bindings

    async def test_app_has_escape_binding(self) -> None:
        """The app has an 'escape' key binding for back."""
        async with OnboardApp().run_test() as pilot:
            bindings = [b.key for b in pilot.app.BINDINGS]
            assert "escape" in bindings


class TestWelcomeScreen:
    """Tests for the WelcomeScreen."""

    async def test_welcome_has_start_button(self) -> None:
        """The welcome screen contains a Start button."""
        async with OnboardApp().run_test() as pilot:
            button = pilot.app.query_one("#btn-start")
            assert button is not None

    async def test_welcome_has_choose_button(self) -> None:
        """The welcome screen contains a Choose a Lesson button."""
        async with OnboardApp().run_test() as pilot:
            button = pilot.app.query_one("#btn-choose")
            assert button is not None

    async def test_welcome_has_quit_button(self) -> None:
        """The welcome screen contains a Quit button."""
        async with OnboardApp().run_test() as pilot:
            button = pilot.app.query_one("#btn-quit")
            assert button is not None

    async def test_welcome_title_text(self) -> None:
        """The welcome screen displays the ONA Onboarding title."""
        async with OnboardApp().run_test() as pilot:
            title = pilot.app.query_one("#welcome-title")
            assert title is not None

    async def test_start_button_navigates_to_lesson(self) -> None:
        """Clicking Start pushes a LessonScreen for lesson 1."""
        async with OnboardApp().run_test() as pilot:
            # Programmatically press the button to ensure the event fires
            btn = pilot.app.query_one("#btn-start", Button)
            btn.press()
            await pilot.pause()
            assert isinstance(pilot.app.screen, LessonScreen)

    async def test_choose_button_navigates_to_menu(self) -> None:
        """Clicking Choose a Lesson pushes the LessonMenuScreen."""
        async with OnboardApp().run_test() as pilot:
            btn = pilot.app.query_one("#btn-choose", Button)
            btn.press()
            await pilot.pause()
            assert isinstance(pilot.app.screen, LessonMenuScreen)


class TestLessonScreen:
    """Tests for the LessonScreen."""

    async def test_lesson_screen_via_start_lesson(self) -> None:
        """Launching the app with start_lesson goes directly to that lesson."""
        async with OnboardApp(start_lesson=1).run_test() as pilot:
            assert isinstance(pilot.app.screen, LessonScreen)

    async def test_lesson_screen_has_scaffold_button(self) -> None:
        """The lesson screen has a Scaffold & Complete button."""
        async with OnboardApp(start_lesson=1).run_test() as pilot:
            button = pilot.app.query_one("#btn-scaffold")
            assert button is not None

    async def test_lesson_screen_has_header(self) -> None:
        """The lesson screen displays a lesson header."""
        async with OnboardApp(start_lesson=1).run_test() as pilot:
            header = pilot.app.query_one("#lesson-header")
            assert header is not None

    async def test_lesson_1_has_next_button(self) -> None:
        """Lesson 1 (not the last) has a Next Lesson button."""
        async with OnboardApp(start_lesson=1).run_test() as pilot:
            button = pilot.app.query_one("#btn-next")
            assert button is not None

    async def test_lesson_6_has_no_next_button(self) -> None:
        """Lesson 6 (the last) does not have a Next Lesson button."""
        async with OnboardApp(start_lesson=6).run_test() as pilot:
            results = pilot.app.query("#btn-next")
            assert len(results) == 0


class TestNavigation:
    """Tests for screen navigation flows."""

    async def test_escape_pops_screen(self) -> None:
        """Pressing escape from a pushed screen goes back."""
        async with OnboardApp().run_test() as pilot:
            # Navigate to lesson menu
            btn = pilot.app.query_one("#btn-choose", Button)
            btn.press()
            await pilot.pause()
            assert isinstance(pilot.app.screen, LessonMenuScreen)
            # Press escape to go back
            await pilot.press("escape")
            assert isinstance(pilot.app.screen, WelcomeScreen)

    async def test_screen_stack_depth(self) -> None:
        """Navigating forward increases the screen stack depth."""
        async with OnboardApp().run_test() as pilot:
            initial_depth = len(pilot.app.screen_stack)
            btn = pilot.app.query_one("#btn-choose", Button)
            btn.press()
            await pilot.pause()
            assert len(pilot.app.screen_stack) == initial_depth + 1

    async def test_app_subtitle(self) -> None:
        """The app subtitle is set correctly."""
        async with OnboardApp().run_test() as pilot:
            assert pilot.app.sub_title == "Interactive developer environment tutorials"

    async def test_welcome_screen_has_three_buttons(self) -> None:
        """The welcome screen has exactly three buttons."""
        async with OnboardApp().run_test() as pilot:
            buttons = pilot.app.query(Button)
            # Start, Choose, Quit
            assert len(buttons) == 3
