from __future__ import annotations

import sys
from pathlib import Path
from typing import Any

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

from tests.cards_helpers import make_account_vm, make_callbacks
from ui.provider_tab import ProviderTab, _FallbackGtk
from ui.view_model import ProviderTabVM


def _vm(*accounts: Any) -> ProviderTabVM:
    return ProviderTabVM(
        tool="codex", accounts=tuple(accounts), add_label="＋ Add Codex account"
    )


def _tab(vm: ProviderTabVM, calls: list[tuple[Any, ...]] | None = None) -> ProviderTab:
    return ProviderTab(
        vm, make_callbacks(calls if calls is not None else []), gtk_module=_FallbackGtk
    )


def test_one_card_per_account_keyed_by_slug() -> None:
    tab = _tab(
        _vm(
            make_account_vm(slug="work", alias="Work"),
            make_account_vm(slug="personal", alias="Personal"),
        )
    )

    assert set(tab.cards) == {"work", "personal"}
    assert tab.cards["work"].alias_label.text == "Work"
    assert tab.cards["personal"].alias_label.text == "Personal"
    assert tab.widget.children == [
        tab.cards["work"].widget,
        tab.cards["personal"].widget,
    ]


def test_update_with_same_slugs_reuses_cards_in_place() -> None:
    tab = _tab(
        _vm(
            make_account_vm(slug="work", alias="Work"),
            make_account_vm(slug="personal", alias="Personal"),
        )
    )
    before = dict(tab.cards)
    widget_children = list(tab.widget.children)

    tab.update(
        _vm(
            make_account_vm(slug="work", alias="Renamed", is_default=True),
            make_account_vm(slug="personal", alias="Personal"),
        )
    )

    assert tab.cards["work"] is before["work"]
    assert tab.cards["personal"] is before["personal"]
    assert tab.widget.children == widget_children
    assert tab.cards["work"].alias_label.text == "Renamed"
    assert tab.cards["work"].default_badge.visible is True


def test_added_account_rebuilds_cards() -> None:
    tab = _tab(_vm(make_account_vm(slug="work")))
    before = dict(tab.cards)

    tab.update(
        _vm(
            make_account_vm(slug="work"),
            make_account_vm(slug="personal", alias="Personal"),
        )
    )

    assert set(tab.cards) == {"work", "personal"}
    assert tab.cards["work"] is not before["work"]
    assert len(tab.widget.children) == 2


def test_removed_account_rebuilds_cards() -> None:
    tab = _tab(
        _vm(
            make_account_vm(slug="work"),
            make_account_vm(slug="personal", alias="Personal"),
        )
    )

    tab.update(_vm(make_account_vm(slug="personal", alias="Personal")))

    assert set(tab.cards) == {"personal"}
    assert tab.widget.children == [tab.cards["personal"].widget]


def test_cards_dispatch_callbacks_with_tool_and_slug() -> None:
    calls: list[tuple[Any, ...]] = []
    tab = _tab(_vm(make_account_vm(tool="codex", slug="work")), calls)

    labels = [label for label, _ in tab.cards["work"].menu_items]
    assert labels[0] == "Set as default"
    tab.cards["work"].menu_items[0][1]()
    tab.cards["work"].menu_items[1][1]()

    assert calls == [("set_default", "codex", "work"), ("reload", "codex", "work")]
