# tests/integration/api/v1/vendor/test_messages.py
"""
Integration tests for vendor messaging endpoints.

Tests the /api/v1/vendor/messages/* endpoints.
"""

import pytest

from app.modules.messaging.models import ConversationType, ParticipantType


@pytest.mark.integration
@pytest.mark.api
@pytest.mark.vendor
class TestVendorMessagesListAPI:
    """Tests for vendor message list endpoints."""

    def test_list_conversations_empty(self, client, vendor_user_headers):
        """Test listing conversations when none exist."""
        response = client.get("/api/v1/vendor/messages", headers=vendor_user_headers)

        assert response.status_code == 200
        data = response.json()
        assert "conversations" in data
        assert "total" in data
        assert "total_unread" in data
        assert data["total"] == 0

    def test_list_conversations_requires_auth(self, client):
        """Test that listing requires authentication."""
        response = client.get("/api/v1/vendor/messages")
        assert response.status_code == 401

    def test_list_conversations_requires_vendor(self, client, admin_headers):
        """Test that admin cannot use vendor endpoint."""
        response = client.get("/api/v1/vendor/messages", headers=admin_headers)
        # Admin doesn't have vendor context
        assert response.status_code == 403

    def test_list_conversations_with_data(
        self, client, vendor_user_headers, vendor_api_conversation
    ):
        """Test listing conversations with existing data."""
        response = client.get("/api/v1/vendor/messages", headers=vendor_user_headers)

        assert response.status_code == 200
        data = response.json()
        assert data["total"] >= 1

    def test_list_conversations_filter_by_type(
        self, client, vendor_user_headers, vendor_api_conversation
    ):
        """Test filtering conversations by type."""
        response = client.get(
            "/api/v1/vendor/messages",
            params={"conversation_type": "admin_vendor"},
            headers=vendor_user_headers,
        )

        assert response.status_code == 200
        data = response.json()
        for conv in data["conversations"]:
            assert conv["conversation_type"] == "admin_vendor"


@pytest.mark.integration
@pytest.mark.api
@pytest.mark.vendor
class TestVendorMessagesUnreadCountAPI:
    """Tests for unread count endpoint."""

    def test_get_unread_count(self, client, vendor_user_headers):
        """Test getting unread count."""
        response = client.get(
            "/api/v1/vendor/messages/unread-count", headers=vendor_user_headers
        )

        assert response.status_code == 200
        data = response.json()
        assert "total_unread" in data
        assert isinstance(data["total_unread"], int)


@pytest.mark.integration
@pytest.mark.api
@pytest.mark.vendor
class TestVendorMessagesRecipientsAPI:
    """Tests for recipients endpoint."""

    def test_get_customer_recipients(
        self, client, vendor_user_headers, test_customer
    ):
        """Test getting customer recipients."""
        response = client.get(
            "/api/v1/vendor/messages/recipients",
            params={"recipient_type": "customer"},
            headers=vendor_user_headers,
        )

        assert response.status_code == 200
        data = response.json()
        assert "recipients" in data
        assert "total" in data

    def test_get_recipients_requires_type(self, client, vendor_user_headers):
        """Test that recipient_type is required."""
        response = client.get(
            "/api/v1/vendor/messages/recipients", headers=vendor_user_headers
        )
        assert response.status_code == 422


@pytest.mark.integration
@pytest.mark.api
@pytest.mark.vendor
class TestVendorMessagesCreateAPI:
    """Tests for conversation creation."""

    def test_create_conversation_vendor_customer(
        self, client, vendor_user_headers, test_customer, test_vendor
    ):
        """Test creating vendor-customer conversation."""
        response = client.post(
            "/api/v1/vendor/messages",
            json={
                "conversation_type": "vendor_customer",
                "subject": "Customer Support",
                "recipient_type": "customer",
                "recipient_id": test_customer.id,
                "vendor_id": test_vendor.id,
                "initial_message": "Hello customer!",
            },
            headers=vendor_user_headers,
        )

        assert response.status_code == 200
        data = response.json()
        assert data["subject"] == "Customer Support"
        assert data["conversation_type"] == "vendor_customer"

    def test_create_conversation_admin_vendor_not_allowed(
        self, client, vendor_user_headers, test_admin, test_vendor
    ):
        """Test vendor cannot initiate admin_vendor conversation."""
        response = client.post(
            "/api/v1/vendor/messages",
            json={
                "conversation_type": "admin_vendor",
                "subject": "Question for Admin",
                "recipient_type": "admin",
                "recipient_id": test_admin.id,
                "vendor_id": test_vendor.id,
            },
            headers=vendor_user_headers,
        )

        assert response.status_code == 400


@pytest.mark.integration
@pytest.mark.api
@pytest.mark.vendor
class TestVendorMessagesDetailAPI:
    """Tests for conversation detail."""

    def test_get_conversation_detail(
        self, client, vendor_user_headers, vendor_api_conversation
    ):
        """Test getting conversation detail."""
        response = client.get(
            f"/api/v1/vendor/messages/{vendor_api_conversation.id}",
            headers=vendor_user_headers,
        )

        assert response.status_code == 200
        data = response.json()
        assert data["id"] == vendor_api_conversation.id
        assert "participants" in data
        assert "messages" in data

    def test_get_conversation_not_found(self, client, vendor_user_headers):
        """Test getting nonexistent conversation."""
        response = client.get(
            "/api/v1/vendor/messages/99999", headers=vendor_user_headers
        )
        assert response.status_code == 404


@pytest.mark.integration
@pytest.mark.api
@pytest.mark.vendor
class TestVendorMessagesSendAPI:
    """Tests for sending messages."""

    def test_send_message(
        self, client, vendor_user_headers, vendor_api_conversation
    ):
        """Test sending a message."""
        response = client.post(
            f"/api/v1/vendor/messages/{vendor_api_conversation.id}/messages",
            data={"content": "Reply from vendor"},
            headers=vendor_user_headers,
        )

        assert response.status_code == 200
        data = response.json()
        assert data["content"] == "Reply from vendor"
        assert data["sender_type"] == "vendor"

    def test_send_message_to_closed(
        self, client, vendor_user_headers, vendor_api_closed_conversation
    ):
        """Test cannot send to closed conversation."""
        response = client.post(
            f"/api/v1/vendor/messages/{vendor_api_closed_conversation.id}/messages",
            data={"content": "Test message"},
            headers=vendor_user_headers,
        )

        assert response.status_code == 400


@pytest.mark.integration
@pytest.mark.api
@pytest.mark.vendor
class TestVendorMessagesActionsAPI:
    """Tests for conversation actions."""

    def test_mark_read(
        self, client, vendor_user_headers, vendor_api_conversation
    ):
        """Test marking conversation as read."""
        response = client.put(
            f"/api/v1/vendor/messages/{vendor_api_conversation.id}/read",
            headers=vendor_user_headers,
        )

        assert response.status_code == 200
        data = response.json()
        assert data["success"] is True
        assert data["unread_count"] == 0

    def test_update_preferences(
        self, client, vendor_user_headers, vendor_api_conversation
    ):
        """Test updating notification preferences."""
        response = client.put(
            f"/api/v1/vendor/messages/{vendor_api_conversation.id}/preferences",
            json={"email_notifications": True, "muted": False},
            headers=vendor_user_headers,
        )

        assert response.status_code == 200
        data = response.json()
        assert data["success"] is True
