"""Tests for the quote and pay CLI commands."""

import json
from unittest.mock import patch, MagicMock

import pytest
from click.testing import CliRunner

from corpo.cli import cli


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


def test_quote_available(runner):
    """Test quote command with an available name."""
    mock_result = {
        "quote_id": "q-123",
        "entity_name": "Test LAO",
        "entity_type": "dao_llc",
        "name_available": True,
        "pricing": {
            "filing_fee": 10000,
            "service_fee": 5000,
            "registered_agent": 0,
            "total_cents": 15000,
            "total_display": "$150.00",
            "currency": "USD",
        },
        "status": "quoted",
    }

    with patch("corpo.cli.load_auth_config") as mock_cfg, \
         patch("corpo.cli.get_api_url", return_value="http://localhost:8080"), \
         patch("corpo.cli.get_api_key", return_value="test-key"), \
         patch("corpo.cli.get_client") as MockClient:
        mock_cfg.return_value = {}
        instance = MockClient.return_value
        instance.create_quote.return_value = mock_result

        result = runner.invoke(cli, ["quote", "Test LAO"])

    assert result.exit_code == 0
    assert "Test LAO" in result.output
    assert "available" in result.output.lower()
    assert "q-123" in result.output
    # JSON output at the end
    assert '"ok": true' in result.output or '"ok":true' in result.output


def test_quote_unavailable(runner):
    """Test quote command with an unavailable name."""
    mock_result = {
        "quote_id": "",
        "entity_name": "Taken LAO",
        "entity_type": "dao_llc",
        "name_available": False,
        "status": "name_unavailable",
    }

    with patch("corpo.cli.load_auth_config") as mock_cfg, \
         patch("corpo.cli.get_api_url", return_value="http://localhost:8080"), \
         patch("corpo.cli.get_api_key", return_value="test-key"), \
         patch("corpo.cli.get_client") as MockClient:
        mock_cfg.return_value = {}
        instance = MockClient.return_value
        instance.create_quote.return_value = mock_result

        result = runner.invoke(cli, ["quote", "Taken LAO"])

    assert result.exit_code == 0
    assert "unavailable" in result.output.lower()


def test_quote_no_api_key(runner):
    """Test quote command without API key configured."""
    with patch("corpo.cli.load_auth_config") as mock_cfg, \
         patch("corpo.cli.get_api_url", return_value="http://localhost:8080"), \
         patch("corpo.cli.get_api_key", return_value=""):
        mock_cfg.return_value = {}
        result = runner.invoke(cli, ["quote", "Test LAO"])

    assert result.exit_code == 1


def test_pay_command(runner):
    """Test pay command with a quote ID."""
    mock_result = {
        "quote_id": "q-123",
        "payment_id": "pay-456",
        "status": "submitted",
    }

    with patch("corpo.cli.load_auth_config") as mock_cfg, \
         patch("corpo.cli.get_api_url", return_value="http://localhost:8080"), \
         patch("corpo.cli.get_api_key", return_value="test-key"), \
         patch("corpo.cli.get_client") as MockClient:
        mock_cfg.return_value = {}
        instance = MockClient.return_value
        instance.pay_quote.return_value = mock_result

        result = runner.invoke(cli, ["pay", "--quote-id", "q-123"])

    assert result.exit_code == 0
    parsed = json.loads(result.output)
    assert parsed["ok"] is True
    assert parsed["data"]["payment_id"] == "pay-456"
