import logging
from collections import Counter
import webbrowser

from web_sentinel.gui.sections import HistorySection, PaymentSection
from web_sentinel.gui.modern_tabbed_window import _GUIStatusHandler
from web_sentinel.model import Finding, ScanRequest, ScanResult


class _FakeText:
    def __init__(self) -> None:
        self._content = ""
        self.state = None

    def config(self, **kwargs) -> None:
        self.state = kwargs.get("state", self.state)

    def delete(self, *_args) -> None:
        self._content = ""

    def insert(self, _index, value: str) -> None:
        self._content += value

    def getvalue(self) -> str:
        return self._content


class _FakeTree:
    def __init__(self) -> None:
        self._children: list[str] = []
        self._selection: list[str] = []

    def get_children(self):
        return list(self._children)

    def delete(self, item: str) -> None:
        if item in self._children:
            self._children.remove(item)

    def insert(self, _parent, _index, values):
        iid = f"item{len(self._children)}"
        self._children.append(iid)
        return iid

    def selection(self) -> list[str]:
        return list(self._selection)

    def set_selection(self, iid: str) -> None:
        self._selection = [iid]


class DummyGUI:
    def __init__(self) -> None:
        self.history_entries: list[ScanResult] = []
        self.history_tree = _FakeTree()
        self.history_tree_data: dict[str, ScanResult] = {}
        self.history_detail_text = _FakeText()
        self.history_var = type("Var", (), {"get": lambda self: True})()
        self.localization = type("Loc", (), {"translate_severity": lambda self, x: x})()
        self.report_engine = type("Rep", (), {"build_context": lambda self, result: {"findings": []}})()

    def _text(self, key: str, **kwargs) -> str:
        if kwargs:
            return f"{key}:{kwargs}"
        return key

    def _render_severity_overview(self, counts: Counter) -> str:
        return str(sum(counts.values()))

    def _determine_scan_type(self, result: ScanResult) -> str:
        return "sast"

    def _history_target_label(self, result: ScanResult) -> str:
        return result.request.domain

    def _format_history_detail(self, result: ScanResult) -> str:
        return f"detail:{result.request.domain}:{len(result.findings)}"


class DummyGUIStatus:
    class _Root:
        def __init__(self, outer) -> None:
            self.outer = outer

        def after(self, _delay, func, message):
            func(message)

    class _Var:
        def __init__(self) -> None:
            self.value = ""

        def set(self, value: str) -> None:
            self.value = value

    def __init__(self) -> None:
        self.root = DummyGUIStatus._Root(self)
        self.status_var = DummyGUIStatus._Var()


def sample_result() -> ScanResult:
    request = ScanRequest(domain="example.com")
    finding = Finding(
        check="source-code",
        title="Hardcoded secret",
        severity="high",
        description="",
        remediation="",
    )
    return ScanResult(request=request, findings=[finding])


def test_history_refresh_and_select():
    gui = DummyGUI()
    gui.history_entries.append(sample_result())
    section = HistorySection(gui)
    section.refresh()

    assert gui.history_tree_data, "History tree data should be populated"
    iid = next(iter(gui.history_tree_data))
    gui.history_tree.set_selection(iid)
    section.on_select()

    assert "detail" in gui.history_detail_text.getvalue()


def test_payment_section_checkout(monkeypatch):
    gui = type("GUI", (), {})()
    section = PaymentSection(gui)

    assert section.open_checkout("pro", "monthly", open_browser=False) is None

    section.controller.client.api_key = "sk_test_dummy"
    monkeypatch.setattr(webbrowser, "open", lambda url: None)
    url = section.open_checkout("pro", "monthly", open_browser=False)
    assert url.endswith("price_pro_monthly")


def test_gui_status_handler_updates_status():
    gui = DummyGUIStatus()
    handler = _GUIStatusHandler(gui)
    record = logging.LogRecord("web_sentinel.gui", logging.INFO, __file__, 0, "hello", None, None)
    handler.handle(record)
    assert gui.status_var.value == "hello"
