from pathlib import Path
from typing import ClassVar

import pytest

from home_agent.cli.main import _handle_auth
from home_agent.core.config import (
    AlertsConfig,
    AppConfig,
    BudgetConfig,
    LLMConfig,
    MemoryConfig,
    PollConfig,
    RetentionConfig,
)


def _config(db_path: Path) -> AppConfig:
    return AppConfig(
        poll=PollConfig(),
        budget=BudgetConfig(),
        retention=RetentionConfig(),
        alerts=AlertsConfig(),
        llm=LLMConfig(),
        memory=MemoryConfig(),
        enabled_providers=["gmail"],
        sqlite_path=db_path,
        daily_digest_enabled=True,
    )


class FakeGoogleAuthManager:
    seen_scopes: ClassVar[tuple[str, ...] | None] = None
    error: ClassVar[RuntimeError | None] = None

    def __init__(self, store: object, token_name: str = "google") -> None:
        self.store: object = store
        self.token_name: str = token_name

    def init_desktop_auth(self, scopes: tuple[str, ...]) -> None:
        if self.__class__.error is not None:
            raise self.__class__.error
        self.__class__.seen_scopes = scopes


def test_handle_auth_reports_missing_google_credentials(
    capsys: pytest.CaptureFixture[str],
    monkeypatch: pytest.MonkeyPatch,
    tmp_path: Path,
) -> None:
    FakeGoogleAuthManager.error = RuntimeError("missing GOOGLE_CLIENT_ID/GOOGLE_CLIENT_SECRET")
    monkeypatch.setattr(
        "home_agent.cli.main.load_plugins",
        lambda enabled: [type("GmailPlugin", (), {"id": "gmail", "version": "0.1.0"})()],
    )
    monkeypatch.setattr("home_agent.cli.main.GoogleAuthManager", FakeGoogleAuthManager)

    exit_code = _handle_auth(_config(tmp_path / "test.db"), "google", True)

    captured = capsys.readouterr()
    assert exit_code == 1
    assert "missing GOOGLE_CLIENT_ID/GOOGLE_CLIENT_SECRET" in captured.out
    assert ".env" in captured.out
    FakeGoogleAuthManager.error = None


def test_handle_auth_initializes_google_with_gmail_and_calendar_scopes(
    capsys: pytest.CaptureFixture[str],
    monkeypatch: pytest.MonkeyPatch,
    tmp_path: Path,
) -> None:
    FakeGoogleAuthManager.seen_scopes = None
    FakeGoogleAuthManager.error = None
    monkeypatch.setattr(
        "home_agent.cli.main.load_plugins",
        lambda enabled: [
            type("GmailPlugin", (), {"id": "gmail", "version": "0.1.0"})(),
            type("CalendarPlugin", (), {"id": "google_calendar", "version": "0.1.0"})(),
        ],
    )
    monkeypatch.setattr("home_agent.cli.main.GoogleAuthManager", FakeGoogleAuthManager)

    exit_code = _handle_auth(_config(tmp_path / "test.db"), "google", True)

    captured = capsys.readouterr()
    assert exit_code == 0
    assert FakeGoogleAuthManager.seen_scopes == (
        "https://www.googleapis.com/auth/gmail.readonly",
        "https://www.googleapis.com/auth/calendar.readonly",
    )
    assert "initialized auth for google" in captured.out


def test_handle_auth_resets_google_token(
    capsys: pytest.CaptureFixture[str],
    monkeypatch: pytest.MonkeyPatch,
    tmp_path: Path,
) -> None:
    tokens_dir = tmp_path / ".data" / "tokens"
    tokens_dir.mkdir(parents=True)
    (tokens_dir / ".key").write_text("keep", encoding="utf-8")
    (tokens_dir / "google.enc").write_text("secret", encoding="utf-8")
    monkeypatch.chdir(tmp_path)

    exit_code = _handle_auth(_config(tmp_path / "test.db"), "google", False, reset=True)

    captured = capsys.readouterr()
    assert exit_code == 0
    assert not (tokens_dir / "google.enc").exists()
    assert (tokens_dir / ".key").exists()
    assert "reset auth for google" in captured.out
