from django.db import models
from colorfield.fields import ColorField
from traduction.helpers import TranslatableMixin
from cms.mixins import CMSPageableMixin


class Program(TranslatableMixin, models.Model):
    """Informations principales du programme master"""
    name = models.CharField('Nom du programme', max_length=200)
    full_name = models.CharField('Nom complet', max_length=300, blank=True)
    description = models.TextField('Description')
    tagline = models.CharField('Slogan', max_length=300, blank=True)

    duration_months = models.PositiveIntegerField('Duree (mois)', default=24)
    ects_credits = models.PositiveIntegerField('Credits ECTS', default=120)
    language = models.CharField('Langue', max_length=50, default='Anglais')
    degree_awarded = models.CharField('Diplome delivre', max_length=200, default='Master of Science')

    objectives = models.TextField('Objectifs du programme', blank=True)
    career_prospects = models.TextField('Debouches professionnels', blank=True)

    class Meta:
        verbose_name = 'Programme'
        verbose_name_plural = 'Programmes'

    def __str__(self):
        return self.get_translated('name') or self.name


class ProgramHighlight(TranslatableMixin, models.Model):
    """Points forts du programme"""
    program = models.ForeignKey(
        Program,
        on_delete=models.CASCADE,
        related_name='highlights',
        verbose_name='Programme'
    )
    title = models.CharField('Titre', max_length=100)
    description = models.TextField('Description')
    icon = models.CharField('Icone', max_length=50, blank=True)
    order = models.PositiveIntegerField('Ordre', default=0)

    class Meta:
        verbose_name = 'Point fort'
        verbose_name_plural = 'Points forts'
        ordering = ['order']

    def __str__(self):
        return self.get_translated('title') or self.title


class Semester(TranslatableMixin, models.Model):
    """Semestres du cursus"""
    program = models.ForeignKey(
        Program,
        on_delete=models.CASCADE,
        related_name='semesters',
        verbose_name='Programme'
    )
    number = models.PositiveIntegerField('Numero')
    title = models.CharField('Titre', max_length=100)
    description = models.TextField('Description', blank=True)
    university = models.ForeignKey(
        'universities.University',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='semesters',
        verbose_name='Universite d\'accueil'
    )

    class Meta:
        verbose_name = 'Semestre'
        verbose_name_plural = 'Semestres'
        ordering = ['number']
        unique_together = ['program', 'number']

    def __str__(self):
        name = self.get_translated('name') or self.title
        return f"Semestre {self.number} - {name}"


class Course(TranslatableMixin, models.Model):
    """Cours par semestre"""
    semester = models.ForeignKey(
        Semester,
        on_delete=models.CASCADE,
        related_name='courses',
        verbose_name='Semestre'
    )
    code = models.CharField('Code', max_length=20)
    title = models.CharField('Titre', max_length=200)
    description = models.TextField('Description', blank=True)
    credits = models.PositiveIntegerField('Credits ECTS', default=6)
    is_mandatory = models.BooleanField('Obligatoire', default=True)
    order = models.PositiveIntegerField('Ordre', default=0)

    class Meta:
        verbose_name = 'Cours'
        verbose_name_plural = 'Cours'
        ordering = ['order', 'code']

    def __str__(self):
        name = self.get_translated('name') or self.title
        return f"{self.code} - {name}"


class Specialization(TranslatableMixin, models.Model):
    """Specialisations disponibles"""
    program = models.ForeignKey(
        Program,
        on_delete=models.CASCADE,
        related_name='specializations',
        verbose_name='Programme'
    )
    name = models.CharField('Nom', max_length=100)
    description = models.TextField('Description')
    icon = models.CharField('Icone', max_length=50, blank=True)
    color = ColorField('Couleur', default='#2563eb')
    order = models.PositiveIntegerField('Ordre', default=0)

    class Meta:
        verbose_name = 'Specialisation'
        verbose_name_plural = 'Specialisations'
        ordering = ['order']

    def __str__(self):
        return self.get_translated('name') or self.name


class AdmissionRequirement(TranslatableMixin, models.Model):
    """Conditions d'admission"""
    REQUIREMENT_TYPES = [
        ('education', 'Formation'),
        ('language', 'Langue'),
        ('documents', 'Documents'),
        ('other', 'Autre'),
    ]

    title = models.CharField('Titre', max_length=200)
    description = models.TextField('Description')
    requirement_type = models.CharField('Type', max_length=20, choices=REQUIREMENT_TYPES)
    icon = models.CharField('Icone', max_length=50, blank=True)
    order = models.PositiveIntegerField('Ordre', default=0)
    is_active = models.BooleanField('Actif', default=True)

    class Meta:
        verbose_name = 'Condition d\'admission'
        verbose_name_plural = 'Conditions d\'admission'
        ordering = ['order']

    def __str__(self):
        return self.get_translated('title') or self.title


class ApplicationCall(CMSPageableMixin, TranslatableMixin, models.Model):
    """
    Appel a candidature pour une annee academique.

    Chaque appel peut avoir sa propre Page CMS pour personnaliser
    le template et les sections affichees.
    """
    STATUS_CHOICES = [
        ('upcoming', 'A venir'),
        ('open', 'Ouvert'),
        ('closed', 'Cloture'),
        ('results', 'Resultats publies'),
    ]

    title = models.CharField('Titre', max_length=200)
    academic_year = models.CharField(
        'Annee academique',
        max_length=9,
        help_text='Ex: 2025-2026',
        unique=True
    )
    description = models.TextField('Description', blank=True)
    status = models.CharField(
        'Statut',
        max_length=20,
        choices=STATUS_CHOICES,
        default='upcoming'
    )

    # Dates cles
    opening_date = models.DateField('Date d\'ouverture')
    deadline_date = models.DateField('Date limite de candidature')
    results_date = models.DateField('Date des resultats', blank=True, null=True)
    start_date = models.DateField('Date de rentree', blank=True, null=True)

    # Informations de candidature
    application_url = models.URLField('Lien de candidature', blank=True)
    application_email = models.EmailField('Email de contact', blank=True)
    places_available = models.PositiveIntegerField('Nombre de places', blank=True, null=True)
    scholarships_available = models.PositiveIntegerField('Bourses disponibles', blank=True, null=True)

    # Documents requis
    documents_required = models.TextField(
        'Documents requis',
        blank=True,
        help_text='Liste des documents (un par ligne)'
    )

    # Informations supplementaires
    additional_info = models.TextField('Informations complementaires', blank=True)

    is_active = models.BooleanField('Actif', default=True)
    is_featured = models.BooleanField('Mis en avant', default=False)
    created_at = models.DateTimeField('Cree le', auto_now_add=True)
    updated_at = models.DateTimeField('Modifie le', auto_now=True)

    # Configuration CMS
    CMS_PAGE_PREFIX = 'appel-candidature'

    class Meta:
        verbose_name = 'Appel a candidature'
        verbose_name_plural = 'Appels a candidature'
        ordering = ['-academic_year']

    def __str__(self):
        return f"Appel {self.academic_year} - {self.get_status_display()}"

    def get_cms_page_slug(self):
        """
        Genere le slug unique pour la page CMS de cet appel.
        Utilise le format: appel-candidature-2024-2025
        """
        from django.utils.text import slugify
        return f"{self.CMS_PAGE_PREFIX}-{slugify(self.academic_year)}"

    def get_cms_page_identifier(self):
        """Utilise l'annee academique comme identifiant unique."""
        return self.academic_year

    def get_cms_page_title(self):
        """Retourne le titre de la page CMS."""
        return f"Appel a candidature {self.academic_year}"

    def get_cms_page_name(self):
        """Retourne le nom interne de la page CMS."""
        return f"Appel {self.academic_year}"

    @property
    def is_open(self):
        """Verifie si l'appel est actuellement ouvert"""
        from django.utils import timezone
        today = timezone.now().date()
        return self.opening_date <= today <= self.deadline_date

    @property
    def days_remaining(self):
        """Nombre de jours restants avant la cloture"""
        from django.utils import timezone
        if not self.is_open:
            return 0
        delta = self.deadline_date - timezone.now().date()
        return max(0, delta.days)

    @property
    def status_color(self):
        """Couleur associee au statut"""
        colors = {
            'upcoming': '#3B82F6',  # Bleu
            'open': '#10B981',      # Vert
            'closed': '#6B7280',    # Gris
            'results': '#F59E0B',   # Orange
        }
        return colors.get(self.status, '#6B7280')

    def get_documents_list(self):
        """Retourne la liste des documents requis"""
        if not self.documents_required:
            return []
        return [doc.strip() for doc in self.documents_required.split('\n') if doc.strip()]

    def get_timeline_events(self):
        """Retourne les evenements du chronogramme"""
        return self.timeline_events.all().order_by('event_date')

    def duplicate(self, new_academic_year=None):
        """
        Cree une copie de cet appel a candidature avec toutes ses donnees liees.

        Args:
            new_academic_year: Nouvelle annee academique (ex: '2026-2027').
                              Si non fourni, genere automatiquement.

        Returns:
            La nouvelle instance ApplicationCall creee.
        """
        from datetime import date

        def add_one_year(d):
            """Ajoute un an a une date en gerant les annees bissextiles."""
            if d is None:
                return None
            try:
                return d.replace(year=d.year + 1)
            except ValueError:
                # 29 fevrier -> 28 fevrier l'annee suivante
                return d.replace(year=d.year + 1, day=28)

        # Generer l'annee academique si non fournie
        if not new_academic_year:
            # Extraire l'annee de debut et incrementer
            try:
                start_year = int(self.academic_year.split('-')[0])
                new_academic_year = f"{start_year + 1}-{start_year + 2}"
            except (ValueError, IndexError):
                new_academic_year = f"{self.academic_year}_copie"

        # Verifier que l'annee academique n'existe pas deja
        if ApplicationCall.objects.filter(academic_year=new_academic_year).exists():
            raise ValueError(f"Un appel pour l'annee {new_academic_year} existe deja.")

        # Creer la copie de l'appel
        new_call = ApplicationCall.objects.create(
            title=self.title.replace(self.academic_year, new_academic_year) if self.academic_year in self.title else f"{self.title} ({new_academic_year})",
            academic_year=new_academic_year,
            description=self.description,
            status='upcoming',  # Toujours commencer par 'A venir'
            opening_date=add_one_year(self.opening_date),
            deadline_date=add_one_year(self.deadline_date),
            results_date=add_one_year(self.results_date),
            start_date=add_one_year(self.start_date),
            application_url=self.application_url,
            application_email=self.application_email,
            places_available=self.places_available,
            scholarships_available=self.scholarships_available,
            documents_required=self.documents_required,
            additional_info=self.additional_info,
            is_active=False,  # Desactive par defaut pour revision
            is_featured=False,
        )

        # Copier les evenements du chronogramme
        for event in self.timeline_events.all():
            ApplicationTimeline.objects.create(
                application_call=new_call,
                title=event.title,
                description=event.description,
                event_date=add_one_year(event.event_date),
                event_type=event.event_type,
                academic_year=new_academic_year,
                icon=event.icon,
                is_completed=False,  # Reinitialiser
                order=event.order,
            )

        return new_call

    @classmethod
    def get_current(cls):
        """Retourne l'appel a candidature actuel (ouvert ou le plus recent)"""
        from django.utils import timezone
        today = timezone.now().date()

        # D'abord chercher un appel ouvert
        open_call = cls.objects.filter(
            is_active=True,
            opening_date__lte=today,
            deadline_date__gte=today
        ).first()

        if open_call:
            return open_call

        # Sinon, retourner l'appel mis en avant
        featured = cls.objects.filter(is_active=True, is_featured=True).first()
        if featured:
            return featured

        # Sinon, le plus recent
        return cls.objects.filter(is_active=True).first()


class ApplicationTimeline(TranslatableMixin, models.Model):
    """Calendrier des candidatures - etapes du chronogramme"""
    EVENT_TYPES = [
        ('open', 'Ouverture'),
        ('deadline', 'Date limite'),
        ('results', 'Resultats'),
        ('start', 'Rentree'),
        ('info', 'Information'),
        ('interview', 'Entretiens'),
    ]

    application_call = models.ForeignKey(
        ApplicationCall,
        on_delete=models.CASCADE,
        related_name='timeline_events',
        verbose_name='Appel a candidature',
        null=True,
        blank=True
    )
    title = models.CharField('Titre', max_length=200)
    description = models.TextField('Description', blank=True)
    event_date = models.DateField('Date')
    event_type = models.CharField('Type', max_length=20, choices=EVENT_TYPES)
    academic_year = models.CharField(
        'Annee academique',
        max_length=9,
        help_text='Ex: 2024-2025',
        blank=True
    )
    icon = models.CharField('Icone', max_length=50, blank=True, help_text='Classe Font Awesome')
    is_completed = models.BooleanField('Termine', default=False)
    order = models.PositiveIntegerField('Ordre', default=0)

    class Meta:
        verbose_name = 'Etape calendrier'
        verbose_name_plural = 'Calendrier candidatures'
        ordering = ['order', 'event_date']

    def __str__(self):
        return f"{self.title} - {self.event_date}"

    @property
    def is_past(self):
        """Verifie si l'evenement est passe"""
        from django.utils import timezone
        return self.event_date < timezone.now().date()

    @property
    def is_current(self):
        """Verifie si c'est l'evenement en cours (aujourd'hui)"""
        from django.utils import timezone
        return self.event_date == timezone.now().date()

    @property
    def event_icon(self):
        """Retourne l'icone par defaut selon le type"""
        if self.icon:
            return self.icon
        icons = {
            'open': 'fa-door-open',
            'deadline': 'fa-clock',
            'results': 'fa-trophy',
            'start': 'fa-graduation-cap',
            'info': 'fa-info-circle',
            'interview': 'fa-comments',
        }
        return icons.get(self.event_type, 'fa-calendar')


class Scholarship(TranslatableMixin, models.Model):
    """Bourses disponibles"""
    COVERAGE_TYPES = [
        ('full', 'Bourse complete'),
        ('tuition', 'Frais de scolarite'),
        ('partial', 'Partielle'),
        ('living', 'Frais de vie'),
    ]

    name = models.CharField('Nom', max_length=200)
    description = models.TextField('Description')
    amount = models.DecimalField('Montant (EUR)', max_digits=10, decimal_places=2, blank=True, null=True)
    coverage_type = models.CharField('Type de couverture', max_length=20, choices=COVERAGE_TYPES)
    requirements = models.TextField('Conditions', blank=True)
    funded_by = models.CharField('Finance par', max_length=200, blank=True)
    total_available = models.PositiveIntegerField('Nombre disponible', blank=True, null=True)
    application_url = models.URLField('Lien de candidature', blank=True)
    is_active = models.BooleanField('Active', default=True)
    order = models.PositiveIntegerField('Ordre', default=0)

    class Meta:
        verbose_name = 'Bourse'
        verbose_name_plural = 'Bourses'
        ordering = ['order']

    def __str__(self):
        return self.get_translated('name') or self.name


class FAQItem(TranslatableMixin, models.Model):
    """Questions frequentes"""
    CATEGORIES = [
        ('program', 'Programme'),
        ('admission', 'Admission'),
        ('mobility', 'Mobilite'),
        ('scholarships', 'Bourses'),
        ('housing', 'Logement'),
        ('career', 'Carrieres'),
        ('other', 'Autre'),
    ]

    question = models.CharField('Question', max_length=300)
    answer = models.TextField('Reponse')
    category = models.CharField('Categorie', max_length=20, choices=CATEGORIES)
    order = models.PositiveIntegerField('Ordre', default=0)
    is_active = models.BooleanField('Active', default=True)

    class Meta:
        verbose_name = 'FAQ'
        verbose_name_plural = 'FAQ'
        ordering = ['category', 'order']

    def __str__(self):
        question = self.get_translated('question') or self.question
        return question[:50]
