"""
Tests pour l'application Team
"""
from django.test import TestCase, Client
from django.urls import reverse

from .models import Person, Professor, PhDStudent, MasterStudent
from apps.universities.models import University
from apps.program.models import Specialization
from config.models import Country


class PersonModelTest(TestCase):
    """Tests pour le modèle Person"""

    def setUp(self):
        self.country = Country.objects.create(name="France", code="FR")
        self.university = University.objects.create(
            name="Test University",
            country=self.country,
            city="Paris",
            description="Test"
        )

    def test_person_creation(self):
        """Test création d'une personne"""
        person = Person.objects.create(
            first_name="Jean",
            last_name="Dupont",
            email="jean.dupont@test.com",
            university=self.university,
            person_type='professor',
            is_active=True
        )
        self.assertEqual(person.first_name, "Jean")
        self.assertEqual(person.last_name, "Dupont")

    def test_full_name(self):
        """Test de la propriété full_name"""
        person = Person.objects.create(
            first_name="Jean",
            last_name="Dupont",
            email="test@test.com",
            person_type='professor'
        )
        self.assertEqual(person.full_name, "Jean Dupont")

    def test_str_representation(self):
        """Test de la représentation string"""
        person = Person.objects.create(
            first_name="Jean",
            last_name="Dupont",
            email="test@test.com",
            person_type='professor'
        )
        self.assertEqual(str(person), "Jean Dupont")

    def test_slug_auto_generation(self):
        """Test génération automatique du slug"""
        person = Person.objects.create(
            first_name="Jean",
            last_name="Dupont",
            email="test@test.com",
            person_type='professor'
        )
        self.assertEqual(person.slug, "jean-dupont")

    def test_is_featured(self):
        """Test personne mise en avant"""
        person = Person.objects.create(
            first_name="Jean",
            last_name="Dupont",
            email="test@test.com",
            person_type='professor',
            is_featured=True
        )
        self.assertTrue(person.is_featured)


class ProfessorModelTest(TestCase):
    """Tests pour le modèle Professor"""

    def setUp(self):
        self.country = Country.objects.create(name="France", code="FR")
        self.university = University.objects.create(
            name="Test University",
            country=self.country,
            city="Paris",
            description="Test"
        )
        self.person = Person.objects.create(
            first_name="Marie",
            last_name="Martin",
            email="marie.martin@test.com",
            university=self.university,
            person_type='professor'
        )

    def test_professor_creation(self):
        """Test création d'un professeur"""
        professor = Professor.objects.create(
            person=self.person,
            title='prof',
            position="Full Professor",
            department="Computer Science"
        )
        self.assertEqual(professor.position, "Full Professor")
        self.assertEqual(professor.person.first_name, "Marie")

    def test_str_representation(self):
        """Test de la représentation string"""
        professor = Professor.objects.create(
            person=self.person,
            title='prof'
        )
        self.assertIn("Marie", str(professor))


class PhDStudentModelTest(TestCase):
    """Tests pour le modèle PhDStudent"""

    def setUp(self):
        self.country = Country.objects.create(name="Germany", code="DE")
        self.university = University.objects.create(
            name="Test University",
            country=self.country,
            city="Berlin",
            description="Test"
        )
        self.person = Person.objects.create(
            first_name="Hans",
            last_name="Mueller",
            email="hans.mueller@test.com",
            university=self.university,
            person_type='phd'
        )

    def test_phd_student_creation(self):
        """Test création d'un doctorant"""
        from datetime import date
        phd = PhDStudent.objects.create(
            person=self.person,
            thesis_title="Machine Learning for Climate Prediction",
            start_date=date(2022, 9, 1)
        )
        self.assertEqual(phd.start_date.year, 2022)
        self.assertIn("Machine Learning", phd.thesis_title)

    def test_str_representation(self):
        """Test de la représentation string"""
        from datetime import date
        phd = PhDStudent.objects.create(
            person=self.person,
            thesis_title="Test Thesis",
            start_date=date(2022, 9, 1)
        )
        self.assertIn("Hans", str(phd))


class MasterStudentModelTest(TestCase):
    """Tests pour le modèle MasterStudent"""

    def setUp(self):
        from apps.program.models import Program
        self.program = Program.objects.create(
            name="EUROMA",
            description="European Master"
        )
        self.country = Country.objects.create(name="Italy", code="IT")
        self.university = University.objects.create(
            name="Test University",
            country=self.country,
            city="Milan",
            description="Test"
        )
        self.person = Person.objects.create(
            first_name="Maria",
            last_name="Rossi",
            email="maria.rossi@test.com",
            university=self.university,
            person_type='master'
        )
        self.specialization = Specialization.objects.create(
            name="AI",
            description="Artificial Intelligence",
            program=self.program
        )

    def test_master_student_creation(self):
        """Test création d'un étudiant master"""
        master = MasterStudent.objects.create(
            person=self.person,
            cohort_year=2024,
            specialization=self.specialization
        )
        self.assertEqual(master.cohort_year, 2024)

    def test_str_representation(self):
        """Test de la représentation string"""
        master = MasterStudent.objects.create(
            person=self.person,
            cohort_year=2024
        )
        self.assertIn("Maria", str(master))


class TeamListViewTest(TestCase):
    """Tests pour la vue liste de l'équipe"""

    def setUp(self):
        self.client = Client()
        self.country = Country.objects.create(name="France", code="FR")
        self.university = University.objects.create(
            name="Test University",
            country=self.country,
            city="Paris",
            description="Test"
        )
        self.person = Person.objects.create(
            first_name="Test",
            last_name="Person",
            email="test@test.com",
            university=self.university,
            person_type='professor',
            is_active=True
        )
        Professor.objects.create(
            person=self.person,
            title='prof'
        )

    def test_list_view_status_code(self):
        """Test que la page liste retourne 200"""
        response = self.client.get(reverse('team:list'))
        self.assertEqual(response.status_code, 200)

    def test_list_view_template(self):
        """Test du template utilisé"""
        response = self.client.get(reverse('team:list'))
        self.assertTemplateUsed(response, 'team/list.html')

    def test_list_view_context(self):
        """Test du contexte de la vue"""
        response = self.client.get(reverse('team:list'))
        # Le contexte peut contenir professors, phd_students, master_students
        self.assertIn('professors', response.context)

    def test_inactive_members_not_shown(self):
        """Test que les membres inactifs ne sont pas affichés"""
        inactive_person = Person.objects.create(
            first_name="Inactive",
            last_name="Person",
            email="inactive@test.com",
            person_type='professor',
            is_active=False
        )
        Professor.objects.create(person=inactive_person, title='prof')

        response = self.client.get(reverse('team:list'))
        self.assertEqual(response.context['professors'].count(), 1)


class TeamDetailViewTest(TestCase):
    """Tests pour la vue détail d'un membre"""

    def setUp(self):
        self.client = Client()
        self.country = Country.objects.create(name="France", code="FR")
        self.university = University.objects.create(
            name="Test University",
            country=self.country,
            city="Paris",
            description="Test"
        )
        self.person = Person.objects.create(
            first_name="Test",
            last_name="Person",
            email="test@test.com",
            university=self.university,
            person_type='professor',
            is_active=True
        )

    def test_detail_view_status_code(self):
        """Test que la page détail retourne 200"""
        response = self.client.get(
            reverse('team:detail', kwargs={'slug': self.person.slug})
        )
        self.assertEqual(response.status_code, 200)

    def test_detail_view_template(self):
        """Test du template utilisé"""
        response = self.client.get(
            reverse('team:detail', kwargs={'slug': self.person.slug})
        )
        self.assertTemplateUsed(response, 'team/detail.html')

    def test_detail_view_404_for_inactive(self):
        """Test 404 pour membre inactif"""
        self.person.is_active = False
        self.person.save()
        response = self.client.get(
            reverse('team:detail', kwargs={'slug': self.person.slug})
        )
        self.assertEqual(response.status_code, 404)
