from django.views.generic import ListView, DetailView
from apps.core.views import CMSPageMixin, CMSObjectMixin
from traduction.helpers import prefetch_translations
from .models import ResearchArea, ResearchProject, Publication


class ResearchListView(CMSPageMixin, ListView):
    """
    Liste des projets de recherche.

    Utilise le template CMS si une page 'recherche' existe.
    """
    model = ResearchProject
    template_name = 'research/list.html'
    context_object_name = 'projects'
    cms_page_slug = 'recherche'

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

    def get_queryset(self):
        queryset = ResearchProject.objects.filter(is_active=True).select_related(
            'research_area', 'university'
        ).prefetch_related('team_members', 'keywords')

        # Filtrage par domaine
        area = self.request.GET.get('area')
        if area:
            queryset = queryset.filter(research_area__slug=area)

        # Filtrage par niveau
        level = self.request.GET.get('level')
        if level in ['master', 'phd', 'postdoc']:
            queryset = queryset.filter(level=level)

        # Filtrage par statut
        status = self.request.GET.get('status')
        if status in ['active', 'completed', 'proposed']:
            queryset = queryset.filter(status=status)

        return queryset

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

        # Ajouter la page CMS au contexte
        if self._cms_page:
            context['page'] = self._cms_page
            context['cms_page'] = self._cms_page

        # Traduire les projets
        projects = list(self.get_queryset())
        prefetch_translations(projects, language_code=language_code)

        # Traduire les objets lies (research_area, university)
        research_areas_to_translate = [p.research_area for p in projects if p.research_area]
        universities_to_translate = [p.university for p in projects if p.university]

        if research_areas_to_translate:
            unique_areas = list({a.pk: a for a in research_areas_to_translate}.values())
            prefetch_translations(unique_areas, language_code=language_code)
            area_map = {a.pk: a for a in unique_areas}
            for project in projects:
                if project.research_area and project.research_area.pk in area_map:
                    project.research_area = area_map[project.research_area.pk]

        if universities_to_translate:
            unique_unis = list({u.pk: u for u in universities_to_translate}.values())
            prefetch_translations(unique_unis, language_code=language_code)
            uni_map = {u.pk: u for u in unique_unis}
            for project in projects:
                if project.university and project.university.pk in uni_map:
                    project.university = uni_map[project.university.pk]

        context['projects'] = projects

        # Domaines de recherche pour le filtre
        research_areas = list(ResearchArea.objects.filter(is_active=True))
        prefetch_translations(research_areas, language_code=language_code)
        context['research_areas'] = research_areas

        # Publications en vedette
        publications = list(Publication.objects.filter(is_active=True, is_featured=True)[:5])
        prefetch_translations(publications, language_code=language_code)
        context['publications'] = publications

        # Filtres actifs
        context['current_area'] = self.request.GET.get('area', '')
        context['current_level'] = self.request.GET.get('level', '')
        context['current_status'] = self.request.GET.get('status', '')

        return context


class ResearchDetailView(CMSObjectMixin, DetailView):
    """
    Detail d'un projet de recherche.

    Utilise la Page CMS associee au projet si disponible.
    """
    model = ResearchProject
    template_name = 'research/detail.html'
    context_object_name = 'project'

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

    def get_queryset(self):
        return ResearchProject.objects.filter(is_active=True).select_related(
            'research_area', 'university', 'cms_page'
        ).prefetch_related('team_members', 'keywords', 'publications')

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

        # Traduire le projet
        prefetch_translations([obj], language_code=language_code)

        # Traduire les objets lies
        if obj.research_area:
            prefetch_translations([obj.research_area], language_code=language_code)
        if obj.university:
            prefetch_translations([obj.university], language_code=language_code)

        # Traduire les membres de l'equipe
        team_members = list(obj.team_members.all())
        if team_members:
            prefetch_translations(team_members, language_code=language_code)

        return obj

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

        # Projets similaires (meme domaine)
        related_projects = list(ResearchProject.objects.filter(
            research_area=self.object.research_area,
            is_active=True
        ).exclude(pk=self.object.pk)[:3])
        prefetch_translations(related_projects, language_code=language_code)
        context['related_projects'] = related_projects

        return context


class PublicationListView(CMSPageMixin, ListView):
    """
    Liste des publications.

    Utilise le template CMS si une page 'publications' existe.
    """
    model = Publication
    template_name = 'research/publications.html'
    context_object_name = 'publications'
    paginate_by = 20
    cms_page_slug = 'publications'

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

    def get_queryset(self):
        queryset = Publication.objects.filter(is_active=True).prefetch_related(
            'publication_authors__person', 'projects'
        )

        # Filtrage par type
        pub_type = self.request.GET.get('type')
        if pub_type:
            queryset = queryset.filter(publication_type=pub_type)

        # Filtrage par annee
        year = self.request.GET.get('year')
        if year:
            queryset = queryset.filter(publication_date__year=year)

        return queryset

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

        # Ajouter la page CMS au contexte
        if self._cms_page:
            context['page'] = self._cms_page
            context['cms_page'] = self._cms_page

        # Traduire les publications de la page courante
        page_obj = context.get('page_obj')
        if page_obj:
            publications = list(page_obj.object_list)
            prefetch_translations(publications, language_code=language_code)

        context['current_type'] = self.request.GET.get('type', '')
        context['current_year'] = self.request.GET.get('year', '')

        # Liste des annees disponibles
        years = Publication.objects.filter(is_active=True).dates('publication_date', 'year', order='DESC')
        context['years'] = [d.year for d in years]

        return context
