"""
E2E API Integration Tests for ReceptionistAI.

Tests the FastAPI backend endpoints based on:
- /mnt/e/genesis-system/RECEPTIONISTAI/QUICK_START.md
- localhost:8000/docs (FastAPI auto-generated docs)
"""
import pytest
import requests
from playwright.sync_api import expect


class TestAPIHealth:
    """API health and availability tests."""

    def test_api_server_running(self, api_url):
        """Verify API server is accessible."""
        response = requests.get(f"{api_url}/v1/health", timeout=5)
        assert response.status_code == 200, "API health check failed"

    def test_health_endpoint_response(self, api_url):
        """Verify health endpoint returns valid JSON."""
        response = requests.get(f"{api_url}/v1/health", timeout=5)
        data = response.json()

        assert "status" in data, "Health response missing 'status' field"
        assert data["status"] in ["healthy", "ok"], f"Unexpected status: {data['status']}"

    def test_api_docs_available(self, api_url):
        """Verify OpenAPI docs are accessible."""
        response = requests.get(f"{api_url}/docs", timeout=5)
        assert response.status_code == 200, "API docs not accessible"


class TestConversationEndpoints:
    """Test conversation/chat endpoints."""

    def test_text_conversation_endpoint(self, api_url):
        """Test POST /v1/conversation/text endpoint."""
        payload = {
            "business_id": "bus_20260215092501_4ecb2567",
            "message": "What are your hours?",
            "session_id": "test_session_001"
        }

        headers = {
            "Content-Type": "application/json",
            "X-API-Key": "gw_live_GIZxDFqNWku4yCPuUpt9mhO8dVTr49tcPrLQdBVWWUXmVt0l4Iiwufpprb3Ju2uL"
        }

        response = requests.post(
            f"{api_url}/v1/conversation/text",
            json=payload,
            headers=headers,
            timeout=10
        )

        assert response.status_code in [200, 201], f"Unexpected status: {response.status_code}"

        # Check response structure
        data = response.json()
        assert "response" in data or "message" in data, "Response missing expected fields"

    def test_conversation_with_lead_data(self, api_url):
        """Test conversation with phone number (lead capture)."""
        payload = {
            "business_id": "bus_20260215092501_4ecb2567",
            "message": "My name is John, call me on 0412345678",
            "session_id": "test_session_002"
        }

        headers = {
            "Content-Type": "application/json",
            "X-API-Key": "gw_live_GIZxDFqNWku4yCPuUpt9mhO8dVTr49tcPrLQdBVWWUXmVt0l4Iiwufpprb3Ju2uL"
        }

        response = requests.post(
            f"{api_url}/v1/conversation/text",
            json=payload,
            headers=headers,
            timeout=10
        )

        assert response.status_code in [200, 201]

    def test_invalid_business_id(self, api_url):
        """Test API handles invalid business ID gracefully."""
        payload = {
            "business_id": "invalid_business_id",
            "message": "Test message",
            "session_id": "test_session_003"
        }

        headers = {
            "Content-Type": "application/json",
            "X-API-Key": "gw_live_GIZxDFqNWku4yCPuUpt9mhO8dVTr49tcPrLQdBVWWUXmVt0l4Iiwufpprb3Ju2uL"
        }

        response = requests.post(
            f"{api_url}/v1/conversation/text",
            json=payload,
            headers=headers,
            timeout=10
        )

        # Should return error (400, 404, or 422)
        assert response.status_code in [400, 404, 422], f"Expected error, got {response.status_code}"

    def test_missing_api_key(self, api_url):
        """Test API requires authentication."""
        payload = {
            "business_id": "bus_20260215092501_4ecb2567",
            "message": "Test message",
            "session_id": "test_session_004"
        }

        # No API key header
        response = requests.post(
            f"{api_url}/v1/conversation/text",
            json=payload,
            timeout=10
        )

        # Should return 401 Unauthorized or 403 Forbidden
        assert response.status_code in [401, 403, 422], f"Expected auth error, got {response.status_code}"


class TestCORSHeaders:
    """Test CORS configuration for widget integration."""

    def test_cors_headers_present(self, api_url):
        """Verify CORS headers are set correctly."""
        # Simulate preflight request
        headers = {
            "Origin": "http://localhost:8888",
            "Access-Control-Request-Method": "POST",
            "Access-Control-Request-Headers": "content-type,x-api-key"
        }

        response = requests.options(
            f"{api_url}/v1/conversation/text",
            headers=headers,
            timeout=5
        )

        # Check CORS headers
        assert "Access-Control-Allow-Origin" in response.headers, "CORS Allow-Origin header missing"
        assert response.headers.get("Access-Control-Allow-Methods"), "CORS Allow-Methods header missing"

    def test_cors_allows_widget_origin(self, api_url):
        """Verify widget origin is allowed."""
        headers = {
            "Origin": "http://localhost:8888"
        }

        response = requests.get(
            f"{api_url}/v1/health",
            headers=headers,
            timeout=5
        )

        allowed_origin = response.headers.get("Access-Control-Allow-Origin")
        assert allowed_origin in ["*", "http://localhost:8888"], f"Origin not allowed: {allowed_origin}"


class TestErrorHandling:
    """Test API error handling and validation."""

    def test_malformed_json(self, api_url):
        """Test API handles malformed JSON."""
        headers = {
            "Content-Type": "application/json",
            "X-API-Key": "gw_live_GIZxDFqNWku4yCPuUpt9mhO8dVTr49tcPrLQdBVWWUXmVt0l4Iiwufpprb3Ju2uL"
        }

        # Send invalid JSON
        response = requests.post(
            f"{api_url}/v1/conversation/text",
            data="invalid json {{{",
            headers=headers,
            timeout=5
        )

        assert response.status_code == 422, f"Expected 422, got {response.status_code}"

    def test_missing_required_fields(self, api_url):
        """Test API validates required fields."""
        payload = {
            # Missing business_id and message
            "session_id": "test_session_005"
        }

        headers = {
            "Content-Type": "application/json",
            "X-API-Key": "gw_live_GIZxDFqNWku4yCPuUpt9mhO8dVTr49tcPrLQdBVWWUXmVt0l4Iiwufpprb3Ju2uL"
        }

        response = requests.post(
            f"{api_url}/v1/conversation/text",
            json=payload,
            headers=headers,
            timeout=5
        )

        assert response.status_code == 422, "Should validate required fields"

    def test_empty_message(self, api_url):
        """Test API handles empty messages."""
        payload = {
            "business_id": "bus_20260215092501_4ecb2567",
            "message": "",
            "session_id": "test_session_006"
        }

        headers = {
            "Content-Type": "application/json",
            "X-API-Key": "gw_live_GIZxDFqNWku4yCPuUpt9mhO8dVTr49tcPrLQdBVWWUXmVt0l4Iiwufpprb3Ju2uL"
        }

        response = requests.post(
            f"{api_url}/v1/conversation/text",
            json=payload,
            headers=headers,
            timeout=5
        )

        # Should return validation error
        assert response.status_code in [400, 422], "Should reject empty message"


class TestAPIPerformance:
    """API response time and performance tests."""

    def test_health_check_fast(self, api_url):
        """Health check should respond quickly."""
        import time

        start_time = time.time()
        response = requests.get(f"{api_url}/v1/health", timeout=5)
        response_time = time.time() - start_time

        assert response.status_code == 200
        assert response_time < 1.0, f"Health check took {response_time:.2f}s (target: <1s)"

    def test_conversation_response_time(self, api_url):
        """Conversation endpoint should respond within reasonable time."""
        import time

        payload = {
            "business_id": "bus_20260215092501_4ecb2567",
            "message": "What are your hours?",
            "session_id": "test_session_perf"
        }

        headers = {
            "Content-Type": "application/json",
            "X-API-Key": "gw_live_GIZxDFqNWku4yCPuUpt9mhO8dVTr49tcPrLQdBVWWUXmVt0l4Iiwufpprb3Ju2uL"
        }

        start_time = time.time()
        response = requests.post(
            f"{api_url}/v1/conversation/text",
            json=payload,
            headers=headers,
            timeout=15
        )
        response_time = time.time() - start_time

        assert response.status_code in [200, 201]
        # AI response can take a few seconds, allow 10s
        assert response_time < 10.0, f"Response took {response_time:.2f}s (target: <10s)"


class TestRateLimiting:
    """Test rate limiting behavior (if implemented)."""

    @pytest.mark.skip(reason="Rate limiting may not be implemented yet")
    def test_rate_limit_enforcement(self, api_url):
        """Test that rate limiting is enforced."""
        # Send many requests rapidly
        headers = {
            "Content-Type": "application/json",
            "X-API-Key": "gw_live_GIZxDFqNWku4yCPuUpt9mhO8dVTr49tcPrLQdBVWWUXmVt0l4Iiwufpprb3Ju2uL"
        }

        payload = {
            "business_id": "bus_20260215092501_4ecb2567",
            "message": "Test",
            "session_id": "test_rate_limit"
        }

        # Send 100 requests
        responses = []
        for i in range(100):
            resp = requests.post(
                f"{api_url}/v1/conversation/text",
                json=payload,
                headers=headers,
                timeout=5
            )
            responses.append(resp.status_code)

        # Should have some 429 (Too Many Requests) responses
        assert 429 in responses, "Rate limiting not enforced"


class TestSessionManagement:
    """Test session handling and persistence."""

    def test_same_session_continuity(self, api_url):
        """Test messages in same session maintain context."""
        session_id = "test_session_continuity"

        headers = {
            "Content-Type": "application/json",
            "X-API-Key": "gw_live_GIZxDFqNWku4yCPuUpt9mhO8dVTr49tcPrLQdBVWWUXmVt0l4Iiwufpprb3Ju2uL"
        }

        # First message
        payload1 = {
            "business_id": "bus_20260215092501_4ecb2567",
            "message": "My name is Alice",
            "session_id": session_id
        }

        response1 = requests.post(
            f"{api_url}/v1/conversation/text",
            json=payload1,
            headers=headers,
            timeout=10
        )

        assert response1.status_code in [200, 201]

        # Second message in same session
        payload2 = {
            "business_id": "bus_20260215092501_4ecb2567",
            "message": "What was my name again?",
            "session_id": session_id
        }

        response2 = requests.post(
            f"{api_url}/v1/conversation/text",
            json=payload2,
            headers=headers,
            timeout=10
        )

        assert response2.status_code in [200, 201]

        # Response should reference "Alice" if context is maintained
        # This is a behavioral test, exact implementation may vary
