from django.views.generic import TemplateView, ListView, DetailView
from django.shortcuts import get_object_or_404
from apps.core.views import CMSPageMixin, CMSDetailView, CMSListView
from .models import (
    Program, ProgramHighlight, Semester, Specialization,
    AdmissionRequirement, ApplicationTimeline, Scholarship, FAQItem,
    ApplicationCall
)
from traduction.helpers import prefetch_translations


class TranslatedProgramMixin:
    """Mixin pour ajouter les traductions aux vues du programme"""

    def get_language_code(self):
        return getattr(self.request, 'current_language_code', 'fr')

    def translate_program_data(self, context):
        """Traduit les donnees communes du programme"""
        language_code = self.get_language_code()

        # Traduire le programme
        if context.get('program'):
            prefetch_translations([context['program']], language_code=language_code)

        # Traduire les highlights
        if context.get('highlights'):
            highlights = list(context['highlights'])
            prefetch_translations(highlights, language_code=language_code)
            context['highlights'] = highlights

        # Traduire les semestres et leurs cours
        if context.get('semesters'):
            semesters = list(context['semesters'])
            prefetch_translations(semesters, language_code=language_code)
            # Traduire les universites liees
            universities = [s.university for s in semesters if s.university]
            if universities:
                prefetch_translations(universities, language_code=language_code)
            context['semesters'] = semesters

        # Traduire les specialisations
        if context.get('specializations'):
            specializations = list(context['specializations'])
            prefetch_translations(specializations, language_code=language_code)
            context['specializations'] = specializations

        # Traduire les requirements
        if context.get('requirements'):
            requirements = list(context['requirements'])
            prefetch_translations(requirements, language_code=language_code)
            context['requirements'] = requirements

        # Traduire la timeline
        if context.get('timeline'):
            timeline = list(context['timeline'])
            prefetch_translations(timeline, language_code=language_code)
            context['timeline'] = timeline

        # Traduire les scholarships
        if context.get('scholarships'):
            scholarships = list(context['scholarships'])
            prefetch_translations(scholarships, language_code=language_code)
            context['scholarships'] = scholarships

        # Traduire les FAQs
        if context.get('faqs'):
            faqs = list(context['faqs'])
            prefetch_translations(faqs, language_code=language_code)
            context['faqs'] = faqs

        # Traduire les appels a candidature
        if context.get('current_call'):
            prefetch_translations([context['current_call']], language_code=language_code)

        if context.get('all_calls'):
            all_calls = list(context['all_calls'])
            prefetch_translations(all_calls, language_code=language_code)
            context['all_calls'] = all_calls

        return context


class ProgramView(TranslatedProgramMixin, CMSPageMixin, TemplateView):
    """
    Vue principale du programme.

    Utilise le template CMS si une page avec le slug 'programme' existe,
    sinon utilise le template par defaut.
    """
    template_name = 'program/about.html'
    cms_page_slug = 'programme'

    def get_context_data(self, **kwargs):
        # Charger la page CMS
        self._cms_page = self.get_cms_page()
        context = super().get_context_data(**kwargs)

        # Recuperer le programme principal (le premier)
        program = Program.objects.first()
        context['program'] = program

        if program:
            context['highlights'] = program.highlights.all()
            context['semesters'] = program.semesters.prefetch_related('courses', 'university').all()
            context['specializations'] = program.specializations.all()

        context['requirements'] = AdmissionRequirement.objects.filter(is_active=True)
        context['timeline'] = ApplicationTimeline.objects.all()[:6]
        context['scholarships'] = Scholarship.objects.filter(is_active=True)
        context['faqs'] = FAQItem.objects.filter(is_active=True)

        # Appliquer les traductions
        context = self.translate_program_data(context)

        # Grouper les FAQs par categorie
        faq_by_category = {}
        for faq in context['faqs']:
            cat = faq.get_category_display()
            if cat not in faq_by_category:
                faq_by_category[cat] = []
            faq_by_category[cat].append(faq)
        context['faq_by_category'] = faq_by_category

        return context


class ApplyView(TranslatedProgramMixin, CMSPageMixin, TemplateView):
    """Vue pour la page Comment postuler?"""
    template_name = 'program/apply.html'
    cms_page_slug = 'comment-postuler'

    def get_context_data(self, **kwargs):
        self._cms_page = self.get_cms_page()
        context = super().get_context_data(**kwargs)
        context['program'] = Program.objects.first()
        context['timeline'] = ApplicationTimeline.objects.all()
        context['requirements'] = AdmissionRequirement.objects.filter(is_active=True)
        context['faqs'] = FAQItem.objects.filter(
            is_active=True,
            category='admission'
        )

        # Appliquer les traductions
        context = self.translate_program_data(context)

        return context


class ScholarshipView(TranslatedProgramMixin, CMSPageMixin, TemplateView):
    """Vue pour la page La Bourse"""
    template_name = 'program/scholarship.html'
    cms_page_slug = 'la-bourse'

    def get_context_data(self, **kwargs):
        self._cms_page = self.get_cms_page()
        context = super().get_context_data(**kwargs)
        context['program'] = Program.objects.first()
        context['scholarships'] = Scholarship.objects.filter(is_active=True)
        context['faqs'] = FAQItem.objects.filter(
            is_active=True,
            category='financial'
        )

        # Appliquer les traductions
        context = self.translate_program_data(context)

        return context


class EligibilityView(TranslatedProgramMixin, CMSPageMixin, TemplateView):
    """Vue pour la page Criteres d'eligibilite"""
    template_name = 'program/eligibility.html'
    cms_page_slug = 'eligibilite'

    def get_context_data(self, **kwargs):
        self._cms_page = self.get_cms_page()
        context = super().get_context_data(**kwargs)
        context['program'] = Program.objects.first()
        context['requirements'] = AdmissionRequirement.objects.filter(is_active=True)
        context['faqs'] = FAQItem.objects.filter(
            is_active=True,
            category='admission'
        )

        # Appliquer les traductions
        context = self.translate_program_data(context)

        return context


class CallForApplicationsView(TranslatedProgramMixin, CMSPageMixin, TemplateView):
    """
    Vue pour la page Appel a candidature (liste/courant).

    Utilise le template CMS si une page 'call-for-application' existe.
    """
    template_name = 'program/call_for_applications.html'
    cms_page_slug = 'call-for-application'

    def get_context_data(self, **kwargs):
        self._cms_page = self.get_cms_page()
        context = super().get_context_data(**kwargs)

        # Recuperer l'appel courant ou specifique
        year = self.kwargs.get('year')
        if year:
            context['current_call'] = get_object_or_404(
                ApplicationCall,
                academic_year=year,
                is_active=True
            )
        else:
            context['current_call'] = ApplicationCall.get_current()

        # Tous les appels actifs pour l'historique
        context['all_calls'] = ApplicationCall.objects.filter(
            is_active=True
        ).order_by('-academic_year')

        # Programme et autres infos
        context['program'] = Program.objects.first()
        context['requirements'] = AdmissionRequirement.objects.filter(is_active=True)
        context['scholarships'] = Scholarship.objects.filter(is_active=True)[:3]

        # FAQs liees a l'admission
        context['faqs'] = FAQItem.objects.filter(
            is_active=True,
            category='admission'
        )

        # Appliquer les traductions
        context = self.translate_program_data(context)

        return context


class CallForApplicationsDetailView(TranslatedProgramMixin, CMSDetailView):
    """
    Vue detail pour un appel a candidature specifique.

    Utilise la Page CMS associee a l'instance ApplicationCall si disponible.
    Sinon, utilise le template par defaut 'program/call_for_applications.html'.

    L'objet ApplicationCall utilise CMSPageableMixin, donc chaque appel
    peut avoir sa propre page CMS avec des sections personnalisees.
    """
    model = ApplicationCall
    template_name = 'program/call_for_applications.html'
    context_object_name = 'current_call'
    slug_field = 'academic_year'
    slug_url_kwarg = 'year'

    # Active la creation auto de page CMS si elle n'existe pas
    cms_auto_create_page = False

    def get_queryset(self):
        return ApplicationCall.objects.filter(is_active=True).select_related('cms_page')

    def get_object(self, queryset=None):
        obj = super().get_object(queryset)
        return obj

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        language_code = self.get_language_code()

        # Ajouter les donnees supplementaires
        all_calls = list(ApplicationCall.objects.filter(is_active=True).order_by('-academic_year'))
        prefetch_translations(all_calls, language_code=language_code)
        context['all_calls'] = all_calls

        context['program'] = Program.objects.first()
        if context['program']:
            prefetch_translations([context['program']], language_code=language_code)

        requirements = list(AdmissionRequirement.objects.filter(is_active=True))
        prefetch_translations(requirements, language_code=language_code)
        context['requirements'] = requirements

        scholarships = list(Scholarship.objects.filter(is_active=True)[:3])
        prefetch_translations(scholarships, language_code=language_code)
        context['scholarships'] = scholarships

        faqs = list(FAQItem.objects.filter(is_active=True, category='admission'))
        prefetch_translations(faqs, language_code=language_code)
        context['faqs'] = faqs

        return context
