"""Tests for Kawaa client."""

import pytest
from pytest_httpx import HTTPXMock

from kawaa import (
    Kawaa,
    VerificationStatus,
    JobStatus,
    AuthenticationError,
    RateLimitError,
    InsufficientCreditsError,
    ValidationError,
)


class TestKawaaClient:
    """Tests for sync Kawaa client."""

    def test_verify_single_email(self, httpx_mock: HTTPXMock):
        """Test single email verification."""
        httpx_mock.add_response(
            method="POST",
            url="https://api.kawaa.com/v1/verify",
            json={
                "email": "test@example.com",
                "status": "valid",
                "quality_score": 95,
                "flags": {
                    "disposable": False,
                    "role": False,
                    "free_provider": False,
                    "catch_all": False,
                },
            },
        )

        client = Kawaa("test-api-key")
        result = client.verify("test@example.com")

        assert result.email == "test@example.com"
        assert result.status == VerificationStatus.VALID
        assert result.score == 95
        assert result.is_valid is True
        assert result.flags.disposable is False

    def test_verify_with_suggestion(self, httpx_mock: HTTPXMock):
        """Test verification with AI suggestion."""
        httpx_mock.add_response(
            method="POST",
            url="https://api.kawaa.com/v1/verify",
            json={
                "email": "test@gmial.com",
                "status": "invalid",
                "quality_score": 0,
                "suggestion": "test@gmail.com",
                "flags": {},
            },
        )

        client = Kawaa("test-api-key")
        result = client.verify("test@gmial.com")

        assert result.status == VerificationStatus.INVALID
        assert result.suggestion == "test@gmail.com"

    def test_verify_disposable_email(self, httpx_mock: HTTPXMock):
        """Test verification of disposable email."""
        httpx_mock.add_response(
            method="POST",
            url="https://api.kawaa.com/v1/verify",
            json={
                "email": "test@mailinator.com",
                "status": "risky",
                "quality_score": 30,
                "flags": {
                    "disposable": True,
                    "role": False,
                    "free_provider": False,
                    "catch_all": False,
                },
            },
        )

        client = Kawaa("test-api-key")
        result = client.verify("test@mailinator.com")

        assert result.status == VerificationStatus.RISKY
        assert result.flags.disposable is True
        assert result.is_deliverable is False  # Score < 70

    def test_batch_verification(self, httpx_mock: HTTPXMock):
        """Test batch email verification."""
        httpx_mock.add_response(
            method="POST",
            url="https://api.kawaa.com/v1/verify/batch",
            json={
                "job_id": "job-123",
                "status": "processing",
                "total_submitted": 10,
                "duplicates_removed": 2,
                "unique_emails": 8,
                "credits_used": 8,
                "credits_remaining": 92,
            },
        )

        client = Kawaa("test-api-key")
        job = client.verify_batch(["a@example.com", "b@example.com"])

        assert job.job_id == "job-123"
        assert job.status == JobStatus.PROCESSING
        assert job.duplicates_removed == 2
        assert job.credits_used == 8

    def test_batch_with_webhook(self, httpx_mock: HTTPXMock):
        """Test batch verification with webhook."""
        httpx_mock.add_response(
            method="POST",
            url="https://api.kawaa.com/v1/verify/batch",
            json={
                "job_id": "job-456",
                "status": "processing",
                "total_submitted": 5,
                "duplicates_removed": 0,
                "unique_emails": 5,
                "credits_used": 5,
                "credits_remaining": 95,
            },
        )

        client = Kawaa("test-api-key")
        job = client.verify_batch(
            ["a@example.com"],
            webhook_url="https://example.com/webhook",
            webhook_secret="secret123",
        )

        assert job.job_id == "job-456"

        # Verify webhook params were sent
        request = httpx_mock.get_request()
        import json
        body = json.loads(request.content)
        assert body["webhook_url"] == "https://example.com/webhook"
        assert body["webhook_secret"] == "secret123"

    def test_get_job_status(self, httpx_mock: HTTPXMock):
        """Test getting job status."""
        httpx_mock.add_response(
            method="GET",
            url="https://api.kawaa.com/v1/jobs/job-123",
            json={
                "job_id": "job-123",
                "status": "completed",
                "total_emails": 10,
                "processed_emails": 10,
                "valid_count": 8,
                "invalid_count": 1,
                "risky_count": 1,
                "unknown_count": 0,
                "progress_percent": 100.0,
            },
        )

        client = Kawaa("test-api-key")
        status = client.get_job_status("job-123")

        assert status.job_id == "job-123"
        assert status.is_completed is True
        assert status.valid_count == 8
        assert status.progress_percent == 100.0

    def test_download_results_json(self, httpx_mock: HTTPXMock):
        """Test downloading results as JSON."""
        httpx_mock.add_response(
            method="GET",
            url="https://api.kawaa.com/v1/jobs/job-123/download",
            json={
                "job_id": "job-123",
                "result_count": 2,
                "results": [
                    {"email": "a@example.com", "status": "valid", "score": 95},
                    {"email": "b@example.com", "status": "invalid", "score": 0},
                ],
            },
        )

        client = Kawaa("test-api-key")
        results = client.download_results("job-123", format="json")

        assert results.result_count == 2
        assert len(results.results) == 2
        assert results.results[0].email == "a@example.com"

    def test_download_results_csv(self, httpx_mock: HTTPXMock):
        """Test downloading results as CSV."""
        csv_content = "email,status,score\na@example.com,valid,95\n"
        httpx_mock.add_response(
            method="GET",
            url="https://api.kawaa.com/v1/jobs/job-123/download",
            text=csv_content,
        )

        client = Kawaa("test-api-key")
        result = client.download_results("job-123", format="csv")

        assert result == csv_content

    def test_get_account(self, httpx_mock: HTTPXMock):
        """Test getting account info."""
        httpx_mock.add_response(
            method="GET",
            url="https://api.kawaa.com/v1/account",
            json={
                "user_id": "user-123",
                "email": "user@example.com",
                "plan": "professional",
                "credits_remaining": 1000,
                "credits_used": 500,
                "created_at": "2024-01-01T00:00:00Z",
            },
        )

        client = Kawaa("test-api-key")
        account = client.get_account()

        assert account.user_id == "user-123"
        assert account.credits_remaining == 1000
        assert account.plan == "professional"


class TestErrorHandling:
    """Tests for error handling."""

    def test_authentication_error(self, httpx_mock: HTTPXMock):
        """Test handling of authentication errors."""
        httpx_mock.add_response(
            method="POST",
            url="https://api.kawaa.com/v1/verify",
            status_code=401,
            json={"error": "Invalid API key"},
        )

        client = Kawaa("invalid-key")
        with pytest.raises(AuthenticationError) as exc_info:
            client.verify("test@example.com")

        assert "Invalid API key" in str(exc_info.value)
        assert exc_info.value.status_code == 401

    def test_rate_limit_error(self, httpx_mock: HTTPXMock):
        """Test handling of rate limit errors."""
        httpx_mock.add_response(
            method="POST",
            url="https://api.kawaa.com/v1/verify",
            status_code=429,
            json={"error": "Rate limit exceeded", "retry_after": 60},
        )

        client = Kawaa("test-api-key", max_retries=1)
        with pytest.raises(RateLimitError) as exc_info:
            client.verify("test@example.com")

        assert exc_info.value.retry_after == 60

    def test_insufficient_credits_error(self, httpx_mock: HTTPXMock):
        """Test handling of insufficient credits."""
        httpx_mock.add_response(
            method="POST",
            url="https://api.kawaa.com/v1/verify/batch",
            status_code=402,
            json={"error": "Insufficient credits"},
        )

        client = Kawaa("test-api-key")
        with pytest.raises(InsufficientCreditsError):
            client.verify_batch(["a@example.com"])

    def test_validation_error(self, httpx_mock: HTTPXMock):
        """Test handling of validation errors."""
        httpx_mock.add_response(
            method="POST",
            url="https://api.kawaa.com/v1/verify",
            status_code=422,
            json={"error": "Invalid email format"},
        )

        client = Kawaa("test-api-key")
        with pytest.raises(ValidationError) as exc_info:
            client.verify("invalid-email")

        assert "Invalid email format" in str(exc_info.value)


class TestRetryLogic:
    """Tests for retry logic."""

    def test_retry_on_server_error(self, httpx_mock: HTTPXMock):
        """Test retry on 5xx errors."""
        # First request fails, second succeeds
        httpx_mock.add_response(
            method="POST",
            url="https://api.kawaa.com/v1/verify",
            status_code=500,
            json={"error": "Internal server error"},
        )
        httpx_mock.add_response(
            method="POST",
            url="https://api.kawaa.com/v1/verify",
            json={
                "email": "test@example.com",
                "status": "valid",
                "score": 95,
                "flags": {},
            },
        )

        client = Kawaa("test-api-key", max_retries=2)
        result = client.verify("test@example.com")

        assert result.status == VerificationStatus.VALID
        assert len(httpx_mock.get_requests()) == 2


class TestContextManager:
    """Tests for context manager usage."""

    def test_context_manager(self, httpx_mock: HTTPXMock):
        """Test client as context manager."""
        httpx_mock.add_response(
            method="POST",
            url="https://api.kawaa.com/v1/verify",
            json={
                "email": "test@example.com",
                "status": "valid",
                "score": 95,
                "flags": {},
            },
        )

        with Kawaa("test-api-key") as client:
            result = client.verify("test@example.com")
            assert result.is_valid

        # Client should be closed
        assert client._client is None or client._client.is_closed
