"""Tests for MockCorpoClient and mock mode factory."""

import json
import os
from unittest.mock import patch

import pytest
from click.testing import CliRunner

from corpo.client import CorpoClient, MockCorpoClient, get_client, is_mock_mode


class TestMockCorpoClient:
    def setup_method(self):
        self.client = MockCorpoClient()

    def test_register_account(self):
        result = self.client.register_account("test@example.com")
        assert "api_key" in result
        assert result["api_key"].startswith("mock-key-")
        assert "account_id" in result
        assert result["email"] == "test@example.com"

    def test_get_account(self):
        result = self.client.get_account("acct-001")
        assert result["account_id"] == "acct-001"
        assert result["status"] == "active"

    def test_create_quote(self):
        result = self.client.create_quote("Test LAO LLC")
        assert result["name_available"] is True
        assert result["entity_name"] == "Test LAO LLC"
        assert "quote_id" in result

    def test_get_quote(self):
        result = self.client.get_quote("q-123")
        assert result["quote_id"] == "q-123"

    def test_pay_quote(self):
        result = self.client.pay_quote("q-123")
        assert result["status"] == "paid"

    def test_get_realm(self):
        result = self.client.get_realm("realm-abc")
        assert result["address"] == "realm-abc"

    def test_list_realms(self):
        result = self.client.list_realms()
        assert isinstance(result, list)
        assert len(result) > 0

    def test_tx_create_realm(self):
        result = self.client.tx_create_realm({"name": "Test"})
        assert result["transaction"] == "MOCK_TX_BASE64"
        assert "blockhash" in result

    def test_get_actions_catalog(self):
        result = self.client.get_actions_catalog()
        assert isinstance(result, list)
        assert len(result) > 0

    def test_initiate_action(self):
        result = self.client.initiate_action("ent-1", "add_member")
        assert result["action_type"] == "add_member"
        assert result["status"] == "pending"

    def test_list_recipes(self):
        result = self.client.list_recipes()
        assert isinstance(result, list)
        assert len(result) > 0

    def test_execute_recipe(self):
        result = self.client.execute_recipe("ent-1", "full-formation")
        assert result["status"] == "completed"

    def test_close_is_noop(self):
        self.client.close()  # should not raise

    def test_counter_increments(self):
        q1 = self.client.create_quote("A LAO LLC")
        q2 = self.client.create_quote("B LAO LLC")
        assert q1["quote_id"] != q2["quote_id"]


class TestIsMockMode:
    def test_default_off(self):
        with patch.dict(os.environ, {}, clear=True):
            os.environ.pop("CORPO_MOCK_MODE", None)
            assert is_mock_mode() is False

    def test_enabled_1(self):
        with patch.dict(os.environ, {"CORPO_MOCK_MODE": "1"}):
            assert is_mock_mode() is True

    def test_enabled_true(self):
        with patch.dict(os.environ, {"CORPO_MOCK_MODE": "true"}):
            assert is_mock_mode() is True

    def test_enabled_yes(self):
        with patch.dict(os.environ, {"CORPO_MOCK_MODE": "yes"}):
            assert is_mock_mode() is True

    def test_disabled_0(self):
        with patch.dict(os.environ, {"CORPO_MOCK_MODE": "0"}):
            assert is_mock_mode() is False

    def test_disabled_empty(self):
        with patch.dict(os.environ, {"CORPO_MOCK_MODE": ""}):
            assert is_mock_mode() is False


class TestGetClientFactory:
    def test_returns_real_by_default(self):
        with patch.dict(os.environ, {}, clear=True):
            os.environ.pop("CORPO_MOCK_MODE", None)
            client = get_client("http://localhost")
            assert isinstance(client, CorpoClient)
            client.close()

    def test_returns_mock_when_enabled(self):
        with patch.dict(os.environ, {"CORPO_MOCK_MODE": "1"}):
            client = get_client("http://localhost")
            assert isinstance(client, MockCorpoClient)


class TestRegisterWithMock:
    def test_register_mock_mode(self):
        runner = CliRunner()
        from corpo.cli import cli
        with patch.dict(os.environ, {"CORPO_MOCK_MODE": "1"}):
            result = runner.invoke(cli, ["register", "--email", "test@example.com"])
            assert result.exit_code == 0
            out = json.loads(result.output)
            assert out["ok"] is True
            assert "account_id" in out["data"]
