##############################################" Formations ############################################################
from flask import jsonify

from app import models
from app.api import bp
from app.api.errors import error_response
from app.api.auth import token_permission_required
from app.scodoc.sco_formations import formation_export
from app.scodoc.sco_permissions import Permission


@bp.route("/formations", methods=["GET"])
@token_permission_required(Permission.APIView)
def formations():
    """
    Retourne la liste des formations

    Exemple de résultat :
        [
          {
            "id": 1,
            "acronyme": "BUT R&T",
            "titre_officiel": "Bachelor technologique r\u00e9seaux et t\u00e9l\u00e9communications",
            "formation_code": "V1RET",
            "code_specialite": null,
            "dept_id": 1,
            "titre": "BUT R&T",
            "version": 1,
            "type_parcours": 700,
            "referentiel_competence_id": null,
            "formation_id": 1
          },
          ...
        ]
    """
    # Récupération de toutes les formations
    list_formations = models.Formation.query.all()

    # Mise en forme des données
    data = [d.to_dict() for d in list_formations]

    return jsonify(data)


@bp.route("/formations/<int:formation_id>", methods=["GET"])
@token_permission_required(Permission.APIView)
def formations_by_id(formation_id: int):
    """
    Retourne une formation en fonction d'un id donné

    formation_id : l'id d'une formation

    Exemple de résultat :
        {
          "id": 1,
          "acronyme": "BUT R&amp;T",
          "titre_officiel": "Bachelor technologique r\u00e9seaux et t\u00e9l\u00e9communications",
          "formation_code": "V1RET",
          "code_specialite": null,
          "dept_id": 1,
          "titre": "BUT R&amp;T",
          "version": 1,
          "type_parcours": 700,
          "referentiel_competence_id": null,
          "formation_id": 1
        }
    """
    # Récupération de la formation
    forma = models.Formation.query.filter_by(id=formation_id).first_or_404()

    # Mise en forme des données
    data = forma.to_dict()

    return jsonify(data)


@bp.route("/formations/formation_export/<int:formation_id>", methods=["GET"])
@token_permission_required(Permission.APIView)
def formation_export_by_formation_id(formation_id: int, export_ids=False):
    """
    Retourne la formation, avec UE, matières, modules

    formation_id : l'id d'une formation

    Exemple de résultat :
        {
          "id": 1,
          "acronyme": "BUT R&amp;T",
          "titre_officiel": "Bachelor technologique r\u00e9seaux et t\u00e9l\u00e9communications",
          "formation_code": "V1RET",
          "code_specialite": null,
          "dept_id": 1,
          "titre": "BUT R&amp;T",
          "version": 1,
          "type_parcours": 700,
          "referentiel_competence_id": null,
          "formation_id": 1,
          "ue": [
            {
              "acronyme": "RT1.1",
              "numero": 1,
              "titre": "Administrer les r\u00e9seaux et l\u2019Internet",
              "type": 0,
              "ue_code": "UCOD11",
              "ects": 12.0,
              "is_external": false,
              "code_apogee": "",
              "coefficient": 0.0,
              "semestre_idx": 1,
              "color": "#B80004",
              "reference": 1,
              "matiere": [
                {
                  "titre": "Administrer les r\u00e9seaux et l\u2019Internet",
                  "numero": 1,
                  "module": [
                    {
                      "titre": "Initiation aux r\u00e9seaux informatiques",
                      "abbrev": "Init aux r\u00e9seaux informatiques",
                      "code": "R101",
                      "heures_cours": 0.0,
                      "heures_td": 0.0,
                      "heures_tp": 0.0,
                      "coefficient": 1.0,
                      "ects": "",
                      "semestre_id": 1,
                      "numero": 10,
                      "code_apogee": "",
                      "module_type": 2,
                      "coefficients": [
                        {
                          "ue_reference": "1",
                          "coef": "12.0"
                        },
                        {
                          "ue_reference": "2",
                          "coef": "4.0"
                        },
                        {
                          "ue_reference": "3",
                          "coef": "4.0"
                        }
                      ]
                    },
                    {
                      "titre": "Se sensibiliser \u00e0 l&apos;hygi\u00e8ne informatique et \u00e0 la cybers\u00e9curit\u00e9",
                      "abbrev": "Hygi\u00e8ne informatique",
                      "code": "SAE11",
                      "heures_cours": 0.0,
                      "heures_td": 0.0,
                      "heures_tp": 0.0,
                      "coefficient": 1.0,
                      "ects": "",
                      "semestre_id": 1,
                      "numero": 10,
                      "code_apogee": "",
                      "module_type": 3,
                      "coefficients": [
                        {
                          "ue_reference": "1",
                          "coef": "16.0"
                        }
                      ]
                    },
                    ...
                  ]
                },
                ...
              ]
            },
          ]
        }
    """
    # Fonction utilité : app.scodoc.sco_formations.formation_export()

    try:
        # Utilisation de la fonction formation_export
        data = formation_export(formation_id, export_ids)
    except ValueError:
        return error_response(
            409,
            message="La requête ne peut être traitée en l’état actuel. \n"
            "Veillez vérifier la conformité du 'formation_id'",
        )

    return jsonify(data)


@bp.route("/formations/moduleimpl/<int:moduleimpl_id>", methods=["GET"])
@token_permission_required(Permission.APIView)
def moduleimpl(moduleimpl_id: int):
    """
    Retourne un module moduleimpl en fonction de son id

    moduleimpl_id : l'id d'un moduleimpl

    Exemple de résultat :
        {
          "id": 1,
          "formsemestre_id": 1,
          "computation_expr": null,
          "module_id": 1,
          "responsable_id": 2,
          "moduleimpl_id": 1,
          "ens": [],
          "module": {
            "heures_tp": 0,
            "code_apogee": "",
            "titre": "Initiation aux réseaux informatiques",
            "coefficient": 1,
            "module_type": 2,
            "id": 1,
            "ects": null,
            "abbrev": "Init aux réseaux informatiques",
            "ue_id": 1,
            "code": "R101",
            "formation_id": 1,
            "heures_cours": 0,
            "matiere_id": 1,
            "heures_td": 0,
            "semestre_id": 1,
            "numero": 10,
            "module_id": 1
          }
        }
    """
    # Récupération des tous les moduleimpl
    moduleimpl = models.ModuleImpl.query.filter_by(id=moduleimpl_id).first_or_404()

    # Mise en forme des données
    data = moduleimpl.to_dict()

    return jsonify(data)


@bp.route(
    "/formations/moduleimpl/formsemestre/<int:formsemestre_id>/liste",
    methods=["GET"],
)
@token_permission_required(Permission.APIView)
def moduleimpls_sem(formsemestre_id: int):
    """
    Retourne la liste des moduleimpl d'un semestre

    formsemestre_id : l'id d'un formsemestre

    Exemple d'utilisation :
        [
          {
            "id": 1,
            "formsemestre_id": 1,
            "computation_expr": null,
            "module_id": 1,
            "responsable_id": 2,
            "module": {
              "heures_tp": 0.0,
              "code_apogee": "",
              "titre": "Initiation aux r\u00e9seaux informatiques",
              "coefficient": 1.0,
              "module_type": 2,
              "id": 1,
              "ects": null,
              "abbrev": "Init aux r\u00e9seaux informatiques",
              "ue_id": 1,
              "code": "R101",
              "formation_id": 1,
              "heures_cours": 0.0,
              "matiere_id": 1,
              "heures_td": 0.0,
              "semestre_id": 1,
              "numero": 10,
              "module_id": 1
            },
            "moduleimpl_id": 1,
            "ens": []
          },
          ...
        ]
    """
    formsemestre = models.FormSemestre.query.filter_by(
        id=formsemestre_id
    ).first_or_404()

    moduleimpls = formsemestre.modimpls_sorted

    data = [moduleimpl.to_dict() for moduleimpl in moduleimpls]

    return jsonify(data)