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

from .models import (
    Program, ProgramHighlight, Semester, Course,
    Specialization, AdmissionRequirement, Scholarship, FAQItem
)
from apps.universities.models import University
from config.models import Country


class ProgramModelTest(TestCase):
    """Tests pour le modèle Program"""

    def test_program_creation(self):
        """Test création d'un programme"""
        program = Program.objects.create(
            name="EUROMA",
            description="European Master Program",
            duration_months=24,
            ects_credits=120
        )
        self.assertEqual(program.name, "EUROMA")
        self.assertEqual(program.ects_credits, 120)

    def test_str_representation(self):
        """Test de la représentation string"""
        program = Program.objects.create(
            name="Test Program",
            description="Description"
        )
        self.assertEqual(str(program), "Test Program")


class SemesterModelTest(TestCase):
    """Tests pour le modèle Semester"""

    def setUp(self):
        self.program = Program.objects.create(
            name="EUROMA",
            description="European Master"
        )
        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_semester_creation(self):
        """Test création d'un semestre"""
        semester = Semester.objects.create(
            title="Semester 1",
            number=1,
            program=self.program,
            university=self.university,
            description="First semester"
        )
        self.assertEqual(semester.title, "Semester 1")
        self.assertEqual(semester.number, 1)

    def test_str_representation(self):
        """Test de la représentation string"""
        semester = Semester.objects.create(
            title="S1",
            number=1,
            program=self.program,
            university=self.university
        )
        self.assertIn("S1", str(semester))


class CourseModelTest(TestCase):
    """Tests pour le modèle Course"""

    def setUp(self):
        self.program = Program.objects.create(
            name="EUROMA",
            description="European Master"
        )
        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.semester = Semester.objects.create(
            title="S1",
            number=1,
            program=self.program,
            university=self.university
        )

    def test_course_creation(self):
        """Test création d'un cours"""
        course = Course.objects.create(
            code="ML101",
            title="Machine Learning",
            semester=self.semester,
            credits=6
        )
        self.assertEqual(course.title, "Machine Learning")
        self.assertEqual(course.credits, 6)

    def test_str_representation(self):
        """Test de la représentation string"""
        course = Course.objects.create(
            code="DL101",
            title="Deep Learning",
            semester=self.semester,
            credits=6
        )
        self.assertIn("Deep Learning", str(course))


class SpecializationModelTest(TestCase):
    """Tests pour le modèle Specialization"""

    def setUp(self):
        self.program = Program.objects.create(
            name="EUROMA",
            description="European Master"
        )

    def test_specialization_creation(self):
        """Test création d'une spécialisation"""
        spec = Specialization.objects.create(
            name="Artificial Intelligence",
            description="AI specialization",
            program=self.program
        )
        self.assertEqual(spec.name, "Artificial Intelligence")

    def test_str_representation(self):
        """Test de la représentation string"""
        spec = Specialization.objects.create(
            name="Data Science",
            description="Test",
            program=self.program
        )
        self.assertEqual(str(spec), "Data Science")


class AdmissionRequirementModelTest(TestCase):
    """Tests pour le modèle AdmissionRequirement"""

    def test_requirement_creation(self):
        """Test création d'une exigence d'admission"""
        req = AdmissionRequirement.objects.create(
            title="Bachelor's Degree",
            description="A Bachelor's degree in Computer Science or related field"
        )
        self.assertEqual(req.title, "Bachelor's Degree")

    def test_str_representation(self):
        """Test de la représentation string"""
        req = AdmissionRequirement.objects.create(
            title="Test Requirement",
            description="Description"
        )
        self.assertEqual(str(req), "Test Requirement")


class ScholarshipModelTest(TestCase):
    """Tests pour le modèle Scholarship"""

    def test_scholarship_creation(self):
        """Test création d'une bourse"""
        scholarship = Scholarship.objects.create(
            name="Erasmus Mundus Scholarship",
            description="Full scholarship covering tuition and living expenses",
            amount=1000,
            coverage_type="full",
            is_active=True
        )
        self.assertEqual(scholarship.name, "Erasmus Mundus Scholarship")
        self.assertEqual(scholarship.amount, 1000)

    def test_str_representation(self):
        """Test de la représentation string"""
        scholarship = Scholarship.objects.create(
            name="Test Scholarship",
            description="Test",
            coverage_type="full"
        )
        self.assertEqual(str(scholarship), "Test Scholarship")


class FAQItemModelTest(TestCase):
    """Tests pour le modèle FAQItem"""

    def test_faq_creation(self):
        """Test création d'une FAQ"""
        faq = FAQItem.objects.create(
            question="How do I apply?",
            answer="You can apply through our online portal."
        )
        self.assertEqual(faq.question, "How do I apply?")

    def test_str_representation(self):
        """Test de la représentation string"""
        faq = FAQItem.objects.create(
            question="Test Question?",
            answer="Answer"
        )
        self.assertEqual(str(faq), "Test Question?")

    def test_ordering(self):
        """Test de l'ordre des FAQs"""
        faq1 = FAQItem.objects.create(
            question="Q1",
            answer="A1",
            order=2
        )
        faq2 = FAQItem.objects.create(
            question="Q2",
            answer="A2",
            order=1
        )
        faqs = list(FAQItem.objects.all())
        self.assertEqual(faqs[0], faq2)


class ProgramViewsTest(TestCase):
    """Tests pour les vues du programme"""

    def setUp(self):
        self.client = Client()

    def test_about_view_status_code(self):
        """Test que la page about retourne 200"""
        response = self.client.get(reverse('program:about'))
        self.assertEqual(response.status_code, 200)

    def test_apply_view_status_code(self):
        """Test que la page apply retourne 200"""
        response = self.client.get(reverse('program:apply'))
        self.assertEqual(response.status_code, 200)

    def test_scholarship_view_status_code(self):
        """Test que la page scholarship retourne 200"""
        response = self.client.get(reverse('program:scholarship'))
        self.assertEqual(response.status_code, 200)

    def test_eligibility_view_status_code(self):
        """Test que la page eligibility retourne 200"""
        response = self.client.get(reverse('program:eligibility'))
        self.assertEqual(response.status_code, 200)
