from __future__ import annotations

import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parents[1]))

from ui.footer import Footer, _FallbackGtk
from ui.view_model import DashboardCallbacks

_TOOLS_ALL = (("codex", "Codex"), ("claude", "Claude Code"), ("grok", "Grok"))


def _callbacks(calls: list[tuple[object, ...]]) -> DashboardCallbacks:
    return DashboardCallbacks(
        on_set_default=lambda tool, slug: calls.append(("set_default", tool, slug)),
        on_reload=lambda tool, slug: calls.append(("reload", tool, slug)),
        on_repair=lambda tool, slug: calls.append(("repair", tool, slug)),
        on_rename=lambda tool, slug: calls.append(("rename", tool, slug)),
        on_remove=lambda tool, slug: calls.append(("remove", tool, slug)),
        on_add=lambda tool: calls.append(("add", tool)),
        on_open_settings=lambda: calls.append(("open_settings",)),
        on_set_limits=lambda tool, slug: calls.append(("set_limits", tool, slug)),
        on_tab_changed=lambda tab_id: calls.append(("tab_changed", tab_id)),
    )


def _footer(
    calls: list[tuple[object, ...]],
    add_label: str = "＋ Add Codex account",
    add_tools: tuple[tuple[str, str], ...] = (("codex", "Codex"),),
    refresh_text: str = "⟳ 12s ago",
) -> Footer:
    return Footer(
        add_label, add_tools, refresh_text, _callbacks(calls), gtk_module=_FallbackGtk
    )


def test_footer_is_single_horizontal_row_with_expanding_timestamp() -> None:
    footer = _footer([])
    assert footer.widget.orientation == _FallbackGtk.Orientation.HORIZONTAL
    assert footer.widget.children == [
        footer.add_button,
        footer.timestamp_label,
        footer.reload_button,
        footer.settings_button,
    ]
    assert footer.timestamp_label.hexpand is True
    assert "footer" in footer.widget.css_classes
    assert "footer-timestamp" in footer.timestamp_label.css_classes
    assert "flat" in footer.add_button.css_classes
    assert footer.add_button.label == "＋ Add Codex account"
    assert footer.timestamp_label.text == "⟳ 12s ago"
    assert footer.reload_button.label == "Reload All"
    assert footer.settings_button.label == "⚙"


def test_add_with_single_tool_dispatches_directly() -> None:
    calls: list[tuple[object, ...]] = []
    footer = _footer(calls)
    footer.add_button.emit("clicked")
    assert calls == [("add", "codex")]
    assert footer.popover.visible is False


def test_add_with_multiple_tools_opens_popover_and_items_dispatch() -> None:
    calls: list[tuple[object, ...]] = []
    footer = _footer(calls, add_label="＋ Add account", add_tools=_TOOLS_ALL)

    footer.add_button.emit("clicked")
    assert calls == []
    assert footer.popover.visible is True
    assert list(footer.add_item_buttons) == ["codex", "claude", "grok"]
    assert footer.add_item_buttons["claude"].label == "＋ Add Claude Code account"

    footer.add_item_buttons["claude"].emit("clicked")
    assert calls == [("add", "claude")]
    assert footer.popover.visible is False


def test_reload_all_dispatches_none_none() -> None:
    calls: list[tuple[object, ...]] = []
    footer = _footer(calls)
    footer.reload_button.emit("clicked")
    assert calls == [("reload", None, None)]


def test_settings_gear_dispatches_open_settings() -> None:
    calls: list[tuple[object, ...]] = []
    footer = _footer(calls)
    footer.settings_button.emit("clicked")
    assert calls == [("open_settings",)]


def test_update_refreshes_label_timestamp_and_add_tools() -> None:
    calls: list[tuple[object, ...]] = []
    footer = _footer(calls)
    footer.update("＋ Add account", _TOOLS_ALL, "⟳ 3m ago")
    assert footer.add_button.label == "＋ Add account"
    assert footer.timestamp_label.text == "⟳ 3m ago"
    footer.add_button.emit("clicked")
    assert calls == []
    footer.add_item_buttons["grok"].emit("clicked")
    assert calls == [("add", "grok")]


def test_update_with_same_tools_keeps_popover_items() -> None:
    footer = _footer([], add_label="＋ Add account", add_tools=_TOOLS_ALL)
    before = footer.add_item_buttons
    footer.update("＋ Add account", _TOOLS_ALL, "⟳ 1m ago")
    assert footer.add_item_buttons is before


def test_busy_tool_disables_single_add_button_until_cleared() -> None:
    calls: list[tuple[object, ...]] = []
    footer = _footer(calls)

    footer.update("＋ Add Codex account", (("codex", "Codex"),), "⟳ 1s ago", frozenset({"codex"}))
    assert footer.add_button.sensitive is False
    footer.add_button.emit("clicked")
    assert calls == []

    footer.update("＋ Add Codex account", (("codex", "Codex"),), "⟳ 2s ago")
    assert footer.add_button.sensitive is True
    footer.add_button.emit("clicked")
    assert calls == [("add", "codex")]


def test_busy_tool_disables_only_its_popover_item() -> None:
    footer = _footer([], add_label="＋ Add account", add_tools=_TOOLS_ALL)

    footer.update("＋ Add account", _TOOLS_ALL, "⟳ 1s ago", frozenset({"claude"}))

    assert footer.add_button.sensitive is True
    assert footer.add_item_buttons["claude"].sensitive is False
    assert footer.add_item_buttons["codex"].sensitive is True
    assert footer.add_item_buttons["grok"].sensitive is True


def test_footer_constructs_headless_without_gtk_module() -> None:
    footer = Footer("＋ Add account", _TOOLS_ALL, "⟳ never", _callbacks([]))
    assert footer.widget is not None
