##############################################################################
# ScoDoc
# Copyright (c) 1999 - 2023 Emmanuel Viennet.  All rights reserved.
# See LICENSE
##############################################################################

"""
Edition associations UE <-> Ref. Compétence
"""
from flask import g, url_for
from app.models import ApcReferentielCompetences, Formation, UniteEns
from app.scodoc import sco_codes_parcours


def form_ue_choix_niveau(ue: UniteEns) -> str:
    """Form. HTML pour associer une UE à un niveau de compétence.
    Le menu select lui meême est vide et rempli en JS par appel à get_ue_niveaux_options_html
    """
    if ue.type != sco_codes_parcours.UE_STANDARD:
        return ""
    ref_comp = ue.formation.referentiel_competence
    if ref_comp is None:
        return f"""<div class="ue_choix_niveau">
        <div class="warning">Pas de référentiel de compétence associé à cette formation !</div>
        <div><a class="stdlink" href="{ url_for('notes.refcomp_assoc_formation', 
                         scodoc_dept=g.scodoc_dept, formation_id=ue.formation.id)
            }">associer un référentiel de compétence</a>
        </div>
        </div>"""
    # Les parcours:
    parcours_options = []
    for parcour in ref_comp.parcours:
        parcours_options.append(
            f"""<option value="{parcour.id}" {
            'selected' if ue.parcour == parcour else ''}
            >{parcour.libelle} ({parcour.code})
            </option>"""
        )

    newline = "\n"
    return f"""
    <div class="ue_choix_niveau">
        <form class="form_ue_choix_niveau">
        <div class="cont_ue_choix_niveau">
            <div>
                <b>Parcours&nbsp;:</b>
                <select class="select_parcour"
                onchange="set_ue_parcour(this);" 
                data-ue_id="{ue.id}"
                data-setter="{
                    url_for( "notes.set_ue_parcours", scodoc_dept=g.scodoc_dept)
                }">
                    <option value="" {
                        'selected' if ue.parcour is None else ''
                    }>Tous</option>
                    {newline.join(parcours_options)}
                </select>
            </div>
            <div>
                <b>Niveau de compétence&nbsp;:</b>
                <select class="select_niveau_ue"
                onchange="set_ue_niveau_competence(this);" 
                data-ue_id="{ue.id}"
                data-setter="{
                    url_for( "notes.set_ue_niveau_competence", scodoc_dept=g.scodoc_dept)
                }">  
                </select>
            </div>
        </div>
        </form>
    </div>
    """


def get_ue_niveaux_options_html(ue: UniteEns) -> str:
    """fragment html avec les options du menu de sélection du
    niveau de compétences associé à une UE.

    Si l'UE n'a pas de parcours associé: présente les niveaux
    de tous les parcours.
    Si l'UE a un parcours: seulement les niveaux de ce parcours.
    """
    ref_comp: ApcReferentielCompetences = ue.formation.referentiel_competence
    if ref_comp is None:
        return ""
    # Les niveaux:
    annee = ue.annee()  # 1, 2, 3
    parcours, niveaux_by_parcours = ref_comp.get_niveaux_by_parcours(
        annee, parcour=ue.parcour
    )

    # Les niveaux déjà associés à d'autres UE du même semestre
    autres_ues = ue.formation.ues.filter_by(semestre_idx=ue.semestre_idx)
    niveaux_autres_ues = {
        oue.niveau_competence_id for oue in autres_ues if oue.id != ue.id
    }
    options = []
    if niveaux_by_parcours["TC"]:  # TC pour Tronc Commun
        options.append("""<optgroup label="Tronc commun">""")
        for n in niveaux_by_parcours["TC"]:
            options.append(
                f"""<option value="{n.id}" {
                    'selected' if ue.niveau_competence == n else ''}
                >{n.annee} {n.competence.titre_long}
                niveau {n.ordre}</option>"""
            )
        options.append("""</optgroup>""")
    for parcour in parcours:
        if len(niveaux_by_parcours[parcour.id]):
            options.append(f"""<optgroup label="Parcours {parcour.libelle}">""")
            for n in niveaux_by_parcours[parcour.id]:
                if n.id in niveaux_autres_ues:
                    disabled = "disabled"
                else:
                    disabled = ""
                options.append(
                    f"""<option value="{n.id}" {'selected'
                    if ue.niveau_competence == n else ''}
                    {disabled}>{n.annee} {n.competence.titre_long}
                    niveau {n.ordre}</option>"""
                )
            options.append("""</optgroup>""")
    return (
        f"""<option value="" {'selected' if ue.niveau_competence is None else ''}>aucun</option>"""
        + "\n".join(options)
    )