from pathlib import Path

from textual.widgets import ContentSwitcher, DataTable, Static

from absolutelyright.tui import AbsolutelyApp


async def test_dashboard_loads_and_renders(claude_dir: Path) -> None:
    app = AbsolutelyApp(claude_dir=claude_dir)
    async with app.run_test() as pilot:
        await pilot.pause()
        await app.workers.wait_for_complete()
        await pilot.pause()

        stats = app.query_one("#stats", Static)
        assert "ON THIS MACHINE" in str(stats.content)

        prompts = app.query_one("#repeat", DataTable)
        assert prompts.row_count == 1  # "fix the bug in auth" x2


async def test_sidebar_switches_sections(claude_dir: Path) -> None:
    app = AbsolutelyApp(claude_dir=claude_dir)
    async with app.run_test() as pilot:
        await pilot.pause()
        switcher = app.query_one("#detail", ContentSwitcher)
        assert switcher.current == "overview"

        await pilot.press("down")
        assert switcher.current == "sessions"

        await pilot.press("down", "down")
        assert switcher.current == "rhythm"


async def test_window_binding_reloads(claude_dir: Path) -> None:
    app = AbsolutelyApp(claude_dir=claude_dir)
    async with app.run_test() as pilot:
        await pilot.pause()
        await app.workers.wait_for_complete()

        await pilot.press("7")
        await app.workers.wait_for_complete()
        await pilot.pause()

        assert app.days == 7
        stats = app.query_one("#stats", Static)
        assert "LAST 7 DAYS" in str(stats.content)


async def test_live_reload_on_transcript_change(claude_dir: Path) -> None:
    import asyncio
    import json

    from conftest import user

    app = AbsolutelyApp(claude_dir=claude_dir)
    async with app.run_test() as pilot:
        await pilot.pause()
        await app.workers.wait_for_complete()
        before = app.query_one("#repeat", DataTable).row_count

        transcript = (
            claude_dir / "projects" / "-Users-me-github-com-me-proj" / "s1.jsonl"
        )
        with transcript.open("a") as f:
            f.write(json.dumps(user("ship it")) + "\n")
            f.write(json.dumps(user("ship it")) + "\n")

        for _ in range(60):  # watchdog event → 1s debounce → reload worker
            await asyncio.sleep(0.1)
            await pilot.pause()
            if app.query_one("#repeat", DataTable).row_count > before:
                break
        await app.workers.wait_for_complete()
        await pilot.pause()
        assert app.query_one("#repeat", DataTable).row_count == before + 1


async def test_tree_expansion_survives_reload(claude_dir: Path) -> None:
    from textual.widgets import Tree

    app = AbsolutelyApp(claude_dir=claude_dir)
    async with app.run_test() as pilot:
        await pilot.pause()
        await app.workers.wait_for_complete()
        await pilot.pause()

        tree = app.query_one("#phrase-tree-you", Tree)
        fix = next(n for n in tree.root.children if n.data == ("fix",))
        fix.expand()
        await pilot.pause()
        assert fix.children  # populated lazily on expand

        app._render_trees(app._phrase_maps)  # what a live reload does
        await pilot.pause()

        fix = next(n for n in tree.root.children if n.data == ("fix",))
        assert fix.is_expanded
        assert [c.data for c in fix.children] == [("fix", "the")]


def test_tree_labels_align_leaf_and_branch() -> None:
    branch = AbsolutelyApp._tree_label("python", 4, 209, depth=2)
    leaf = AbsolutelyApp._tree_label("client", 2, 4, depth=3, leaf=True)
    # leaves render no 2-cell arrow icon, so their label is 2 cells longer
    # and one indent (3 cells) shallower-padded: same final columns either way
    assert leaf.cell_len == branch.cell_len + 2 - AbsolutelyApp.TREE_INDENT


def test_tree_bars_never_exceed_parent_share() -> None:
    # a child whose count tops its siblings still can't render a full bar
    # unless it IS the parent's whole volume
    half = AbsolutelyApp._tree_label("client", 2, 4, depth=3, leaf=True)
    assert str(half).count("▓") == 5
    full = AbsolutelyApp._tree_label("me", 6442, 6624, depth=2)
    assert str(full).count("▓") == 10
