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

"""Jury DUT120: gestion et vues

Ce diplôme est attribué sur demande aux étudiants de BUT ayant acquis les 120 ECTS
de BUT 1 et BUT 2.

"""
import time
from flask import flash, g, redirect, render_template, request, url_for
from flask_wtf import FlaskForm
from wtforms import SubmitField

from app import db, log
from app.but import cursus_but
from app.decorators import scodoc, permission_required
from app.models import FormSemestre, Identite, Scolog, ValidationDUT120
from app.scodoc.sco_exceptions import ScoPermissionDenied, ScoValueError
from app.scodoc.sco_permissions import Permission
from app.views import notes_bp as bp
from app.views import ScoData


def etud_valide_dut120(etud: Identite, referentiel_competence_id: int) -> bool:
    """Vrai si l'étudiant satisfait les conditions pour valider le DUT120"""
    ects_but1_but2 = etud_ects_but1_but2(etud, referentiel_competence_id)
    return ects_but1_but2 >= 120


def etud_ects_but1_but2(etud, referentiel_competence_id: int) -> float:
    """Les ECTS enregistré en BUT1 et BUT2 de ce ref. et du parcours"""
    # parcours de la dernière inscription
    parcour = cursus_but.get_etud_parcours(etud, referentiel_competence_id)
    return cursus_but.but_ects_valides(
        etud,
        referentiel_competence_id,
        parcour_id=parcour.id if parcour else None,
        annees_but=("BUT1", "BUT2"),
    )


class ValidationDUT120Form(FlaskForm):
    "Formulaire validation DUT120"
    submit = SubmitField("Enregistrer le diplôme DUT 120")


@bp.route(
    "/validate_dut120/etudid/<int:etudid>/formsemestre/<int:formsemestre_id>",
    methods=["GET", "POST"],
)
@scodoc
@permission_required(Permission.ScoView)
def validate_dut120_etud(etudid: int, formsemestre_id: int):
    """Formulaire validation individuelle du DUT120"""
    # Check arguments
    etud = Identite.get_etud(etudid)
    formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
    refcomp = formsemestre.formation.referentiel_competence
    if not refcomp:
        raise ScoValueError("formation non associée à un référentiel de compétences")
    # Permission
    if not formsemestre.can_edit_jury():
        raise ScoPermissionDenied(
            dest_url=url_for(
                "notes.formsemestre_status",
                scodoc_dept=g.scodoc_dept,
                formsemestre_id=formsemestre_id,
            )
        )
    ects_but1_but2 = etud_ects_but1_but2(etud, refcomp.id)
    form = ValidationDUT120Form()
    # Check if ValidationDUT120 instance already exists
    existing_validation = ValidationDUT120.query.filter_by(
        etudid=etud.id, referentiel_competence_id=refcomp.id
    ).first()

    if existing_validation:
        flash("DUT120 déjà validé", "info")
        etud_can_validate_dut = False
    # Check if the student meets the criteria
    elif ects_but1_but2 < 120:
        flash("L'étudiant ne remplit pas les conditions", "warning")
        etud_can_validate_dut = False  # here existing_validation is None
    else:
        etud_can_validate_dut = True

    if etud_can_validate_dut and request.method == "POST" and form.validate_on_submit():
        new_validation = ValidationDUT120(
            etudid=etud.id,
            referentiel_competence_id=refcomp.id,
            formsemestre_id=formsemestre.id,  # Replace with appropriate value
        )
        db.session.add(new_validation)
        Scolog.logdb(
            "jury_but",
            etudid=etud.id,
            msg=f"Validation DUT120 enregistrée depuis S{formsemestre.semestre_id}",
        )
        db.session.commit()
        log(f"ValidationDUT120 enregistrée pour {etud} depuis {formsemestre}")
        flash("Validation DUT120 enregistrée", "success")
        return redirect(etud.url_fiche())

    return render_template(
        "but/validate_dut120.j2",
        ects_but1_but2=ects_but1_but2,
        etud=etud,
        etud_can_validate_dut=etud_can_validate_dut,
        form=form,
        formsemestre=formsemestre,
        sco=ScoData(formsemestre=formsemestre, etud=etud),
        time=time,
        title="Délivrance du DUT",
        validation=existing_validation,
    )