from pathlib import Path

import pytest

from home_agent.contracts.types import Alert, UrgencyLabel
from home_agent.core.config import LoggingConfig
from home_agent.core.logging import configure_logging, reset_logging
from home_agent.notifications.notifier import ToastNotifier


def test_toast_notifier_initializes_backend_and_sends_notification(
    monkeypatch: pytest.MonkeyPatch,
    tmp_path: Path,
) -> None:
    configure_logging(
        LoggingConfig(
            directory=tmp_path,
            file_name="test.jsonl",
            console_level="DEBUG",
            file_level="DEBUG",
            enable_console=False,
        )
    )

    class FakeDesktopNotifierSync:
        def __init__(self, *, app_name: str) -> None:
            self.app_name: str = app_name
            self.sent: list[tuple[str, str]] = []
            created.append(self)

        def send(self, *, title: str, message: str) -> None:
            self.sent.append((title, message))

    created: list[FakeDesktopNotifierSync] = []

    monkeypatch.setattr(
        "home_agent.notifications.notifier._desktop_notifier_factory",
        FakeDesktopNotifierSync,
    )
    monkeypatch.setattr(
        "home_agent.notifications.notifier._desktop_notifier_import_error",
        None,
    )

    alert = Alert(
        title="HIGH: Deadline",
        body="From sender@example.com (google_calendar)",
        severity=UrgencyLabel.HIGH,
    )
    log_path = tmp_path / "alerts.log"

    ToastNotifier(log_path).notify(alert)

    assert len(created) == 1
    assert created[0].app_name == "home-agent"
    assert created[0].sent == [("HIGH: Deadline", "From sender@example.com (google_calendar)")]
    assert log_path.read_text(encoding="utf-8") == (
        "[high] HIGH: Deadline - From sender@example.com (google_calendar)\n"
    )

    joined = (tmp_path / "test.jsonl").read_text(encoding="utf-8")
    assert "notifications.desktop.start" in joined
    assert "notifications.desktop.completed" in joined
    assert "notifications.desktop.failed" not in joined

    reset_logging()


def test_toast_notifier_logs_send_failure_without_raising(
    monkeypatch: pytest.MonkeyPatch,
    tmp_path: Path,
) -> None:
    configure_logging(
        LoggingConfig(
            directory=tmp_path,
            file_name="test.jsonl",
            console_level="DEBUG",
            file_level="DEBUG",
            enable_console=False,
        )
    )

    class FakeDesktopNotifierSync:
        def __init__(self, *, app_name: str) -> None:
            self.app_name: str = app_name

        def send(self, *, title: str, message: str) -> None:
            _ = title, message
            msg = "boom"
            raise RuntimeError(msg)

    monkeypatch.setattr(
        "home_agent.notifications.notifier._desktop_notifier_factory",
        FakeDesktopNotifierSync,
    )
    monkeypatch.setattr(
        "home_agent.notifications.notifier._desktop_notifier_import_error",
        None,
    )

    alert = Alert(
        title="CRITICAL: Incident",
        body="From ops@example.com (gmail)",
        severity=UrgencyLabel.CRITICAL,
    )
    log_path = tmp_path / "alerts.log"

    ToastNotifier(log_path).notify(alert)

    assert log_path.read_text(encoding="utf-8") == (
        "[critical] CRITICAL: Incident - From ops@example.com (gmail)\n"
    )

    joined = (tmp_path / "test.jsonl").read_text(encoding="utf-8")
    assert "notifications.desktop.start" in joined
    assert "notifications.desktop.failed" in joined
    assert "boom" in joined

    reset_logging()


def test_toast_notifier_logs_init_failure_and_skips_send(
    monkeypatch: pytest.MonkeyPatch,
    tmp_path: Path,
) -> None:
    configure_logging(
        LoggingConfig(
            directory=tmp_path,
            file_name="test.jsonl",
            console_level="DEBUG",
            file_level="DEBUG",
            enable_console=False,
        )
    )

    class FakeDesktopNotifierSync:
        def __init__(self, *, app_name: str) -> None:
            _ = app_name
            msg = "backend unavailable"
            raise RuntimeError(msg)

    monkeypatch.setattr(
        "home_agent.notifications.notifier._desktop_notifier_factory",
        FakeDesktopNotifierSync,
    )
    monkeypatch.setattr(
        "home_agent.notifications.notifier._desktop_notifier_import_error",
        None,
    )

    alert = Alert(
        title="HIGH: Deadline",
        body="From sender@example.com (google_calendar)",
        severity=UrgencyLabel.HIGH,
    )
    log_path = tmp_path / "alerts.log"

    ToastNotifier(log_path).notify(alert)

    assert log_path.read_text(encoding="utf-8") == (
        "[high] HIGH: Deadline - From sender@example.com (google_calendar)\n"
    )

    joined = (tmp_path / "test.jsonl").read_text(encoding="utf-8")
    assert "notifications.desktop.init_failed" in joined
    assert "backend unavailable" in joined
    assert "notifications.desktop.failed" in joined
    assert "notifications.desktop.completed" not in joined

    reset_logging()
