"""Tests for CLI commands using CliRunner."""

import json
from unittest.mock import MagicMock, patch

import pytest
from click.testing import CliRunner

from corpo.cli import cli


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


def test_help(runner):
    result = runner.invoke(cli, ["--help"])
    assert result.exit_code == 0
    assert "corpo" in result.output
    assert "KEYPAIR SECURITY" in result.output


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


def test_init_creates_keypair(runner, tmp_path, monkeypatch):
    from pathlib import Path as RealPath

    original_expanduser = RealPath.expanduser

    def mock_expanduser(self):
        s = str(self)
        if "~/.corpo" in s:
            remainder = s.split("~/.corpo/")[-1] if "~/.corpo/" in s else ""
            base = tmp_path / ".corpo"
            return base / remainder if remainder else base
        return original_expanduser(self)

    monkeypatch.setattr(RealPath, "expanduser", mock_expanduser)

    result = runner.invoke(cli, ["init"])
    assert result.exit_code == 0
    parsed = json.loads(result.output)
    assert parsed["ok"] is True
    assert "pubkey" in parsed["data"]
    assert (tmp_path / ".corpo" / "keypair.json").exists()
    assert (tmp_path / ".corpo" / "config.toml").exists()


def test_status_no_keypair(runner, tmp_path):
    result = runner.invoke(cli, ["--config", str(tmp_path / "nope.toml"), "status"])
    # Should still succeed but with null pubkey
    assert result.exit_code == 0
    parsed = json.loads(result.output)
    assert parsed["ok"] is True
    assert parsed["data"]["pubkey"] is None


def test_realms_command(runner, tmp_config):
    """Test realms command with mocked client."""
    with patch("corpo.cli.get_client") as MockClient:
        instance = MockClient.return_value
        instance.list_realms.return_value = [{"name": "TestDAO"}]
        result = runner.invoke(cli, ["--config", str(tmp_config), "realms"])

    assert result.exit_code == 0
    parsed = json.loads(result.output)
    assert parsed["ok"] is True
    assert parsed["data"]["realms"] == [{"name": "TestDAO"}]


def test_proposals_requires_governance(runner, tmp_path):
    """Without governance configured, proposals should fail."""
    cfg = tmp_path / "empty.toml"
    cfg.write_text("[network]\napi_url = \"http://localhost\"\n")
    result = runner.invoke(cli, ["--config", str(cfg), "proposals"])
    assert result.exit_code == 1


def test_members_command(runner, tmp_config):
    with patch("corpo.cli.get_client") as MockClient:
        instance = MockClient.return_value
        instance.list_members.return_value = [{"owner": "abc"}]
        result = runner.invoke(cli, [
            "--config", str(tmp_config),
            "members",
        ])

    assert result.exit_code == 0
    parsed = json.loads(result.output)
    assert parsed["ok"] is True


def test_realm_by_address(runner, tmp_config):
    with patch("corpo.cli.get_client") as MockClient:
        instance = MockClient.return_value
        instance.get_realm.return_value = {"address": "abc", "realm": {"name": "Test"}}
        result = runner.invoke(cli, [
            "--config", str(tmp_config),
            "realm", "--address", "abc",
        ])

    assert result.exit_code == 0
    parsed = json.loads(result.output)
    assert parsed["ok"] is True


def test_realm_by_name(runner, tmp_config):
    with patch("corpo.cli.get_client") as MockClient:
        instance = MockClient.return_value
        instance.get_realm_by_name.return_value = {"address": "xyz", "realm": {"name": "Named"}}
        result = runner.invoke(cli, [
            "--config", str(tmp_config),
            "realm", "--name", "Named",
        ])

    assert result.exit_code == 0
    parsed = json.loads(result.output)
    assert parsed["ok"] is True
