# Copyright (C) 2025 by Animath
# SPDX-License-Identifier: GPL-3.0-or-later

from citric import Client
from django.conf import settings
from django.db import models
from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _

from participation.models import Team, Tournament
from registration.models import ParticipantRegistration, StudentRegistration


class Survey(models.Model):
    """
    Ce modèle représente un sondage LimeSurvey afin de faciliter l'import des
    participant⋅es au sondage et d'effectuer le suivi.
    """
    survey_id = models.IntegerField(
        primary_key=True,
        verbose_name=_("survey identifier"),
        help_text=_("The numeric identifier of the Limesurvey."),
    )

    name = models.CharField(
        max_length=255,
        verbose_name=_("display name"),
    )

    invite_team = models.BooleanField(
        default=False,
        verbose_name=_("invite whole team"),
        help_text=_("When this field is checked, teams will get only one survey invitation instead of one per person."),
    )

    invite_coaches = models.BooleanField(
        default=True,
        verbose_name=_("invite coaches"),
        help_text=_("When this field is checked, coaches will also be invited in the survey. No effect when the whole team is invited."),
    )

    tournament = models.ForeignKey(
        Tournament,
        null=True,
        blank=True,
        default=None,
        on_delete=models.SET_NULL,
        related_name="surveys",
        verbose_name=_("tournament restriction"),
        help_text=_("When this field is filled, the survey participants will be restricted to this tournament members."),
    )

    completed_registrations = models.ManyToManyField(
        ParticipantRegistration,
        blank=True,
        related_name="completed_surveys",
        verbose_name=_("participants that completed the survey"),
    )

    completed_teams = models.ManyToManyField(
        Team,
        blank=True,
        related_name="completed_surveys",
        verbose_name=_("teams that completed the survey"),
    )

    @property
    def participants(self):
        if self.invite_team:
            teams = Team.objects.filter(participation__valid=True)
            if self.tournament:
                teams = teams.filter(participation__tournament=self.tournament)
            return teams.order_by('participation__tournament__name', 'trigram').all()
        else:
            if self.invite_coaches:
                registrations = ParticipantRegistration.objects.filter(team__participation__valid=True)
            else:
                registrations = StudentRegistration.objects.filter(team__participation__valid=True)
            if self.tournament:
                registrations = registrations.filter(team__participation__tournament=self.tournament)
            return registrations.order_by('team__participation__tournament__name', 'team__trigram').all()

    @property
    def completed(self):
        if self.invite_team:
            return self.completed_teams
        else:
            return self.completed_registrations

    def get_absolute_url(self):
        return reverse_lazy("survey:survey_detail", args=(self.survey_id,))

    def generate_participants_data(self):
        participants_data = []
        if self.invite_team:
            for team in self.participants:
                participant_data = {"firstname": team.name, "lastname": f"(équipe {team.trigram})", "email": team.email}
                participants_data.append(participant_data)
        else:
            for reg in self.participants:
                participant_data = {"firstname": reg.user.first_name, "lastname": reg.user.last_name, "email": reg.user.email}
                participants_data.append(participant_data)
        return participants_data

    def invite_all(self):
        participants_data = self.generate_participants_data()
        with Client(f"{settings.LIMESURVEY_URL}/index.php/admin/remotecontrol", settings.LIMESURVEY_USER, settings.LIMESURVEY_PASSWORD) as client:
            try:
                current_participants = client.list_participants(self.survey_id, limit=10000)
            except:
                current_participants = []
            current_participants_email = set(participant['participant_info']['email'] for participant in current_participants)
            participants_data = [participant_data for participant_data in participants_data if participant_data['email'] not in current_participants_email]
            try:
                client.activate_tokens(self.survey_id)
            except:
                pass
            new_participants = client.add_participants(self.survey_id, participant_data=participants_data)
            if new_participants:
                client.invite_participants(self.survey_id, token_ids=[participant['tid'] for participant in new_participants])
            return new_participants

    def fetch_completion_data(self):
        with Client(f"{settings.LIMESURVEY_URL}/index.php/admin/remotecontrol", settings.LIMESURVEY_USER, settings.LIMESURVEY_PASSWORD) as client:
            participants = client.list_participants(self.survey_id, limit=10000, attributes=['completed'])
        if self.invite_team:
            team_names = [participant['participant_info']['firstname'] for participant in participants if participant['completed'] != 'N']
            self.completed_teams.set(list(Team.objects.filter(name__in=team_names).values_list('id', flat=True)))
        else:
            mails = [participant['participant_info']['email'] for participant in participants if participant['completed'] != 'N']
            self.completed_registrations.set(list(ParticipantRegistration.objects.filter(user__email__in=mails).values_list('id', flat=True)))
        self.save()


    class Meta:
        verbose_name = _("survey")
        verbose_name_plural = _("surveys")
