########################################## Formsemestres ##############################################################
from flask import jsonify

import app
from app import models
from app.api import bp
from app.api.auth import token_auth, token_permission_required
from app.models import Departement, FormSemestre, FormSemestreEtape
from app.scodoc.sco_bulletins import get_formsemestre_bulletin_etud_json
from app.scodoc.sco_permissions import Permission
from app.scodoc.sco_utils import ModuleType


@bp.route("/formsemestre/<int:formsemestre_id>", methods=["GET"])
@token_auth.login_required
@token_permission_required(Permission.APIView)
def formsemestre(formsemestre_id: int):
    """
    Information sur le formsemestre indiqué.

    formsemestre_id : l'id du formsemestre

    Exemple de résultat :
        {
          "block_moyennes": false,
          "bul_bgcolor": "white",
          "bul_hide_xml": false,
          "date_debut_iso": "2021-09-01",
          "date_debut": "01/09/2021",
          "date_fin_iso": "2022-08-31",
          "date_fin": "31/08/2022",
          "dept_id": 1,
          "elt_annee_apo": null,
          "elt_sem_apo": null,
          "ens_can_edit_eval": false,
          "etat": true,
          "formation_id": 1,
          "formsemestre_id": 1,
          "gestion_compensation": false,
          "gestion_semestrielle": false,
          "id": 1,
          "modalite": "FI",
          "resp_can_change_ens": true,
          "resp_can_edit": false,
          "responsables": [1, 99], // uids
          "scodoc7_id": null,
          "semestre_id": 1,
          "titre_formation" : "BUT GEA",
          "titre_num": "BUT GEA semestre 1",
          "titre": "BUT GEA",
        }

    """
    formsemestre: FormSemestre = models.FormSemestre.query.filter_by(
        id=formsemestre_id
    ).first_or_404()
    data = formsemestre.to_dict()
    # Pour le moment on a besoin de fixer le departement
    # pour accéder aux préferences
    dept = Departement.query.get(formsemestre.dept_id)
    app.set_sco_dept(dept.acronym)
    data["annee_scolaire"] = formsemestre.annee_scolaire_str()
    data["session_id"] = formsemestre.session_id()
    return jsonify(data)


@bp.route("/formsemestre/apo/<string:etape_apo>", methods=["GET"])
@token_auth.login_required
@token_permission_required(Permission.APIView)
def formsemestre_apo(etape_apo: str):
    """
    Retourne les informations sur les formsemestres ayant cette étape Apogée

    etape_apo : un code étape apogée

    Exemple de résultat :
    [
        { ...formsemestre...
        }, ...
      ]
    """
    formsemestres = FormSemestre.query.filter(
        FormSemestreEtape.etape_apo == etape_apo,
        FormSemestreEtape.formsemestre_id == FormSemestre.id,
    )

    return jsonify([formsemestre.to_dict() for formsemestre in formsemestres])


@bp.route("/formsemestre/<int:formsemestre_id>/bulletins", methods=["GET"])
@token_auth.login_required
@token_permission_required(Permission.APIView)
def bulletins(formsemestre_id: int):
    """
    Retourne les bulletins d'un formsemestre donné

    formsemestre_id : l'id d'un formesemestre

    Exemple de résultat :
        [
            {
              "version": "0",
              "type": "BUT",
              "date": "2022-04-27T07:18:16.450634Z",
              "publie": true,
              "etudiant": {
                "civilite": "X",
                "code_ine": "1",
                "code_nip": "1",
                "date_naissance": "",
                "email": "SACHA.COSTA@example.com",
                "emailperso": "",
                "etudid": 1,
                "nom": "COSTA",
                "prenom": "SACHA",
                "nomprenom": "Sacha COSTA",
                "lieu_naissance": "",
                "dept_naissance": "",
                "nationalite": "",
                "boursier": "",
                "fiche_url": "/ScoDoc/TAPI/Scolarite/ficheEtud?etudid=1",
                "photo_url": "/ScoDoc/TAPI/Scolarite/get_photo_image?etudid=1&size=small",
                "id": 1,
                "codepostaldomicile": "",
                "paysdomicile": "",
                "telephonemobile": "",
                "typeadresse": "domicile",
                "domicile": "",
                "villedomicile": "",
                "telephone": "",
                "fax": "",
                "description": ""
              },
              "formation": {
                "id": 1,
                "acronyme": "BUT R&amp;T",
                "titre_officiel": "Bachelor technologique r\u00e9seaux et t\u00e9l\u00e9communications",
                "titre": "BUT R&amp;T"
              },
              "formsemestre_id": 1,
              "etat_inscription": "I",
              "options": {
                "show_abs": true,
                "show_abs_modules": false,
                "show_ects": true,
                "show_codemodules": false,
                "show_matieres": false,
                "show_rangs": true,
                "show_ue_rangs": true,
                "show_mod_rangs": true,
                "show_moypromo": false,
                "show_minmax": false,
                "show_minmax_mod": false,
                "show_minmax_eval": false,
                "show_coef": true,
                "show_ue_cap_details": false,
                "show_ue_cap_current": true,
                "show_temporary": true,
                "temporary_txt": "Provisoire",
                "show_uevalid": true,
                "show_date_inscr": true
              },
              "ressources": {
                "R101": {
                  "id": 1,
                  "titre": "Initiation aux r\u00e9seaux informatiques",
                  "code_apogee": null,
                  "url": "/ScoDoc/TAPI/Scolarite/Notes/moduleimpl_status?moduleimpl_id=1",
                  "moyenne": {},
                  "evaluations": [
                    {
                      "id": 1,
                      "description": "eval1",
                      "date": "2022-04-20",
                      "heure_debut": "08:00",
                      "heure_fin": "09:00",
                      "coef": "01.00",
                      "poids": {
                        "RT1.1": 1.0,
                      },
                      "note": {
                        "value": "12.00",
                        "min": "00.00",
                        "max": "18.00",
                        "moy": "10.88"
                      },
                      "url": "/ScoDoc/TAPI/Scolarite/Notes/evaluation_listenotes?evaluation_id=1"
                    }
                  ]
                },
              },
              "saes": {
                "SAE11": {
                  "id": 2,
                  "titre": "Se sensibiliser \u00e0 l&apos;hygi\u00e8ne informatique et \u00e0 la cybers\u00e9curit\u00e9",
                  "code_apogee": null,
                  "url": "/ScoDoc/TAPI/Scolarite/Notes/moduleimpl_status?moduleimpl_id=2",
                  "moyenne": {},
                  "evaluations": []
                },
              },
              "ues": {
                "RT1.1": {
                  "id": 1,
                  "titre": "Administrer les r\u00e9seaux et l\u2019Internet",
                  "numero": 1,
                  "type": 0,
                  "color": "#B80004",
                  "competence": null,
                  "moyenne": {
                    "value": "08.50",
                    "min": "06.00",
                    "max": "16.50",
                    "moy": "11.31",
                    "rang": "12",
                    "total": 16
                  },
                  "bonus": "00.00",
                  "malus": "00.00",
                  "capitalise": null,
                  "ressources": {
                    "R101": {
                      "id": 1,
                      "coef": 12.0,
                      "moyenne": "12.00"
                    },
                  },
                  "saes": {
                    "SAE11": {
                      "id": 2,
                      "coef": 16.0,
                      "moyenne": "~"
                    },
                  },
                  "ECTS": {
                    "acquis": 0.0,
                    "total": 12.0
                  }
                },
              "semestre": {
                "etapes": [],
                "date_debut": "2021-09-01",
                "date_fin": "2022-08-31",
                "annee_universitaire": "2021 - 2022",
                "numero": 1,
                "inscription": "",
                "groupes": [],
                "absences": {
                  "injustifie": 1,
                  "total": 2
                },
                "ECTS": {
                  "acquis": 0,
                  "total": 30.0
                },
                "notes": {
                  "value": "10.60",
                  "min": "02.40",
                  "moy": "11.05",
                  "max": "17.40"
                },
                "rang": {
                  "value": "10",
                  "total": 16
                }
              }
            },
            ...
        ]
    """
    formsemestre = models.FormSemestre.query.filter_by(
        id=formsemestre_id
    ).first_or_404()
    dept = models.Departement.query.filter_by(id=formsemestre.dept_id).first_or_404()
    app.set_sco_dept(dept.acronym)

    data = []
    for etu in formsemestre.etuds:
        bul_etu = get_formsemestre_bulletin_etud_json(formsemestre, etu)
        data.append(bul_etu.json)

    return jsonify(data)


# XXX Attendre ScoDoc 9.3
# @bp.route("/formsemestre/<int:formsemestre_id>/jury", methods=["GET"])
# @token_auth.login_required
# @token_permission_required(Permission.APIView)
# def jury(formsemestre_id: int):
#     """
#     Retourne le récapitulatif des décisions jury

#     formsemestre_id : l'id d'un formsemestre

#     Exemple de résultat :

#     """
#     # Fonction utilisée : app.scodoc.sco_pvjury.formsemestre_pvjury()

#     formsemestre = models.FormSemestre.query.filter_by(
#         id=formsemestre_id
#     ).first_or_404()

#     dept = models.Departement.query.filter_by(id=formsemestre.dept_id).first_or_404()

#     app.set_sco_dept(dept.acronym)

#     data = formsemestre_pvjury(formsemestre_id)

#     # try:
#     #     # Utilisation de la fonction formsemestre_pvjury
#     #     data = formsemestre_pvjury(formsemestre_id)
#     # except AttributeError:
#     #     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(
    "/formsemestre/<int:formsemestre_id>/programme",
    methods=["GET"],
)
@token_auth.login_required
@token_permission_required(Permission.APIView)
def formsemestre_programme(formsemestre_id: int):
    """
    Retourne la liste des Ues, ressources et SAE d'un semestre

    formsemestre_id : l'id d'un formsemestre

    Exemple de résultat :
        {
          "ues": [
            {
              "type": 0,
              "formation_id": 1,
              "ue_code": "UCOD11",
              "id": 1,
              "ects": 12.0,
              "acronyme": "RT1.1",
              "is_external": false,
              "numero": 1,
              "code_apogee": "",
              "titre": "Administrer les r\u00e9seaux et l\u2019Internet",
              "coefficient": 0.0,
              "semestre_idx": 1,
              "color": "#B80004",
              "ue_id": 1
            },
            ...
          ],
          "ressources": [
            {
            "ens": [ 10, 18 ],
            "formsemestre_id": 1,
            "id": 15,
            "module": {
                "abbrev": "Programmer",
                "code": "SAE15",
                "code_apogee": "V7GOP",
                "coefficient": 1.0,
                "formation_id": 1,
                "heures_cours": 0.0,
                "heures_td": 0.0,
                "heures_tp": 0.0,
                "id": 15,
                "matiere_id": 3,
                "module_id": 15,
                "module_type": 3,
                "numero": 50,
                "semestre_id": 1,
                "titre": "Programmer en Python",
                "ue_id": 3
            },
            "module_id": 15,
            "moduleimpl_id": 15,
            "responsable_id": 2
          },
            ...
          ],
          "saes": [
            {
              ...
            },
            ...
          ],
          "modules" : [ ... les modules qui ne sont ni des SAEs ni des ressources ... ]
        }
    """
    formsemestre: FormSemestre = models.FormSemestre.query.filter_by(
        id=formsemestre_id
    ).first_or_404()

    ues = formsemestre.query_ues()
    m_list = {
        ModuleType.RESSOURCE: [],
        ModuleType.SAE: [],
        ModuleType.STANDARD: [],
    }
    for modimpl in formsemestre.modimpls_sorted:
        d = modimpl.to_dict()
        m_list[modimpl.module.module_type].append(d)

    return jsonify(
        {
            "ues": [ue.to_dict() for ue in ues],
            "ressources": m_list[ModuleType.RESSOURCE],
            "saes": m_list[ModuleType.SAE],
            "modules": m_list[ModuleType.STANDARD],
        }
    )
