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


class ResearchArea(TranslatableMixin, models.Model):
    """Domaines de recherche"""
    name = models.CharField('Nom', max_length=100)
    slug = models.SlugField('Slug', max_length=100, unique=True, blank=True)
    description = models.TextField('Description')
    short_description = models.CharField('Description courte', max_length=300, blank=True)

    icon = models.CharField('Icone', max_length=50, blank=True)
    color = ColorField('Couleur', default='#2563eb')
    image = models.ImageField('Image', upload_to='research/areas/', blank=True, null=True)

    order = models.PositiveIntegerField('Ordre', default=0)
    is_active = models.BooleanField('Actif', default=True)

    class Meta:
        verbose_name = 'Domaine de recherche'
        verbose_name_plural = 'Domaines de recherche'
        ordering = ['order', 'name']

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

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name)
        super().save(*args, **kwargs)

    @property
    def project_count(self):
        return self.projects.filter(is_active=True).count()


class ResearchProject(CMSPageableMixin, TranslatableMixin, models.Model):
    """
    Projets de recherche.

    Chaque projet peut avoir sa propre Page CMS pour personnaliser
    le template et les sections affichees.
    """
    # Configuration CMS
    CMS_PAGE_PREFIX = 'projet-recherche'

    STATUS_CHOICES = [
        ('active', 'En cours'),
        ('completed', 'Termine'),
        ('proposed', 'Propose'),
    ]

    LEVEL_CHOICES = [
        ('master', 'Master'),
        ('phd', 'Doctorat'),
        ('postdoc', 'Post-doctorat'),
    ]

    title = models.CharField('Titre', max_length=255)
    slug = models.SlugField('Slug', max_length=255, unique=True, blank=True)
    description = models.TextField('Description')
    short_description = models.CharField('Description courte', max_length=400, blank=True)

    research_area = models.ForeignKey(
        ResearchArea,
        on_delete=models.SET_NULL,
        null=True,
        related_name='projects',
        verbose_name='Domaine'
    )

    level = models.CharField('Niveau', max_length=20, choices=LEVEL_CHOICES, default='master')
    status = models.CharField('Statut', max_length=20, choices=STATUS_CHOICES, default='active')

    university = models.ForeignKey(
        'universities.University',
        on_delete=models.SET_NULL,
        null=True,
        related_name='research_projects',
        verbose_name='Universite'
    )

    team_members = models.ManyToManyField(
        'team.Person',
        related_name='research_projects',
        verbose_name='Membres',
        blank=True
    )

    image = models.ImageField('Image', upload_to='research/projects/', blank=True, null=True)

    start_date = models.DateField('Date de debut', blank=True, null=True)
    end_date = models.DateField('Date de fin', blank=True, null=True)

    funding_amount = models.DecimalField('Financement (EUR)', max_digits=12, decimal_places=2, blank=True, null=True)
    funding_source = models.CharField('Source de financement', max_length=200, blank=True)

    external_url = models.URLField('Lien externe', blank=True)

    is_featured = models.BooleanField('Mis en avant', default=False)
    is_active = models.BooleanField('Actif', default=True)
    order = models.PositiveIntegerField('Ordre', default=0)

    created_at = models.DateTimeField('Cree le', auto_now_add=True)

    class Meta:
        verbose_name = 'Projet de recherche'
        verbose_name_plural = 'Projets de recherche'
        ordering = ['-is_featured', 'order', '-start_date']

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

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)[:300]
        super().save(*args, **kwargs)

    def get_cms_page_slug(self):
        """Genere le slug unique pour la page CMS de ce projet."""
        return f"{self.CMS_PAGE_PREFIX}-{self.slug}"

    def get_cms_page_identifier(self):
        """Utilise le slug du projet comme identifiant."""
        return self.slug

    def get_cms_page_title(self):
        """Retourne le titre de la page CMS."""
        return self.title

    def get_cms_page_name(self):
        """Retourne le nom interne de la page CMS."""
        return f"Projet: {self.title[:50]}"


class ResearchKeyword(models.Model):
    """Mots-cles pour les projets"""
    project = models.ForeignKey(
        ResearchProject,
        on_delete=models.CASCADE,
        related_name='keywords',
        verbose_name='Projet'
    )
    keyword = models.CharField('Mot-cle', max_length=50)
    order = models.PositiveIntegerField('Ordre', default=0)

    class Meta:
        verbose_name = 'Mot-cle'
        verbose_name_plural = 'Mots-cles'
        ordering = ['order']

    def __str__(self):
        return self.keyword


class Publication(TranslatableMixin, models.Model):
    """Publications scientifiques"""
    PUBLICATION_TYPES = [
        ('journal', 'Article de journal'),
        ('conference', 'Conference'),
        ('workshop', 'Workshop'),
        ('book_chapter', 'Chapitre de livre'),
        ('thesis', 'These'),
        ('report', 'Rapport'),
    ]

    title = models.CharField('Titre', max_length=500)
    abstract = models.TextField('Resume', blank=True)

    publication_type = models.CharField('Type', max_length=20, choices=PUBLICATION_TYPES)
    venue = models.CharField('Revue/Conference', max_length=300, blank=True)
    publication_date = models.DateField('Date de publication')

    authors = models.ManyToManyField(
        'team.Person',
        through='PublicationAuthor',
        related_name='publications',
        verbose_name='Auteurs'
    )
    external_authors = models.TextField('Auteurs externes', blank=True, help_text='Auteurs non membres du programme')

    projects = models.ManyToManyField(
        ResearchProject,
        related_name='publications',
        verbose_name='Projets associes',
        blank=True
    )

    doi = models.CharField('DOI', max_length=100, blank=True, unique=True, null=True)
    pdf_url = models.URLField('Lien PDF', blank=True)
    external_url = models.URLField('Lien externe', blank=True)

    is_peer_reviewed = models.BooleanField('Revu par les pairs', default=True)
    is_featured = models.BooleanField('Mis en avant', default=False)
    is_active = models.BooleanField('Actif', default=True)

    created_at = models.DateTimeField('Cree le', auto_now_add=True)

    class Meta:
        verbose_name = 'Publication'
        verbose_name_plural = 'Publications'
        ordering = ['-publication_date']

    def __str__(self):
        title = self.get_translated('title') or self.title
        return title[:100]

    def get_all_authors_display(self):
        internal = ', '.join([str(a.person) for a in self.publication_authors.all()])
        if self.external_authors:
            return f"{internal}, {self.external_authors}" if internal else self.external_authors
        return internal


class PublicationAuthor(models.Model):
    """Table intermediaire pour les auteurs de publications"""
    publication = models.ForeignKey(
        Publication,
        on_delete=models.CASCADE,
        related_name='publication_authors'
    )
    person = models.ForeignKey(
        'team.Person',
        on_delete=models.CASCADE,
        related_name='publication_authorships'
    )
    order = models.PositiveIntegerField('Ordre', default=0)
    is_corresponding = models.BooleanField('Auteur correspondant', default=False)

    class Meta:
        verbose_name = 'Auteur'
        verbose_name_plural = 'Auteurs'
        ordering = ['order']
        unique_together = ['publication', 'person']

    def __str__(self):
        return f"{self.person} - {self.publication.title[:50]}"
