# -*- mode: python -*-
# -*- coding: utf-8 -*-

##############################################################################
#
# Gestion scolarite IUT
#
# Copyright (c) 1999 - 2023 Emmanuel Viennet.  All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
#
##############################################################################

from datetime import datetime
import re
import requests

from flask import url_for
from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileAllowed, FileRequired
from markupsafe import Markup
from sqlalchemy import text
from wtforms import (
    BooleanField,
    DateField,
    FieldList,
    FormField,
    HiddenField,
    IntegerField,
    SelectField,
    SelectMultipleField,
    StringField,
    SubmitField,
    TextAreaField,
)
from wtforms.validators import (
    ValidationError,
    DataRequired,
    Email,
    Optional,
    NumberRange,
)
from wtforms.widgets import ListWidget, CheckboxInput

from app import db
from app.auth.models import User
from app.entreprises import SIRET_PROVISOIRE_START
from app.entreprises.models import (
    Entreprise,
    EntrepriseCorrespondant,
    EntreprisePreferences,
    EntrepriseSite,
    EntrepriseTaxeApprentissage,
)
from app.models import Identite, Departement
from app.scodoc import sco_utils as scu

CHAMP_REQUIS = "Ce champ est requis"
SUBMIT_MARGE = {"style": "margin-bottom: 10px;"}


def _build_string_field(label, required=True, render_kw=None):
    if required:
        return StringField(
            label,
            validators=[DataRequired(message=CHAMP_REQUIS)],
            render_kw=render_kw,
        )
    else:
        return StringField(label, validators=[Optional()], render_kw=render_kw)


class EntreprisesFilterForm(FlaskForm):
    active = BooleanField("Toutes les entreprises")
    association = BooleanField("Seulement les associations partenaires")
    siret_provisoire = BooleanField("Seulement SIRET provisoire")


class EntrepriseCreationForm(FlaskForm):
    siret = StringField(
        "SIRET",
        validators=[Optional()],
        render_kw={"placeholder": "Numéro composé de 14 chiffres"},
        description="Laissez vide pour générer un SIRET provisoire",
    )
    association = BooleanField("Association")
    nom_entreprise = _build_string_field("Nom de l'entreprise (*)")
    adresse = _build_string_field("Adresse de l'entreprise (*)")
    codepostal = _build_string_field("Code postal de l'entreprise (*)")
    ville = _build_string_field("Ville de l'entreprise (*)")
    pays = _build_string_field("Pays de l'entreprise", required=False)

    civilite = SelectField(
        "Civilité du correspondant",
        choices=[("H", "Monsieur"), ("F", "Madame")],
        validators=[DataRequired(message=CHAMP_REQUIS)],
    )
    nom_correspondant = _build_string_field("Nom du correspondant", required=False)
    prenom_correspondant = _build_string_field(
        "Prénom du correspondant", required=False
    )
    telephone = _build_string_field("Téléphone du correspondant", required=False)
    mail = StringField(
        "Mail du correspondant",
        validators=[Optional(), Email(message="Adresse e-mail invalide")],
    )
    poste = _build_string_field("Poste du correspondant", required=False)
    service = _build_string_field("Service du correspondant", required=False)
    origine = _build_string_field("Origine du correspondant", required=False)
    notes = _build_string_field("Notes sur le correspondant", required=False)

    submit = SubmitField("Enregistrer", render_kw=SUBMIT_MARGE)
    cancel = SubmitField("Annuler", render_kw=SUBMIT_MARGE)

    def validate(self, extra_validators=None):
        validate = True
        if not super().validate(extra_validators):
            return False

        if EntreprisePreferences.get_check_siret() and self.siret.data != "":
            siret_data = self.siret.data.strip().replace(" ", "")
            self.siret.data = siret_data
            if re.match("^\d{14}$", siret_data) is None:
                self.siret.errors.append("Format incorrect")
                validate = False
            else:
                try:
                    req = requests.get(
                        f"https://entreprise.data.gouv.fr/api/sirene/v1/siret/{siret_data}",
                        timeout=scu.SCO_EXT_TIMEOUT,
                    )
                    if req.status_code != 200:
                        self.siret.errors.append("SIRET inexistant")
                        validate = False
                except requests.ConnectionError:
                    self.siret.errors.append(
                        "Impossible de vérifier l'existance du SIRET"
                    )
                    validate = False
                entreprise = Entreprise.query.filter_by(siret=siret_data).first()
                if entreprise is not None:
                    if entreprise.visible is True:
                        lien = f"<a href='{url_for('entreprises.fiche_entreprise', entreprise_id=entreprise.id)}'>ici</a>"
                        self.siret.errors.append(
                            Markup(
                                f"Entreprise déjà présent, lien vers la fiche : {lien}"
                            )
                        )
                        validate = False
                    else:
                        self.siret.errors.append("Entreprise en phase de validation")
                        validate = False

        if (
            self.nom_correspondant.data.strip()
            or self.prenom_correspondant.data.strip()
            or self.telephone.data.strip()
            or self.mail.data.strip()
            or self.poste.data.strip()
            or self.service.data.strip()
            or self.origine.data.strip()
            or self.notes.data.strip()
        ):
            if not self.nom_correspondant.data.strip():
                self.nom_correspondant.errors.append("Ce champ est requis")
                validate = False
            if not self.prenom_correspondant.data.strip():
                self.prenom_correspondant.errors.append("Ce champ est requis")
                validate = False
            if not self.telephone.data.strip() and not self.mail.data.strip():
                msg = "Saisir un moyen de contact (mail ou téléphone)"
                self.telephone.errors.append(msg)
                self.mail.errors.append(msg)
                validate = False

        return validate


class EntrepriseModificationForm(FlaskForm):
    siret = StringField("SIRET (*)")
    new_siret = StringField(
        "Modification du SIRET provisoire (*)",
        description="Activé uniquement pour les entreprises avec SIRET provisoire",
    )
    association = BooleanField("Association")
    nom = _build_string_field("Nom de l'entreprise (*)")
    adresse = _build_string_field("Adresse (*)")
    codepostal = _build_string_field("Code postal (*)")
    ville = _build_string_field("Ville (*)")
    pays = _build_string_field("Pays", required=False)
    submit = SubmitField("Modifier", render_kw=SUBMIT_MARGE)
    cancel = SubmitField("Annuler", render_kw=SUBMIT_MARGE)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.siret.render_kw = {"disabled": ""}
        if self.siret.data.startswith(SIRET_PROVISOIRE_START) is True:
            self.new_siret.validators = [Optional()]
        else:
            self.new_siret.render_kw = {"disabled": ""}

    def validate_new_siret(self, new_siret):
        if EntreprisePreferences.get_check_siret() and new_siret.data is not None:
            siret_data = new_siret.data.strip().replace(" ", "")
            self.new_siret.data = siret_data
            if re.match("^\d{14}$", siret_data) is None:
                raise ValidationError("Format incorrect")
            else:
                try:
                    req = requests.get(
                        f"https://entreprise.data.gouv.fr/api/sirene/v1/siret/{siret_data}",
                        timeout=scu.SCO_EXT_TIMEOUT,
                    )
                    if req.status_code != 200:
                        raise ValidationError("SIRET inexistant")
                except requests.ConnectionError:
                    raise ValidationError("Impossible de vérifier l'existance du SIRET")
                entreprise = Entreprise.query.filter_by(siret=siret_data).first()
                if entreprise is not None:
                    if entreprise.visible is True:
                        lien = f'<a href="/ScoDoc/entreprises/fiche_entreprise/{entreprise.id}">ici</a>'
                        raise ValidationError(
                            Markup(
                                f"Entreprise déjà présent, lien vers la fiche : {lien}"
                            )
                        )
                    else:
                        raise ValidationError("Entreprise en phase de validation")


class SiteCreationForm(FlaskForm):
    hidden_entreprise_id = HiddenField()
    nom = _build_string_field("Nom du site (*)")
    adresse = _build_string_field("Adresse (*)")
    codepostal = _build_string_field("Code postal (*)")
    ville = _build_string_field("Ville (*)")
    pays = _build_string_field("Pays", required=False)
    submit = SubmitField("Enregistrer", render_kw=SUBMIT_MARGE)
    cancel = SubmitField("Annuler", render_kw=SUBMIT_MARGE)

    def validate(self, extra_validators=None):
        validate = True
        if not super().validate(extra_validators):
            return False

        site = EntrepriseSite.query.filter_by(
            entreprise_id=self.hidden_entreprise_id.data, nom=self.nom.data
        ).first()

        if site is not None:
            self.nom.errors.append("Ce site existe déjà (même nom)")
            validate = False

        return validate


class SiteModificationForm(FlaskForm):
    hidden_entreprise_id = HiddenField()
    hidden_site_id = HiddenField()
    nom = _build_string_field("Nom du site (*)")
    adresse = _build_string_field("Adresse (*)")
    codepostal = _build_string_field("Code postal (*)")
    ville = _build_string_field("Ville (*)")
    pays = _build_string_field("Pays", required=False)
    submit = SubmitField("Modifier", render_kw=SUBMIT_MARGE)
    cancel = SubmitField("Annuler", render_kw=SUBMIT_MARGE)

    def validate(self, extra_validators=None):
        validate = True
        if not super().validate(extra_validators):
            return False

        site = EntrepriseSite.query.filter(
            EntrepriseSite.entreprise_id == self.hidden_entreprise_id.data,
            EntrepriseSite.id != self.hidden_site_id.data,
            EntrepriseSite.nom == self.nom.data,
        ).first()

        if site is not None:
            self.nom.errors.append("Ce site existe déjà (même nom)")
            validate = False

        return validate


class MultiCheckboxField(SelectMultipleField):
    widget = ListWidget(prefix_label=False)
    option_widget = CheckboxInput()


class OffreCreationForm(FlaskForm):
    hidden_entreprise_id = HiddenField()
    intitule = _build_string_field("Intitulé (*)")
    description = TextAreaField(
        "Description (*)", validators=[DataRequired(message=CHAMP_REQUIS)]
    )
    type_offre = SelectField(
        "Type de l'offre (*)",
        choices=[("Stage"), ("Alternance")],
        validators=[DataRequired(message=CHAMP_REQUIS)],
    )
    missions = TextAreaField(
        "Missions (*)", validators=[DataRequired(message=CHAMP_REQUIS)]
    )
    duree = _build_string_field("Durée (*)")
    depts = MultiCheckboxField("Départements (*)", validators=[Optional()], coerce=int)
    expiration_date = DateField("Date expiration", validators=[Optional()])
    correspondant = SelectField("Correspondant à contacter", validators=[Optional()])
    fichier = FileField(
        "Fichier",
        validators=[
            Optional(),
            FileAllowed(["pdf", "docx"], "Fichier .pdf ou .docx uniquement"),
        ],
    )
    submit = SubmitField("Enregistrer", render_kw=SUBMIT_MARGE)
    cancel = SubmitField("Annuler", render_kw=SUBMIT_MARGE)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.correspondant.choices = [("", "")] + [
            (correspondant.id, f"{correspondant.nom} {correspondant.prenom}")
            for correspondant in db.session.query(EntrepriseCorrespondant)
            .join(EntrepriseSite, EntrepriseCorrespondant.site_id == EntrepriseSite.id)
            .filter(EntrepriseSite.entreprise_id == self.hidden_entreprise_id.data)
            .all()
        ]

        self.depts.choices = [
            (dept.id, dept.acronym) for dept in Departement.query.all()
        ]

    def validate(self, extra_validators=None):
        validate = True
        if not super().validate(extra_validators):
            return False

        if len(self.depts.data) < 1:
            self.depts.errors.append("Choisir au moins un département")
            validate = False

        return validate


class OffreModificationForm(FlaskForm):
    hidden_entreprise_id = HiddenField()
    intitule = _build_string_field("Intitulé (*)")
    description = TextAreaField(
        "Description (*)", validators=[DataRequired(message=CHAMP_REQUIS)]
    )
    type_offre = SelectField(
        "Type de l'offre (*)",
        choices=[("Stage"), ("Alternance")],
        validators=[DataRequired(message=CHAMP_REQUIS)],
    )
    missions = TextAreaField(
        "Missions (*)", validators=[DataRequired(message=CHAMP_REQUIS)]
    )
    duree = _build_string_field("Durée (*)")
    depts = MultiCheckboxField("Départements (*)", validators=[Optional()], coerce=int)
    expiration_date = DateField("Date expiration", validators=[Optional()])
    correspondant = SelectField("Correspondant à contacter", validators=[Optional()])
    submit = SubmitField("Modifier", render_kw=SUBMIT_MARGE)
    cancel = SubmitField("Annuler", render_kw=SUBMIT_MARGE)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.correspondant.choices = [("", "")] + [
            (correspondant.id, f"{correspondant.nom} {correspondant.prenom}")
            for correspondant in db.session.query(EntrepriseCorrespondant)
            .join(EntrepriseSite, EntrepriseCorrespondant.site_id == EntrepriseSite.id)
            .filter(EntrepriseSite.entreprise_id == self.hidden_entreprise_id.data)
            .all()
        ]

        self.depts.choices = [
            (dept.id, dept.acronym) for dept in Departement.query.all()
        ]

    def validate(self, extra_validators=None):
        validate = True
        if not super().validate(extra_validators):
            return False

        if len(self.depts.data) < 1:
            self.depts.errors.append("Choisir au moins un département")
            validate = False

        return validate


class CorrespondantCreationForm(FlaskForm):
    civilite = SelectField(
        "Civilité (*)",
        choices=[("H", "Monsieur"), ("F", "Madame")],
        validators=[DataRequired(message=CHAMP_REQUIS)],
        render_kw={"class": "form-control"},
    )
    nom = StringField(
        "Nom (*)",
        validators=[DataRequired('Le champ "Nom" est requis')],
        render_kw={"class": "form-control"},
    )
    prenom = StringField(
        "Prénom (*)",
        validators=[DataRequired('Le champ "Prénom" est requis')],
        render_kw={"class": "form-control"},
    )
    telephone = _build_string_field(
        "Téléphone (*)", required=False, render_kw={"class": "form-control"}
    )
    mail = StringField(
        "Mail (*)",
        validators=[Optional(), Email(message="Adresse e-mail invalide")],
        render_kw={"class": "form-control"},
    )
    poste = _build_string_field(
        "Poste", required=False, render_kw={"class": "form-control"}
    )
    service = _build_string_field(
        "Service", required=False, render_kw={"class": "form-control"}
    )
    origine = _build_string_field(
        "Origine", required=False, render_kw={"class": "form-control"}
    )
    notes = _build_string_field(
        "Notes", required=False, render_kw={"class": "form-control"}
    )

    def validate(self, extra_validators=None):
        validate = True
        if not super().validate(extra_validators):
            return False

        if not self.telephone.data and not self.mail.data:
            msg = "Saisir un moyen de contact (mail ou téléphone)"
            self.telephone.errors.append(msg)
            validate = False

        return validate


class CorrespondantsCreationForm(FlaskForm):
    hidden_site_id = HiddenField()
    correspondants = FieldList(FormField(CorrespondantCreationForm), min_entries=1)
    submit = SubmitField("Enregistrer")
    cancel = SubmitField("Annuler")

    def validate(self, extra_validators=None):
        validate = True
        if not super().validate(extra_validators):
            return False

        correspondant_list = []
        for entry in self.correspondants.entries:
            if entry.nom.data and entry.prenom.data:
                if (
                    entry.nom.data.strip(),
                    entry.prenom.data.strip(),
                ) in correspondant_list:
                    entry.nom.errors.append(
                        "Vous avez saisi 2 fois le même nom et prenom"
                    )
                    entry.prenom.errors.append("")
                    validate = False
                correspondant_list.append(
                    (entry.nom.data.strip(), entry.prenom.data.strip())
                )
                correspondant = EntrepriseCorrespondant.query.filter_by(
                    site_id=self.hidden_site_id.data,
                    nom=entry.nom.data,
                    prenom=entry.prenom.data,
                ).first()
                if correspondant is not None:
                    entry.nom.errors.append(
                        "Ce correspondant existe déjà (même nom et prénom)"
                    )
                    entry.prenom.errors.append("")
                    validate = False
        return validate


class CorrespondantModificationForm(FlaskForm):
    hidden_correspondant_id = HiddenField()
    hidden_site_id = HiddenField()
    hidden_entreprise_id = HiddenField()
    civilite = SelectField(
        "Civilité (*)",
        choices=[("H", "Monsieur"), ("F", "Madame")],
        validators=[DataRequired(message=CHAMP_REQUIS)],
    )
    nom = _build_string_field("Nom (*)")
    prenom = _build_string_field("Prénom (*)")
    telephone = _build_string_field("Téléphone (*)", required=False)
    mail = StringField(
        "Mail (*)",
        validators=[Optional(), Email(message="Adresse e-mail invalide")],
    )
    poste = _build_string_field("Poste", required=False)
    service = _build_string_field("Service", required=False)
    origine = _build_string_field("Origine", required=False)
    notes = _build_string_field("Notes", required=False)
    site = SelectField(
        "Site du correspondant", validators=[DataRequired()], description="Nom du site"
    )
    submit = SubmitField("Modifier", render_kw=SUBMIT_MARGE)
    cancel = SubmitField("Annuler", render_kw=SUBMIT_MARGE)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.site.choices = [
            (site.id, f"{site.nom}")
            for site in db.session.query(EntrepriseSite)
            .filter(EntrepriseSite.entreprise_id == self.hidden_entreprise_id.data)
            .all()
        ]

    def validate(self, extra_validators=None):
        validate = True
        if not super().validate(extra_validators):
            return False

        correspondant = EntrepriseCorrespondant.query.filter(
            EntrepriseCorrespondant.id != self.hidden_correspondant_id.data,
            EntrepriseCorrespondant.site_id == self.hidden_site_id.data,
            EntrepriseCorrespondant.nom == self.nom.data,
            EntrepriseCorrespondant.prenom == self.prenom.data,
        ).first()
        if correspondant is not None:
            self.nom.errors.append("Ce correspondant existe déjà (même nom et prénom)")
            self.prenom.errors.append("")
            validate = False

        if not self.telephone.data and not self.mail.data:
            msg = "Saisir un moyen de contact (mail ou téléphone)"
            self.telephone.errors.append(msg)
            self.mail.errors.append(msg)
            validate = False

        return validate


class ContactCreationForm(FlaskForm):
    date = _build_string_field(
        "Date (*)",
        render_kw={"type": "datetime-local"},
    )
    utilisateur = _build_string_field(
        "Utilisateur (*)",
        render_kw={"placeholder": "Tapez le nom de l'utilisateur"},
    )
    notes = TextAreaField("Notes (*)", validators=[DataRequired(message=CHAMP_REQUIS)])
    submit = SubmitField("Enregistrer", render_kw=SUBMIT_MARGE)
    cancel = SubmitField("Annuler", render_kw=SUBMIT_MARGE)

    def validate_utilisateur(self, utilisateur):
        utilisateur_data = self.utilisateur.data.upper().strip()
        stm = text(
            "SELECT id, UPPER(CONCAT(nom, ' ', prenom, ' ', '(', user_name, ')')) FROM \"user\" WHERE UPPER(CONCAT(nom, ' ', prenom, ' ', '(', user_name, ')'))=:utilisateur_data"
        )
        utilisateur = (
            User.query.from_statement(stm)
            .params(utilisateur_data=utilisateur_data)
            .first()
        )
        if utilisateur is None:
            raise ValidationError("Champ incorrect (selectionnez dans la liste)")


class ContactModificationForm(FlaskForm):
    date = _build_string_field(
        "Date (*)",
        render_kw={"type": "datetime-local"},
    )
    utilisateur = _build_string_field(
        "Utilisateur (*)",
        render_kw={"placeholder": "Tapez le nom de l'utilisateur"},
    )
    notes = TextAreaField("Notes (*)", validators=[DataRequired(message=CHAMP_REQUIS)])
    submit = SubmitField("Modifier", render_kw=SUBMIT_MARGE)
    cancel = SubmitField("Annuler", render_kw=SUBMIT_MARGE)

    def validate_utilisateur(self, utilisateur):
        utilisateur_data = self.utilisateur.data.upper().strip()
        stm = text(
            "SELECT id, UPPER(CONCAT(nom, ' ', prenom, ' ', '(', user_name, ')')) FROM \"user\" WHERE UPPER(CONCAT(nom, ' ', prenom, ' ', '(', user_name, ')'))=:utilisateur_data"
        )
        utilisateur = (
            User.query.from_statement(stm)
            .params(utilisateur_data=utilisateur_data)
            .first()
        )
        if utilisateur is None:
            raise ValidationError("Champ incorrect (selectionnez dans la liste)")


class StageApprentissageCreationForm(FlaskForm):
    etudiant = _build_string_field(
        "Étudiant (*)",
        render_kw={"placeholder": "Tapez le nom de l'étudiant", "autocomplete": "off"},
    )
    etudid = HiddenField()
    type_offre = SelectField(
        "Type de l'offre (*)",
        choices=[("Stage"), ("Alternance")],
        validators=[DataRequired(message=CHAMP_REQUIS)],
    )
    date_debut = DateField(
        "Date début (*)", validators=[DataRequired(message=CHAMP_REQUIS)]
    )
    date_fin = DateField(
        "Date fin (*)", validators=[DataRequired(message=CHAMP_REQUIS)]
    )
    notes = TextAreaField("Notes")
    submit = SubmitField("Enregistrer", render_kw=SUBMIT_MARGE)
    cancel = SubmitField("Annuler", render_kw=SUBMIT_MARGE)

    def validate(self, extra_validators=None):
        validate = True
        if not super().validate(extra_validators):
            validate = False

        if (
            self.date_debut.data
            and self.date_fin.data
            and self.date_debut.data > self.date_fin.data
        ):
            self.date_debut.errors.append("Les dates sont incompatibles")
            self.date_fin.errors.append("Les dates sont incompatibles")
            validate = False

        return validate

    def validate_etudid(self, field):
        "L'etudid doit avoit été placé par le JS"
        etudid = int(field.data) if field.data else None
        etudiant = db.session.get(Identite, etudid) if etudid is not None else None
        if etudiant is None:
            raise ValidationError("Étudiant introuvable (sélectionnez dans la liste)")


class FrenchFloatField(StringField):
    "A field allowing to enter . or ,"

    def process_formdata(self, valuelist):
        "catch incoming data"
        if not valuelist:
            return
        try:
            value = valuelist[0].replace(",", ".")
            self.data = float(value)
        except ValueError as exc:
            self.data = None
            raise ValueError(self.gettext("Not a valid decimal value.")) from exc


class TaxeApprentissageForm(FlaskForm):
    hidden_entreprise_id = HiddenField()
    annee = IntegerField(
        "Année (*)",
        validators=[
            DataRequired(message=CHAMP_REQUIS),
            NumberRange(
                min=1900,
                max=int(datetime.now().strftime("%Y")),
                message=f"L'année doit être inférieure ou égale à {int(datetime.now().strftime('%Y'))}",
            ),
        ],
        default=int(datetime.now().strftime("%Y")),
    )
    montant = FrenchFloatField(
        "Montant (*)",
        validators=[
            DataRequired(message=CHAMP_REQUIS),
            # NumberRange(
            #     min=0.1,
            #     max=1e8,
            #     message="Le montant doit être supérieur à 0",
            # ),
        ],
        default=1,
    )
    notes = TextAreaField("Notes")
    submit = SubmitField("Enregistrer", render_kw=SUBMIT_MARGE)
    cancel = SubmitField("Annuler", render_kw=SUBMIT_MARGE)

    def validate(self, extra_validators=None):
        validate = True
        if not super().validate(extra_validators):
            return False

        taxe = EntrepriseTaxeApprentissage.query.filter_by(
            entreprise_id=self.hidden_entreprise_id.data, annee=self.annee.data
        ).first()
        if taxe is not None:
            self.annee.errors.append(
                "Une taxe d'apprentissage a déjà été versé pour cette année"
            )
            validate = False

        return validate


class TaxeApprentissageModificationForm(FlaskForm):
    annee = IntegerField("Année (*)")
    montant = IntegerField(
        "Montant (*)",
        validators=[
            DataRequired(message=CHAMP_REQUIS),
            NumberRange(
                min=1,
                message="Le montant doit être supérieur à 0",
            ),
        ],
        default=1,
    )
    notes = TextAreaField("Notes")
    submit = SubmitField("Modifier", render_kw=SUBMIT_MARGE)
    cancel = SubmitField("Annuler", render_kw=SUBMIT_MARGE)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.annee.render_kw = {"disabled": ""}


class EnvoiOffreForm(FlaskForm):
    responsables = FieldList(
        StringField(
            "Responsable (*)",
            render_kw={
                "placeholder": "Tapez le nom du responsable de formation",
                "class": "form-control",
            },
        ),
        min_entries=1,
    )
    submit = SubmitField("Envoyer")
    cancel = SubmitField("Annuler")

    def validate(self, extra_validators=None):
        validate = True
        list_select = True

        if not super().validate(extra_validators):
            return False

        for entry in self.responsables.entries:
            if entry.data:
                responsable_data = entry.data.upper().strip()
                stm = text(
                    "SELECT id, UPPER(CONCAT(nom, ' ', prenom, ' ', '(', user_name, ')')) FROM \"user\" WHERE UPPER(CONCAT(nom, ' ', prenom, ' ', '(', user_name, ')'))=:responsable_data"
                )
                responsable = (
                    User.query.from_statement(stm)
                    .params(responsable_data=responsable_data)
                    .first()
                )
                if responsable is None:
                    validate, list_select = False, False

        if list_select is False:
            self.responsables.errors.append(
                "Champ incorrect (selectionnez dans la liste)"
            )

        return validate


class AjoutFichierForm(FlaskForm):
    fichier = FileField(
        "Fichier (*)",
        validators=[
            FileRequired(message=CHAMP_REQUIS),
            FileAllowed(["pdf", "docx"], "Fichier .pdf ou .docx uniquement"),
        ],
    )
    submit = SubmitField("Ajouter", render_kw=SUBMIT_MARGE)
    cancel = SubmitField("Annuler", render_kw=SUBMIT_MARGE)


class SuppressionConfirmationForm(FlaskForm):
    submit = SubmitField("Supprimer", render_kw=SUBMIT_MARGE)
    cancel = SubmitField("Annuler", render_kw=SUBMIT_MARGE)


class DesactivationConfirmationForm(FlaskForm):
    notes_active = TextAreaField("Notes sur la désactivation", validators=[Optional()])
    submit = SubmitField("Modifier", render_kw=SUBMIT_MARGE)
    cancel = SubmitField("Annuler", render_kw=SUBMIT_MARGE)


class ActivationConfirmationForm(FlaskForm):
    submit = SubmitField("Modifier", render_kw=SUBMIT_MARGE)
    cancel = SubmitField("Annuler", render_kw=SUBMIT_MARGE)


class ValidationConfirmationForm(FlaskForm):
    submit = SubmitField("Valider", render_kw=SUBMIT_MARGE)
    cancel = SubmitField("Annuler", render_kw=SUBMIT_MARGE)


class ImportForm(FlaskForm):
    fichier = FileField(
        "Fichier (*)",
        validators=[
            FileRequired(message=CHAMP_REQUIS),
            FileAllowed(["xlsx"], "Fichier .xlsx uniquement"),
        ],
    )
    submit = SubmitField("Importer", render_kw=SUBMIT_MARGE)


class PreferencesForm(FlaskForm):
    mail_entreprise = StringField(
        "Mail notifications",
        validators=[Optional(), Email(message="Adresse e-mail invalide")],
        description="utilisé pour envoi mail notification application relations entreprises",
    )
    check_siret = BooleanField("Vérification SIRET")
    submit = SubmitField("Valider", render_kw=SUBMIT_MARGE)
    cancel = SubmitField("Annuler", render_kw=SUBMIT_MARGE)
