"""
Tests de sécurité — GestionNotification
Vérifie :
  - Les notifications sont filtrées par utilisateur (plus d'accès global)
  - Authentification requise
"""

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, ProfileRole
from Establishment.models import Establishment
from GestionNotification.models import Notification


# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------

def create_user_with_role(email, name="Ecole Test"):
    user = Profile.objects.create_user(
        username=email, email=email, password="TestPass!123"
    )
    est = Establishment.objects.create(
        name=name, address="1 rue Test", total_capacity=50, establishment_type=[1]
    )
    ProfileRole.objects.create(
        profile=user, role_type=ProfileRole.RoleType.PROFIL_ECOLE,
        establishment=est, is_active=True
    )
    return user


OVERRIDE = dict(
    CACHES={'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'}},
    SESSION_ENGINE='django.contrib.sessions.backends.db',
)


# ---------------------------------------------------------------------------
# Tests
# ---------------------------------------------------------------------------

@override_settings(**OVERRIDE)
class NotificationAuthTest(TestCase):
    """Authentification requise sur l'endpoint notifications."""

    def setUp(self):
        self.client = APIClient()
        self.url = reverse('GestionNotification:notifications')

    def test_sans_auth_retourne_401(self):
        response = self.client.get(self.url)
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)


@override_settings(**OVERRIDE)
class NotificationFilterTest(TestCase):
    """
    Chaque utilisateur ne voit que ses propres notifications.
    Avant la correction, toutes les notifications étaient retournées
    à n'importe quel utilisateur authentifié (IDOR).
    """

    def setUp(self):
        self.client = APIClient()
        self.url = reverse('GestionNotification:notifications')
        self.alice = create_user_with_role('alice_notif@test.com', 'Ecole Alice')
        self.bob = create_user_with_role('bob_notif@test.com', 'Ecole Bob')

        # Créer une notification pour Alice et une pour Bob
        Notification.objects.create(
            user=self.alice, message='Message pour Alice', typeNotification=0
        )
        Notification.objects.create(
            user=self.bob, message='Message pour Bob', typeNotification=0
        )

    def test_alice_voit_uniquement_ses_notifications(self):
        """Alice ne doit voir que sa propre notification, pas celle de Bob."""
        token = str(RefreshToken.for_user(self.alice).access_token)
        self.client.credentials(HTTP_AUTHORIZATION=f'Bearer {token}')
        response = self.client.get(self.url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        data = response.json()
        self.assertEqual(len(data), 1, "Alice doit voir uniquement ses propres notifications")
        self.assertEqual(data[0]['message'], 'Message pour Alice')

    def test_bob_voit_uniquement_ses_notifications(self):
        """Bob ne doit voir que sa propre notification, pas celle d'Alice."""
        token = str(RefreshToken.for_user(self.bob).access_token)
        self.client.credentials(HTTP_AUTHORIZATION=f'Bearer {token}')
        response = self.client.get(self.url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        data = response.json()
        self.assertEqual(len(data), 1, "Bob doit voir uniquement ses propres notifications")
        self.assertEqual(data[0]['message'], 'Message pour Bob')

    def test_liste_globale_inaccessible(self):
        """
        Un utilisateur authentifié ne doit pas voir les notifs des autres.
        Vérification croisée : nombre de notifs retournées == 1.
        """
        carol = create_user_with_role('carol_notif@test.com', 'Ecole Carol')
        token = str(RefreshToken.for_user(carol).access_token)
        self.client.credentials(HTTP_AUTHORIZATION=f'Bearer {token}')
        response = self.client.get(self.url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        data = response.json()
        # Carol n'a aucune notification
        self.assertEqual(len(data), 0,
                         "Un utilisateur sans notification ne doit pas voir celles des autres (IDOR)")
