"""Testes unitários para as tools MCP do server.py.

Valida: Requisitos 1.3, 1.4, 2.4, 2.5, 3.2, 3.3, 8.2, 8.3
"""

import logging
from unittest.mock import AsyncMock, MagicMock, patch

import pytest
from mcp.shared.exceptions import McpError

from pack_mcp_google_chat_notification.server import send_message, send_card, send_thread_message


VALID_WEBHOOK = "https://chat.googleapis.com/v1/spaces/test/messages?key=k&token=t"


# --- send_message edge cases (Requisitos 1.3, 1.4) ---


class TestSendMessage:
    """Testes unitários para a tool send_message."""

    async def test_empty_text_raises_error(self):
        """Texto vazio deve retornar McpError. Valida: Requisito 1.3"""
        with pytest.raises(McpError, match="O texto da mensagem é obrigatório"):
            await send_message(text="", webhook_url=VALID_WEBHOOK)

    async def test_no_webhook_raises_error(self):
        """Sem webhook configurado deve retornar McpError. Valida: Requisito 1.4"""
        with pytest.raises(McpError, match="Nenhum webhook configurado"):
            await send_message(text="hello")

    async def test_success_with_valid_params(self):
        """Envio com parâmetros válidos deve retornar sucesso."""
        mock_client = MagicMock()
        mock_client.resolve_webhook_url.return_value = VALID_WEBHOOK
        mock_client.validate_webhook_url.return_value = None
        mock_client.post = AsyncMock(return_value={"name": "spaces/test/messages/123"})

        with patch("pack_mcp_google_chat_notification.server.get_client", return_value=mock_client):
            result = await send_message(text="hello", webhook_url=VALID_WEBHOOK)

        assert result == {"success": True}
        mock_client.post.assert_awaited_once()


# --- send_card edge cases (Requisitos 2.4, 2.5) ---


class TestSendCard:
    """Testes unitários para a tool send_card."""

    async def test_empty_title_raises_error(self):
        """Título vazio deve retornar McpError. Valida: Requisito 2.4"""
        with pytest.raises(McpError, match="O título do card é obrigatório"):
            await send_card(title="", sections=[{"widgets": []}], webhook_url=VALID_WEBHOOK)

    async def test_empty_sections_raises_error(self):
        """Sections vazia deve retornar McpError. Valida: Requisito 2.5"""
        with pytest.raises(McpError, match="Pelo menos uma seção é obrigatória"):
            await send_card(title="Title", sections=[], webhook_url=VALID_WEBHOOK)

    async def test_success_with_valid_params(self):
        """Envio com parâmetros válidos deve retornar sucesso."""
        mock_client = MagicMock()
        mock_client.resolve_webhook_url.return_value = VALID_WEBHOOK
        mock_client.validate_webhook_url.return_value = None
        mock_client.post = AsyncMock(return_value={"name": "spaces/test/messages/123"})

        with patch("pack_mcp_google_chat_notification.server.get_client", return_value=mock_client):
            result = await send_card(
                title="Test Card",
                sections=[{"widgets": [{"textParagraph": {"text": "hello"}}]}],
                webhook_url=VALID_WEBHOOK,
            )

        assert result == {"success": True}
        mock_client.post.assert_awaited_once()


# --- send_thread_message edge cases (Requisitos 3.2, 3.3) ---


class TestSendThreadMessage:
    """Testes unitários para a tool send_thread_message."""

    async def test_empty_text_raises_error(self):
        """Texto vazio deve retornar McpError. Valida: Requisito 3.2"""
        with pytest.raises(McpError, match="O texto da mensagem é obrigatório"):
            await send_thread_message(text="", thread_key="thread-1", webhook_url=VALID_WEBHOOK)

    async def test_empty_thread_key_raises_error(self):
        """Thread key vazia deve retornar McpError. Valida: Requisito 3.3"""
        with pytest.raises(McpError, match="A chave da thread é obrigatória"):
            await send_thread_message(text="hello", thread_key="", webhook_url=VALID_WEBHOOK)

    async def test_no_webhook_raises_error(self):
        """Sem webhook configurado deve retornar McpError."""
        with pytest.raises(McpError, match="Nenhum webhook configurado"):
            await send_thread_message(text="hello", thread_key="thread-1")

    async def test_success_with_valid_params(self):
        """Envio com parâmetros válidos deve retornar sucesso com thread_key."""
        mock_client = MagicMock()
        mock_client.resolve_webhook_url.return_value = VALID_WEBHOOK
        mock_client.validate_webhook_url.return_value = None
        mock_client.post = AsyncMock(return_value={"name": "spaces/test/messages/123"})

        with patch("pack_mcp_google_chat_notification.server.get_client", return_value=mock_client):
            result = await send_thread_message(
                text="hello", thread_key="mr-123", webhook_url=VALID_WEBHOOK
            )

        assert result == {"success": True, "thread_key": "mr-123"}
        mock_client.post.assert_awaited_once()
        # Verify thread params were passed
        call_kwargs = mock_client.post.call_args
        assert call_kwargs[1].get("params") or call_kwargs[0][2] if len(call_kwargs[0]) > 2 else call_kwargs[1].get("params")


# --- LOG_LEVEL configuration (Requisitos 8.2, 8.3) ---


class TestLogLevelConfiguration:
    """Testes para configuração de LOG_LEVEL via variável de ambiente."""

    def test_default_log_level_is_warning(self):
        """Sem LOG_LEVEL definido, o nível padrão deve ser WARNING. Valida: Requisito 8.3"""
        import importlib
        import pack_mcp_google_chat_notification.server as server_module

        # The conftest autouse fixture clears LOG_LEVEL, so reimporting gives us the default
        importlib.reload(server_module)
        assert server_module.log_level == "WARNING"

    def test_log_level_from_env_var(self, monkeypatch):
        """LOG_LEVEL definido via env var deve ser respeitado. Valida: Requisito 8.2"""
        import importlib
        import pack_mcp_google_chat_notification.server as server_module

        monkeypatch.setenv("LOG_LEVEL", "debug")
        importlib.reload(server_module)
        assert server_module.log_level == "DEBUG"
