from bulk_update_or_create import BulkUpdateOrCreateQuerySet
from django.db import models

from .administre import Administre
from .commun import NiveauFonctionnelChoices, SpecifiqueChoices
from .competence import Competence
from .domaine import Domaine
from .filiere import Filiere
from .fonction import Fonction
from .formation_emploi import FormationEmploi
from .sous_vivier import SousVivier
from .pam import PAM

class AvisPosteChoices(models.TextChoices):
    """
    [Poste] choix pour les avis
    attributs supplémentaires :
    - calc_enabled : est-ce que cet avis permet le calcul ?
    - dec_enabled  : est-ce que cet avis permet de créer une décision ?
    """

    #     (valeur, calc_enabled, dec_enabled), libellé
    P1         = ('P1',         True,  True),  'Priorité 1'
    P2         = ('P2',         True,  True),  'Priorité 2'
    P3         = ('P3',         True,  True),  'Priorité 3'
    P4         = ('P4',         True,  True),  'Priorité 4'
    GELE       = ('GELE',       False, False), 'Gelé'
    NON_ETUDIE = ('NON_ETUDIE', False, False), 'Non étudié'

    def __new__(cls, value):
        obj = str.__new__(cls, value[0])
        obj._value_ = value[0]
        obj.calc_enabled = value[1]
        obj.dec_enabled  = value[2]
        return obj


class DirectCommissionneChoices(models.TextChoices):
    """
    [Poste] choix pour direct/commissionné
    """

    DIRECT       = 'DIRECT',       'Direct'
    COMMISSIONNE = 'COMMISSIONNE', 'Commissionné'


class PropositionsArmementChoices(models.TextChoices):
    """
    [Poste] choix pour les propositions d'armement
    """

    PROPOSE = 'PROPOSE', 'Propositions'
    VALIDE  = 'VALIDE',  'Propositions validées'


class Poste(models.Model):
    """
    Modèle des postes
    """

    class Cols():
        """ Constantes pour les noms de colonnes """

        PK                   = 'p_id'
        CATEGORIE            = 'p_categorie'
        FONCTION             = 'p_code_fonction'
        NIVEAU_FONCTIONNEL   = 'p_nf'
        # relations many-to-many
        M2M_COMPETENCES      = 'competences'
        M2M_SOUS_VIVIERS     = 'sous_viviers'
        M2M_PAM              = 'p_pam'
        # relations one-to-many
        O2M_DECISION         = 'decisions'
        # relations one-to-one ou many-to-one
        REL_ADMINISTRE       = 'p_administre'
        REL_DOMAINE          = 'p_domaine'
        REL_FILIERE          = 'p_filiere'
        REL_FONCTION         = 'fonction'
        REL_FORMATION_EMPLOI = 'formation_emploi'


    objects = BulkUpdateOrCreateQuerySet.as_manager()

    p_id = models.CharField(max_length=100, primary_key=True)
    p_pam = models.ManyToManyField(PAM, through='Postes_Pams')
    p_annee = models.CharField(max_length=100, default=False)
    p_administre = models.ForeignKey(Administre, on_delete=models.SET_NULL, null=True, blank=True)
    fonction = models.ForeignKey(Fonction, on_delete=models.SET_NULL, null=True, blank=True)
    sous_viviers = models.ManyToManyField(SousVivier, related_name=SousVivier.Cols.M2M_POSTES, blank=True)
    formation_emploi = models.ForeignKey(FormationEmploi, on_delete=models.SET_NULL, related_name=FormationEmploi.Cols.REL_POSTE, null=True, blank=True)
    competences = models.ManyToManyField(Competence, blank=True)
    p_domaine = models.ForeignKey(Domaine, on_delete=models.SET_NULL, null=True, blank=True)
    p_filiere = models.ForeignKey(Filiere, on_delete=models.SET_NULL, null=True, blank=True)
    p_fonction = models.CharField(max_length=100, null=True, blank=True)
    p_code_fonction = models.CharField(max_length=100, null=True, blank=True)
    p_nf = models.CharField(max_length=100, null=True, blank=True, choices=NiveauFonctionnelChoices.choices)
    p_categorie = models.CharField(max_length=100, null=True, blank=True)
    p_dep = models.CharField('Département', max_length=2, null=True, blank=True)
    p_liste_id_marques = models.CharField('Marques PAM en cours', max_length=100, null=True, blank=True)
    p_eip = models.CharField(max_length=100, null=True, blank=True)
    p_avis = models.CharField(max_length=100, choices=AvisPosteChoices.choices, null=True, default=AvisPosteChoices.NON_ETUDIE)
    p_avis_fe = models.CharField(max_length=100, choices=AvisPosteChoices.choices, null=True, default=AvisPosteChoices.NON_ETUDIE)
    p_notes_gestionnaire = models.TextField(null=True, blank=True)
    p_notes_partagees = models.TextField(null=True, blank=True)
    p_ciat = models.BooleanField('CIAT', default=False, null=True)
    p_specifique = models.CharField('PPE / SHM / ITD', max_length=250, choices=SpecifiqueChoices.choices, null=True, blank=True)
    p_direct_commissionne = models.CharField('Direct Commissionne', max_length=100, choices=DirectCommissionneChoices.choices, null=True, blank=True)
    propositions_armement = models.CharField("propositions d'armement", db_column='p_propositions_armement', max_length=10, choices=PropositionsArmementChoices.choices, null=True, blank=True)
    p_priorisation_pcp = models.TextField('Priorisation PCP', null=True, blank=True)
    p_nfs = models.CharField('Domaine de gestion (BVT)', max_length=100, null=True, blank=True)
    p_itd_cellule = models.CharField(max_length=100, null=True, blank=True)
    p_itd_affecte = models.BooleanField(null=True, blank=True)


    @property
    def p_poids_competences(self):
        "le poids des competences"
        if self.p_specifique:
            return 65 if self.competences.exists() else 0
        else:
            return 60 if self.competences.exists() else 0

    @property
    def p_poids_filiere(self):
        "le poids des filieres"
        if self.p_specifique:
            return 0 if self.competences.exists() else 20
        else:
            return 10 if self.competences.exists() else 75


    @property
    def p_poids_nf(self):
        "le poids des niveaux fonctionnels"
        if self.p_specifique:
            return 35 if self.competences.exists() else 80
        else:
            return 30 if self.competences.exists() else 25

    @property
    def p_poids_filiere_nf_competences(self):
        "le poids des filieres, nf et competences"
        if self.p_specifique:
            return (0, 35, 65) if self.competences.exists() else (20, 80, 0)
        else:
            return (10, 30, 60) if self.competences.exists() else (75, 25, 0)

    class Meta:
        constraints = [
            models.CheckConstraint(
                name='%(app_label)s_%(class)s_p_direct_commissionne_valid',
                check=models.Q(p_direct_commissionne__in=DirectCommissionneChoices.values)
            ),
            models.CheckConstraint(
                name='%(app_label)s_%(class)s_p_nf_valid',
                check=models.Q(p_nf__in=NiveauFonctionnelChoices.values)
            ),
            models.CheckConstraint(
                name='%(app_label)s_%(class)s_p_specifique_valid',
                check=models.Q(p_specifique__in=SpecifiqueChoices.values)
            ),
            models.CheckConstraint(
                name='%(app_label)s_%(class)s_propositions_armement_valid',
                check=models.Q(propositions_armement__in=PropositionsArmementChoices.values)
            ),
        ]


class Postes_Pams(models.Model):
    class Cols():
        """ Constantes pour les noms de colonnes """

        PK                         = 'id'
        REL_PAM                    = 'p_pam'
        REL_POSTE                  = 'poste'
        O2M_DECISION               = 'decisions'


    objects = BulkUpdateOrCreateQuerySet.as_manager()

    id = models.CharField(primary_key=True, max_length=100)
    p_pam = models.ForeignKey(PAM, on_delete = models.CASCADE, related_name='p_pam')
    poste = models.ForeignKey(Poste, on_delete=models.CASCADE, related_name='poste')
    p_avis_pam = models.CharField(max_length=100, choices=AvisPosteChoices.choices, null=True, default=AvisPosteChoices.NON_ETUDIE)
    p_avis_fe_pam = models.CharField(max_length=100, choices=AvisPosteChoices.choices, null=True, default=AvisPosteChoices.NON_ETUDIE)
    p_direct_commissionne_pam = models.CharField('Direct Commissionne', max_length=100, choices=DirectCommissionneChoices.choices, null=True, blank=True)
    p_notes_gestionnaire_pam = models.TextField(null=True, blank=True)
    p_priorisation_pcp_pam = models.TextField('Priorisation PCP', null=True, blank=True)
    info_reo = models.CharField(max_length=100, default="")
