"""Tests for ComplianceRAGClient."""

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

from compliance.services.rag_client import ComplianceRAGClient, RAGSearchResult


class TestComplianceRAGClient:
    """Tests for the RAG client proxy."""

    def setup_method(self):
        self.client = ComplianceRAGClient(base_url="http://test-sdk:8090")

    @pytest.mark.asyncio
    async def test_search_success(self):
        """Successful search returns parsed results."""
        mock_response = MagicMock()
        mock_response.status_code = 200
        mock_response.json.return_value = {
            "query": "DSGVO Art. 35",
            "results": [
                {
                    "text": "Art. 35 DSGVO regelt die Datenschutz-Folgenabschaetzung...",
                    "regulation_code": "eu_2016_679",
                    "regulation_name": "DSGVO",
                    "regulation_short": "DSGVO",
                    "category": "regulation",
                    "article": "Art. 35",
                    "paragraph": "",
                    "source_url": "https://example.com",
                    "score": 0.92,
                }
            ],
            "count": 1,
        }

        with patch("httpx.AsyncClient") as MockClient:
            mock_instance = AsyncMock()
            mock_instance.post.return_value = mock_response
            mock_instance.__aenter__ = AsyncMock(return_value=mock_instance)
            mock_instance.__aexit__ = AsyncMock(return_value=False)
            MockClient.return_value = mock_instance

            results = await self.client.search("DSGVO Art. 35", collection="bp_compliance_ce")

        assert len(results) == 1
        assert results[0].regulation_code == "eu_2016_679"
        assert results[0].score == 0.92
        assert "Art. 35" in results[0].text

    @pytest.mark.asyncio
    async def test_search_failure_returns_empty(self):
        """Network errors return empty list, never raise."""
        with patch("httpx.AsyncClient") as MockClient:
            mock_instance = AsyncMock()
            mock_instance.post.side_effect = Exception("Connection refused")
            mock_instance.__aenter__ = AsyncMock(return_value=mock_instance)
            mock_instance.__aexit__ = AsyncMock(return_value=False)
            MockClient.return_value = mock_instance

            results = await self.client.search("test query")

        assert results == []

    @pytest.mark.asyncio
    async def test_search_http_error_returns_empty(self):
        """HTTP errors return empty list."""
        mock_response = MagicMock()
        mock_response.status_code = 500
        mock_response.text = "Internal Server Error"

        with patch("httpx.AsyncClient") as MockClient:
            mock_instance = AsyncMock()
            mock_instance.post.return_value = mock_response
            mock_instance.__aenter__ = AsyncMock(return_value=mock_instance)
            mock_instance.__aexit__ = AsyncMock(return_value=False)
            MockClient.return_value = mock_instance

            results = await self.client.search("test query")

        assert results == []

    def test_format_for_prompt(self):
        """format_for_prompt produces Markdown output."""
        results = [
            RAGSearchResult(
                text="Die Verarbeitung personenbezogener Daten...",
                regulation_code="eu_2016_679",
                regulation_name="DSGVO",
                regulation_short="DSGVO",
                category="regulation",
                article="Art. 35",
                paragraph="",
                source_url="https://example.com",
                score=0.9,
            ),
            RAGSearchResult(
                text="Risikobewertung fuer KI-Systeme...",
                regulation_code="eu_2024_1689",
                regulation_name="AI Act",
                regulation_short="AI Act",
                category="regulation",
                article="",
                paragraph="",
                source_url="https://example.com",
                score=0.85,
            ),
        ]

        output = self.client.format_for_prompt(results)

        assert "## Relevanter Rechtskontext" in output
        assert "**DSGVO**" in output
        assert "Art. 35" in output
        assert "**AI Act**" in output

    def test_format_for_prompt_empty(self):
        """Empty results return empty string."""
        assert self.client.format_for_prompt([]) == ""

    def test_format_for_prompt_truncation(self):
        """Long text is truncated to 400 chars."""
        results = [
            RAGSearchResult(
                text="A" * 500,
                regulation_code="test",
                regulation_name="Test",
                regulation_short="Test",
                category="test",
                article="",
                paragraph="",
                source_url="",
                score=0.5,
            ),
        ]

        output = self.client.format_for_prompt(results)
        assert "..." in output


class TestCollectionMapping:
    """Tests for regulation → collection mapping in AIComplianceAssistant."""

    def test_eu_regulations_map_to_ce(self):
        from compliance.services.ai_compliance_assistant import AIComplianceAssistant
        assistant = AIComplianceAssistant.__new__(AIComplianceAssistant)

        assert assistant._collection_for_regulation("DSGVO") == "bp_compliance_ce"
        assert assistant._collection_for_regulation("GDPR") == "bp_compliance_ce"
        assert assistant._collection_for_regulation("AI_ACT") == "bp_compliance_ce"
        assert assistant._collection_for_regulation("NIS2") == "bp_compliance_ce"
        assert assistant._collection_for_regulation("CRA") == "bp_compliance_ce"

    def test_de_regulations_map_to_recht(self):
        from compliance.services.ai_compliance_assistant import AIComplianceAssistant
        assistant = AIComplianceAssistant.__new__(AIComplianceAssistant)

        assert assistant._collection_for_regulation("BDSG") == "bp_compliance_recht"
        assert assistant._collection_for_regulation("TDDDG") == "bp_compliance_recht"
        assert assistant._collection_for_regulation("TKG") == "bp_compliance_recht"

    def test_unknown_regulation_defaults_to_ce(self):
        from compliance.services.ai_compliance_assistant import AIComplianceAssistant
        assistant = AIComplianceAssistant.__new__(AIComplianceAssistant)

        assert assistant._collection_for_regulation("UNKNOWN") == "bp_compliance_ce"
        assert assistant._collection_for_regulation("") == "bp_compliance_ce"

    def test_case_insensitive(self):
        from compliance.services.ai_compliance_assistant import AIComplianceAssistant
        assistant = AIComplianceAssistant.__new__(AIComplianceAssistant)

        assert assistant._collection_for_regulation("dsgvo") == "bp_compliance_ce"
        assert assistant._collection_for_regulation("bdsg") == "bp_compliance_recht"
