from django.db import models
from datetime import date
from django.utils import timezone

class Bailleur(models.Model):
    """Modèle représentant un bailleur de fonds pour les projets de recherche."""
    nom_organisme = models.CharField(
        max_length=200, 
        unique=True
    )
    contact = models.CharField(
        max_length=100, 
        blank=True, 
        null=True
    )
    email = models.EmailField(
        blank=True, 
        null=True
    )
    pays = models.CharField(
        max_length=100, 
        blank=True, 
        null=True
    )
    
    def __str__(self):
        return self.nom_organisme
    
class DomaineDeRecherche(models.Model):
    """Modèle représentant les domaines de recherche"""

    DOMAINE_RECHERCHE = [
        ('sciences_sociales', 'Sciences sociales'),
        ('naturelles', 'Naturelles'),
        ('humaines', 'Humaines'),
        ('veterinaires', 'Vétérinaires')
    ]

    nom = models.CharField(
        max_length=100, 
        verbose_name="Domaine de recherche", 
        choices=DOMAINE_RECHERCHE,
        primary_key=True
    )

    class Meta:
        verbose_name = 'Domaine de recherche'
        verbose_name_plural = 'Domaines de recherche'

    def __str__(self):
        return self.nom
    
class Projet(models.Model):
    """Modèle représentant un projet de recherche avec ses caractéristiques et son bailleur associé."""
    TYPE_PROJET = [
        ('laboratoire', 'Laboratoire'),
        ('épidémiologie', 'Épidémiologie'),
        ('sciences sociales', 'Sciences sociales'),
        ('cliniques', 'Cliniques'),
        ('autre', 'Autre'),
    ]
    id_projet = models.CharField(
        max_length=100, 
        blank=True, 
        unique=True, 
        primary_key=True, 
        verbose_name="ID du projet"
    )
    nom_projet = models.CharField(
        max_length=200, 
        verbose_name="Nom du projet"
    )
    date_debut = models.DateField(
        verbose_name="Date de début"
     )
    date_fin = models.DateField(
        verbose_name="Date de fin"
    )
    numero_convention = models.CharField(
        max_length=100, 
        verbose_name="Numéro de convention"
    )
    description = models.TextField(
        verbose_name="Description"
    )
    type_projet = models.CharField(
        max_length=100,
        choices=TYPE_PROJET,
        default='épidémiologie',
        verbose_name="Type de projet"
    )
    domaine_recherche = models.ManyToManyField(DomaineDeRecherche)
    budget=models.DecimalField(
        max_digits=12,
        decimal_places=2, 
        verbose_name="Budget"
    )
    budget_RH = models.DecimalField(
        max_digits=12,
        decimal_places=2,
        verbose_name="Budget RH"
    )
    created_at = models.DateTimeField(auto_now_add=True)  
    bailleur = models.ForeignKey(
        Bailleur, 
        on_delete=models.SET_NULL, 
        null=True, 
        blank=True, 
        verbose_name="Bailleur de fonds"
    )

    @property
    def statut(self):
        if self.date_fin < date.today():
            return "Terminé"
        return "En cours"
    
    @property
    def avancement(self):
        aujourd_hui = date.today()
        if (self.date_debut and self.date_fin) and (self.date_debut < self.date_fin):
            duree_projet = (self.date_fin - self.date_debut).days
            temps_ecoule = (aujourd_hui - self.date_debut).days
            if duree_projet > 0:
                return round((temps_ecoule / duree_projet) * 100, 2)
            
        return 0
    
    def __str__(self):
        return f"{self.nom_projet}"

class FinancementProjet(models.Model):
    """
    Modèle représentant le financement d'un projet par un bailleur, 
    avec le pourcentage de contribution.
    """
    projet = models.ForeignKey(
        Projet, 
        on_delete=models.CASCADE
    )
    bailleur = models.ForeignKey(
        Bailleur, 
        on_delete=models.CASCADE
    )
    pourcentage = models.DecimalField(
        max_digits = 5, 
        decimal_places=2
    )

    class Meta:
        unique_together = ('projet', 'bailleur')

    def __str__(self):
        return f"{self.bailleur.nom} - {self.projet.nom_projet} ({self.pourcentage}%)"

class DocumentProjet(models.Model):
    """Modèle représentant un document associé à un projet, avec des métadonnées et un fichier attaché."""
    NOM_DOCUMENT_CHOICES = [
        ('protocole', 'Protocole d’étude'),
        ('ethique', "Approbation du comité d'éthique"),
        ('autorisation', 'Autorisation (DNLP)'),
        ('rapport_technique', 'Rapport technique'),
        ('rapport_financier', 'Rapport financier'),
        ('rapport_avancement', "Rapport d'avancement"),
        ('convention', 'Convention'),
        ('rapport_final', 'Rapport final'),
        ('autre', 'Autre'),
    ]

    projet = models.ForeignKey(
        Projet, 
        on_delete=models.CASCADE, 
        related_name='documents', 
        verbose_name="Projet"
    )
    date_ajout = models.DateTimeField(
        auto_now_add=True, 
        verbose_name="Date d'ajout"
    )
    nom_document = models.CharField(
        max_length = 100, 
        choices = NOM_DOCUMENT_CHOICES, 
        verbose_name="Type de document"
    )
    description = models.TextField(
        blank = True,
        verbose_name = "Description"
    )
    numero = models.CharField(
        max_length = 100, 
        blank = True, 
        null = True, 
        verbose_name = "Numéro du document"
    )
    date_validite = models.DateField(
        blank = True, 
        null = True, 
        verbose_name = "Date de validité"
    )
    fichier = models.FileField(
        upload_to = 'documents_projets/', 
        verbose_name = "Fichier à télécharger"
    )
    
    def __str__(self):
        return f"{self.nom_document} ({self.projet})"

class ActiviteProjet(models.Model):
    """Modèle représentant le planning d'un projet, avec des activités associées et un statut."""
    projet = models.ForeignKey(
        Projet, 
        on_delete = models.CASCADE, 
        verbose_name = "Projet"
    )
    titre = models.CharField(
        max_length = 200, 
        verbose_name = "Titre de l'activité"
    )
    description = models.TextField(
        blank = True, 
        null = True, 
        verbose_name = "Description de l'activité"
    )
    date_debut = models.DateField(verbose_name="Date de début")
    date_fin = models.DateField(verbose_name="Date de fin")
    annuler = models.BooleanField(
        default = False, 
        verbose_name = "Annuler l'activité"
    )
    motif_annulation = models.TextField(
        blank = True, 
        null = True, 
        verbose_name = "Motif d'annulation"
    )

    motif_changement_budget = models.TextField(
        blank = True,
        null = True,
        verbose_name = "Motif de changement de budget"
    )
    budget_prevu = models.DecimalField(
        max_digits = 15, 
        decimal_places = 2, 
        default = 0, 
        verbose_name = "Budget prévu"
    )
    budget_depense = models.DecimalField(
        max_digits = 15, 
        decimal_places = 2, 
        default = 0, 
        verbose_name = "Budget dépensé"
    )
    besoin_ressource_materielle = models.TextField(
        verbose_name="Besoin de ressources matérielles"
    )

    @property
    def statut(self):
        today = timezone.now().date()
        if not self.annuler:
            if self.date_fin < today:
                return 'Terminé'
            elif self.date_debut > today:
                return 'À venir'
            else:
                return 'En cours'
        else:
            return 'Annulé'
        
    def __str__(self):
        return f"{self.titre} ({self.projet.nom_projet})"
    
# class LivrableAttendu(models.Model):
#     """
#     Modèle représentant un livrable attendu pour une activité de projet, 
#     avec des critères de validation.
#     """
#     activite = models.ForeignKey(
#         ActiviteProjet, 
#         on_delete = models.CASCADE, 
#         related_name = "livrables_attendus"
#     )
#     nom = models.CharField(max_length=255)

#     def __str__(self):
#         return f"{self.nom} (Activité: {self.activite.titre})"

class LivrablesLivres(models.Model):
    """Modèle représentant un livrable livré pour une activité de projet."""
    activite = models.ForeignKey(
        ActiviteProjet, 
        on_delete = models.CASCADE
    )
        # nom = models.ForeignKey(
        #     LivrableAttendu,
        #     on_delete = models.CASCADE
        # )
    nom = models.CharField(
        max_length=255,
        verbose_name="Nom du livrable"
    ) 
    
    fichier = models.FileField(
        upload_to = 'fichier_livrables/',
        blank = True, 
        null = True
    )
    def __str__(self):
        return self.nom