from __future__ import annotations

from pathlib import Path
from types import SimpleNamespace

import click
import pytest

import worai.seoreport.cli as mod


class _Template:
    def __init__(self, seen: dict[str, object]):
        self._seen = seen

    def render(self, data):
        self._seen["data"] = data
        return "rendered"


class _Env:
    def __init__(self, loader, seen):
        self._seen = seen
        self.loader = loader

    def get_template(self, name):
        self._seen["template"] = name
        return _Template(self._seen)


def test_resolve_value_and_timestamp(monkeypatch: pytest.MonkeyPatch) -> None:
    ctx = SimpleNamespace()
    assert mod._resolve_value(ctx, "v", "gsc.id", "GSC_ID") == "v"
    monkeypatch.setenv("GSC_ID", "env")
    assert mod._resolve_value(ctx, None, "gsc.id", "GSC_ID") == "env"

    monkeypatch.delenv("GSC_ID")
    monkeypatch.setattr(mod, "load_profile", lambda _ctx: (SimpleNamespace(settings={"gsc_id": "cfg"}), "p", Path("x")))
    assert mod._resolve_value(ctx, None, "gsc.id", None) == "cfg"
    assert len(mod.generate_timestamp_str()) == 15


def test_run_error_paths(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
    with pytest.raises(Exception):
        mod.run(SimpleNamespace(), site=None)

    monkeypatch.setattr(mod, "_resolve_value", lambda *_a, **_k: "sc-domain:example.com")
    with pytest.raises(Exception):
        mod.run(SimpleNamespace(), site="sc-domain:example.com", token="a.json", ga_token="b.json")

    monkeypatch.setattr(mod, "generate_timestamp_str", lambda: "20260101_000000")
    monkeypatch.setattr(mod, "Environment", lambda loader: _Env(loader, {}))
    monkeypatch.setattr(mod, "generate_report_data", lambda _o: {})
    with pytest.raises(click.exceptions.Exit) as exc:
        mod.run(
            SimpleNamespace(),
            site="sc-domain:example.com",
            output=str(tmp_path / "x.md"),
            format="markdown",
            client_secrets=None,
            token=None,
            ga_id=None,
            ga_client_secrets=None,
            ga_token=None,
            ga_direct_share=2.0,
            ga_source_regex="(chatgpt)",
            ga_channel_group_name="AI Channel Group",
            ga_channel_group_id=None,
            gsc_max_workers=3,
            ga_max_workers=3,
            port=8080,
            inspect_limit=0,
            url_regex=None,
        )
    assert exc.value.exit_code == 1


def test_run_success_html_and_failure_from_generator(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
    seen: dict[str, object] = {}
    monkeypatch.setattr(mod, "_resolve_value", lambda _ctx, value, _path, _env: value)
    monkeypatch.setattr(mod, "generate_timestamp_str", lambda: "20260101_000000")
    monkeypatch.setattr(mod, "Environment", lambda loader: _Env(loader, seen))
    monkeypatch.setattr(mod, "generate_report_data", lambda _o: {"ok": True})

    out = tmp_path / "report.html"
    mod.run(
        SimpleNamespace(),
        site="sc-domain:example.com",
        output=str(out),
        format="html",
        client_secrets=None,
        token=None,
        ga_id=None,
        ga_client_secrets=None,
        ga_token=None,
        ga_direct_share=0.3,
        ga_source_regex="(chatgpt)",
        ga_channel_group_name="AI Channel Group",
        ga_channel_group_id=None,
        gsc_max_workers=3,
        ga_max_workers=3,
        port=8080,
        inspect_limit=0,
        url_regex=None,
    )
    assert out.read_text(encoding="utf-8") == "rendered"
    assert seen["template"] == "report.html"

    monkeypatch.setattr(mod, "generate_report_data", lambda _o: (_ for _ in ()).throw(RuntimeError("boom")))
    with pytest.raises(click.exceptions.Exit) as exc:
        mod.run(
            SimpleNamespace(),
            site="sc-domain:example.com",
            output=str(tmp_path / "x.md"),
            format="markdown",
            client_secrets=None,
            token=None,
            ga_id=None,
            ga_client_secrets=None,
            ga_token=None,
            ga_direct_share=0.3,
            ga_source_regex="(chatgpt)",
            ga_channel_group_name="AI Channel Group",
            ga_channel_group_id=None,
            gsc_max_workers=3,
            ga_max_workers=3,
            port=8080,
            inspect_limit=0,
            url_regex=None,
        )
    assert exc.value.exit_code == 1
