"""
Tests unitaires pour le module GestionMessagerie.
Vérifie que les endpoints (conversations, messages, upload) requièrent une
authentification JWT.
"""

import json

from django.test import TestCase, override_settings
from django.urls import reverse
from rest_framework import status
from rest_framework.test import APIClient
from rest_framework_simplejwt.tokens import RefreshToken

from Auth.models import Profile


def create_user(email="messagerie_test@example.com", password="testpassword123"):
    return Profile.objects.create_user(username=email, email=email, password=password)


def get_jwt_token(user):
    refresh = RefreshToken.for_user(user)
    return str(refresh.access_token)


TEST_REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
}

TEST_CACHES = {'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'}}

OVERRIDE = dict(
    CACHES=TEST_CACHES,
    SESSION_ENGINE='django.contrib.sessions.backends.db',
    REST_FRAMEWORK=TEST_REST_FRAMEWORK,
    CHANNEL_LAYERS={'default': {'BACKEND': 'channels.layers.InMemoryChannelLayer'}},
)


@override_settings(**OVERRIDE)
class ConversationListEndpointAuthTest(TestCase):
    """Tests d'authentification sur les endpoints de conversation."""

    def setUp(self):
        self.client = APIClient()
        self.user = create_user()

    def test_get_conversations_par_user_sans_auth_retourne_401(self):
        """GET /GestionMessagerie/conversations/user/{id}/ sans token doit retourner 401."""
        url = reverse("GestionMessagerie:conversations_by_user", kwargs={"user_id": 1})
        response = self.client.get(url)
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

    def test_post_create_conversation_sans_auth_retourne_401(self):
        """POST /GestionMessagerie/create-conversation/ sans token doit retourner 401."""
        url = reverse("GestionMessagerie:create_conversation")
        response = self.client.post(
            url,
            data=json.dumps({"participants": [1, 2]}),
            content_type="application/json",
        )
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

    def test_post_send_message_sans_auth_retourne_401(self):
        """POST /GestionMessagerie/send-message/ sans token doit retourner 401."""
        url = reverse("GestionMessagerie:send_message")
        response = self.client.post(
            url,
            data=json.dumps({"content": "Bonjour"}),
            content_type="application/json",
        )
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

    def test_post_mark_as_read_sans_auth_retourne_401(self):
        """POST /GestionMessagerie/conversations/mark-as-read/ sans token doit retourner 401."""
        url = reverse("GestionMessagerie:mark_as_read")
        response = self.client.post(
            url,
            data=json.dumps({}),
            content_type="application/json",
        )
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

    def test_get_search_recipients_sans_auth_retourne_401(self):
        """GET /GestionMessagerie/search-recipients/ sans token doit retourner 401."""
        url = reverse("GestionMessagerie:search_recipients")
        response = self.client.get(url)
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

    def test_post_upload_file_sans_auth_retourne_401(self):
        """POST /GestionMessagerie/upload-file/ sans token doit retourner 401."""
        url = reverse("GestionMessagerie:upload_file")
        response = self.client.post(url)
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

    def test_delete_conversation_sans_auth_retourne_401(self):
        """DELETE /GestionMessagerie/conversations/{uuid}/ sans token doit retourner 401."""
        import uuid as uuid_lib
        conversation_id = uuid_lib.uuid4()
        url = reverse(
            "GestionMessagerie:delete_conversation",
            kwargs={"conversation_id": conversation_id},
        )
        response = self.client.delete(url)
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

    def test_get_conversation_messages_sans_auth_retourne_401(self):
        """GET /GestionMessagerie/conversations/{uuid}/messages/ sans token doit retourner 401."""
        import uuid as uuid_lib
        conversation_id = uuid_lib.uuid4()
        url = reverse(
            "GestionMessagerie:conversation_messages",
            kwargs={"conversation_id": conversation_id},
        )
        response = self.client.get(url)
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

    def test_get_conversations_avec_auth_retourne_non_403(self):
        """GET avec token valide ne doit pas retourner 401/403."""
        token = get_jwt_token(self.user)
        self.client.credentials(HTTP_AUTHORIZATION=f"Bearer {token}")
        url = reverse("GestionMessagerie:conversations_by_user", kwargs={"user_id": self.user.id})
        response = self.client.get(url)
        self.assertNotIn(response.status_code, [status.HTTP_401_UNAUTHORIZED, status.HTTP_403_FORBIDDEN])
