"""CLI command tests."""

from __future__ import annotations

import os

import pytest
from click.testing import CliRunner

from clawsy.cli import cli
from clawsy.client import HubClient, HubError
from clawsy.config import Config


HUB_URL = "https://agenthub.clawsy.app"
# Set CLAWSY_TEST_KEY env var to run authenticated tests
API_KEY = os.environ.get("CLAWSY_TEST_KEY", "")


@pytest.fixture
def runner():
    return CliRunner()


# --- Unit tests (no network) ---

class TestQualityGate:
    def test_hub_error_preserves_data(self):
        err = HubError(422, "task quality too low", {"can_improve": True, "issues": ["vague title"]})
        assert err.status == 422
        assert err.data["can_improve"] is True
        assert "vague title" in err.data["issues"]

    def test_hub_error_default_data(self):
        err = HubError(500, "internal error")
        assert err.data == {}


class TestCLI:
    def test_version(self, runner):
        result = runner.invoke(cli, ["--version"])
        assert result.exit_code == 0
        assert "0.2.0" in result.output

    def test_karma_no_auth(self, runner):
        result = runner.invoke(cli, ["karma"])
        assert result.exit_code == 1 or "Not connected" in result.output


# --- Public API tests (no auth needed) ---

class TestPublicAPI:
    def test_list_categories(self):
        cfg = Config(hub_url=HUB_URL, api_key="")
        hub = HubClient(cfg)
        try:
            cats = hub.list_categories()
            assert len(cats) >= 4
            ids = [c["id"] for c in cats]
            assert "content" in ids
            assert "data" in ids
        finally:
            hub.close()

    def test_leaderboard(self):
        cfg = Config(hub_url=HUB_URL, api_key="")
        hub = HubClient(cfg)
        try:
            lb = hub.leaderboard()
            assert isinstance(lb, list)
        finally:
            hub.close()


# --- Authenticated API tests (need CLAWSY_TEST_KEY) ---

@pytest.fixture
def auth_hub():
    if not API_KEY:
        pytest.skip("CLAWSY_TEST_KEY not set")
    cfg = Config(hub_url=HUB_URL, api_key=API_KEY)
    client = HubClient(cfg)
    yield client
    client.close()


class TestAuthAPI:
    def test_list_tasks(self, auth_hub):
        tasks = auth_hub.list_tasks(status="open")
        assert isinstance(tasks, list)

    def test_get_karma(self, auth_hub):
        data = auth_hub.get_karma()
        assert "karma_balance" in data

    def test_generate_title(self, auth_hub):
        title = auth_hub.generate_title(
            description="Improve SEO copy for landing page",
            program_md="Our product helps teams collaborate better.",
        )
        assert isinstance(title, str)
        assert len(title) > 0

    def test_get_quality_nonexistent(self, auth_hub):
        with pytest.raises(HubError) as exc:
            auth_hub.get_quality(999999)
        assert exc.value.status == 404

    def test_create_and_quality(self, auth_hub):
        """Create a task and check quality score."""
        try:
            result = auth_hub.create_task(
                title="CLI Test Task",
                description="Testing from pytest",
                program_md="Improve this text for better readability and SEO.",
                visibility="private",
            )
            assert result.get("id")
            task_id = result["id"]

            quality = auth_hub.get_quality(task_id)
            # Quality may or may not have score (depends on LLM availability)
            assert "recommendation" in quality
        except HubError as e:
            # 402 (no karma) or 422 (quality gate) are acceptable
            assert e.status in (402, 422, 429)
