from __future__ import annotations

from pathlib import Path
from types import SimpleNamespace

import click
import pytest

from worai.commands import (
    canonicals as canonicals_cmd,
    find_faq_page_wrong_type as faq_cmd,
    google_search_console as gsc_cmd,
    link_groups as link_groups_cmd,
    upload_entities_from_turtle as upload_cmd,
)
from worai.errors import UsageError


def test_google_search_console_resolve_and_run(monkeypatch: pytest.MonkeyPatch) -> None:
    ctx = SimpleNamespace()
    assert gsc_cmd._resolve_value(ctx, "v", "oauth.client_secrets", "ENV") == "v"

    monkeypatch.setenv("ENV", "from_env")
    assert gsc_cmd._resolve_value(ctx, None, "oauth.client_secrets", "ENV") == "from_env"

    monkeypatch.delenv("ENV")
    monkeypatch.setattr(
        gsc_cmd,
        "load_profile_settings",
        lambda _ctx: ({"oauth_client_secrets": "from_profile"}, "p"),
    )
    assert gsc_cmd._resolve_value(ctx, None, "oauth.client_secrets", None) == "from_profile"

    from worai.core.output import OutputFormat

    seen: dict[str, object] = {}
    monkeypatch.setattr(gsc_cmd, "gsc_run", lambda options: seen.setdefault("options", options) or [])
    monkeypatch.setattr(gsc_cmd, "write_output", lambda *_a, **_kw: None)

    gsc_cmd.run(
        ctx=SimpleNamespace(),
        site="sc-domain:example.com",
        client_secrets="client.json",
        token=None,
        port=8080,
        output=None,
        fmt=OutputFormat.csv,
        row_limit=100,
        search_type="web",
        data_state="all",
    )
    assert seen["options"].site == "sc-domain:example.com"


def test_google_search_console_missing_client_secrets(monkeypatch: pytest.MonkeyPatch) -> None:
    from worai.core.output import OutputFormat

    monkeypatch.setattr(gsc_cmd, "load_profile_settings", lambda _ctx: ({}, "default"))
    with pytest.raises(UsageError, match="--client-secrets is required"):
        gsc_cmd.run(
            ctx=SimpleNamespace(),
            site="sc-domain:example.com",
            client_secrets=None,
            token=None,
            port=8080,
            output=None,
            fmt=OutputFormat.csv,
            row_limit=100,
            search_type="web",
            data_state="all",
        )


def test_canonicals_dedupe_wrapper(monkeypatch: pytest.MonkeyPatch) -> None:
    monkeypatch.setattr(
        canonicals_cmd,
        "load_profile_settings",
        lambda _ctx: (
            {
                "gsc_site_id": "sc-domain:example.com",
                "oauth_client_secrets": "client.json",
                "oauth_token": "oauth_token.json",
                "canonicals_output": "canonical_{profile}_{date}_{seq:3}.csv",
            },
            "p",
        ),
    )
    seen: dict[str, object] = {}
    def _stub(options):
        seen["options"] = options
        return [1]
    monkeypatch.setattr(canonicals_cmd, "run_dedupe", _stub)

    canonicals_cmd.dedupe(
        ctx=SimpleNamespace(),
        input_csv="in.csv",
        output_csv="out.csv",
        site_url=None,
        interval="28d",
        url_regex=None,
        concurrency="auto",
        request_timeout_sec=10.0,
        service_account=None,
        client_secrets=None,
        token=None,
        port=8080,
    )
    assert seen["options"].site_url == "sc-domain:example.com"


def test_canonicals_dedupe_missing_site_and_invalid_auth(monkeypatch: pytest.MonkeyPatch) -> None:
    monkeypatch.setattr(canonicals_cmd, "load_profile_settings", lambda _ctx: ({}, "default"))
    with pytest.raises(UsageError, match="--site is required"):
        canonicals_cmd.dedupe(
            ctx=SimpleNamespace(),
            input_csv="in.csv",
            output_csv="out.csv",
            site_url=None,
            interval="28d",
            url_regex=None,
            concurrency="auto",
            request_timeout_sec=10.0,
            service_account=None,
            client_secrets=None,
            token=None,
            port=8080,
        )

    with pytest.raises(UsageError, match="either --service-account or --client-secrets"):
        canonicals_cmd.dedupe(
            ctx=SimpleNamespace(),
            input_csv="in.csv",
            output_csv="out.csv",
            site_url="sc-domain:example.com",
            interval="28d",
            url_regex=None,
            concurrency="auto",
            request_timeout_sec=10.0,
            service_account="sa.json",
            client_secrets="client.json",
            token=None,
            port=8080,
        )


def test_upload_entities_wrapper(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
    folder = tmp_path / "data"
    folder.mkdir()

    monkeypatch.setattr(upload_cmd, "resolve_profile_api_key", lambda _ctx: ("wl", "default", Path("/tmp/w.toml")))
    monkeypatch.setattr(upload_cmd, "upload_run", lambda _opts: 3)

    with pytest.raises(click.exceptions.Exit) as exc:
        upload_cmd.run(SimpleNamespace(), folder, False, 0, None, "https://api.wordlift.io", None)
    assert exc.value.exit_code == 3

    with pytest.raises(UsageError, match="Folder not found"):
        upload_cmd.run(
            SimpleNamespace(), tmp_path / "missing", False, 0, None, "https://api.wordlift.io", None
        )


def test_upload_entities_wrapper_missing_key(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
    folder = tmp_path / "data"
    folder.mkdir()
    monkeypatch.setattr(upload_cmd, "resolve_profile_api_key", lambda _ctx: (None, "default", Path("/tmp/w.toml")))
    with pytest.raises(UsageError, match="Missing API key"):
        upload_cmd.run(SimpleNamespace(), folder, False, 0, None, "https://api.wordlift.io", None)


def test_faq_wrapper_modes(monkeypatch: pytest.MonkeyPatch) -> None:
    seen: dict[str, object] = {}
    monkeypatch.setattr(faq_cmd, "faq_run", lambda options: seen.setdefault("options", options))

    faq_cmd.run(SimpleNamespace(), "data.ttl", patch=False, dry_run=True, replace_type=True)
    assert seen["options"].mode == "dry-run"
    assert seen["options"].replace_type is True

    monkeypatch.setattr(faq_cmd, "resolve_profile_api_key", lambda _ctx: (None, "default", Path("/tmp/w.toml")))
    with pytest.raises(UsageError, match="required for --patch"):
        faq_cmd.run(SimpleNamespace(), "data.ttl", patch=True, dry_run=False, replace_type=False)


def test_link_groups_wrapper(monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]) -> None:
    monkeypatch.setattr(link_groups_cmd, "link_groups_run", lambda _opts: "ttl-output")
    link_groups_cmd.run(SimpleNamespace(), "in.csv", "turtle", False, False, 2, 3)
    assert "ttl-output" in capsys.readouterr().out

    monkeypatch.setattr(link_groups_cmd, "resolve_profile_api_key", lambda _ctx: (None, "default", Path("/tmp/w.toml")))
    with pytest.raises(UsageError, match="required when using --apply"):
        link_groups_cmd.run(SimpleNamespace(), "in.csv", "turtle", True, False, 2, 3)

    seen: dict[str, object] = {}
    monkeypatch.setattr(link_groups_cmd, "resolve_profile_api_key", lambda _ctx: ("wl", "default", Path("/tmp/w.toml")))
    monkeypatch.setattr(link_groups_cmd, "link_groups_run", lambda options: seen.setdefault("apply", options.apply) or "")
    link_groups_cmd.run(SimpleNamespace(), "in.csv", "turtle", True, False, 2, 3)
    assert seen["apply"] is True
