<div id="studentTable">
    <div class="thead">
        <div class="tr">
            <div class="th sticky" order="ASC" onclick="reOrderEtudiants()">Noms</div>
            <button id="addColumn" class="floating-button">+</button>
        </div>
    </div>
    <div class="tbody">

        {% for etud in etudiants %}
        <div class="tr" etudid="{{etud.etudid}}">
            <div class="td sticky etudinfo" id="row-{{etud.etudid}}">
                <span>{{etud.nomprenom}}</span>
            </div>
        </div>
        {% endfor %}
    </div>
</div>
<style>
    .td.sticky .pdp-hover {
        display: none;
    }

    .td.sticky:hover .pdp-hover {
        position: absolute;
        display: block;
        width: 90px;
        height: 90px;
        border-radius: 15px;
        transition: all 0.5s;
        left: calc(80% - 45px);
        top: -25%;
    }

    .err-assi {
        display: flex;
        justify-content: flex-start;
        align-items: center;
        gap: 15px;
    }

    .tr[etudid] {
        height: 50px;
    }

    .table-container {
        overflow: auto;
        position: relative;
        max-width: 100%;
        margin: 0 auto;
        box-shadow: 0 0 1rem 0 rgba(0, 0, 0, .2);
    }

    .table {
        border-collapse: collapse;
    }

    .thead .tr {
        display: flex;
        align-items: center;
    }

    .thead .tr .th {
        height: 200px;
        display: flex;
        justify-content: center;
        align-items: center;
        font-size: 16px;
    }

    .th.sticky {
        z-index: 5;
        cursor: pointer;
    }

    .th,
    .td {
        text-align: center;
        width: 225px;
        border: 1px solid #ddd;
        display: flex;
        justify-content: center;
        align-content: center;
        min-height: 40px;
    }

    .tr {
        display: flex;
        justify-content: flex-start;
        align-items: center;
        width: max-content;
    }

    .td span {
        align-items: center;
        display: flex;
    }

    .td[assiduite_id='insc'] * {
        display: none;
    }

    .td[assiduite_id='insc']::after {
        content: "non inscrit au module";
        font-style: italic;
    }

    .sticky {
        position: sticky;
        left: 0;
        background-color: #fafafa;
        border-right: 1px solid #ddd;
        z-index: 100;
    }

    .mini-form {
        display: flex;
        justify-content: center;
        align-items: center;
        flex-direction: column;
        width: 100%;
    }

    .mini-form input,
    .mini-form select {
        display: block;
        margin: 5px;
        padding: 5px;
        border-radius: 5px;
        border: 1px solid #ddd;
        max-width: 195px;
    }

    #addColumn {
        font-size: 24px;
        width: 50px;
        height: 50px;
        border-radius: 50%;
        right: -60px;
        top: calc(50% - 50px /2);
        background-color: #09c;
        color: white;
        border: none;
        outline: none;
        cursor: pointer;
        transition: background-color 0.3s;
    }

    #addColumn:hover {
        background-color: var(--color-primary);
    }

    .th {
        background-color: #09c;
        color: white;
        position: relative;
    }

    .th.error {
        background-color: var(--color-error);
    }

    .tbody .tr:nth-child(even) {
        background-color: #f2f2f2;
    }

    .tbody .tr:hover {
        background-color: #ddd;
    }

    .td .etat {
        display: grid;
        grid-template-columns: 33% 33% 33%;
        grid-template-rows: 50% 50%;

        font-size: small;
    }


    .btngroup {
        width: 100%;
        display: flex;
        justify-content: space-between;
        align-items: center;
        flex-direction: row;
    }

    .btngroup>button {
        background-color: transparent;
        outline: none;
        border: none;
        cursor: pointer;
        color: whitesmoke;
    }

    .th .closeCol {
        font-size: 16px;
    }

    .activate {
        font-size: 14px;
    }

    .th[activated] {
        transition: all 0.5s;
    }

    .th[activated='false'] {
        opacity: 0.5;
    }

    .num {
        border: 1px whitesmoke solid;
        border-radius: 15px;
        padding: 2px 4px;
        width: 24px;
    }

    .assi_rbtn,
    .assi_lbl {
        width: 100%;
        display: flex;
        justify-content: space-evenly;
        align-items: center;

    }

    .td[assiduite_id='conflit'] {
        background-color: var(--color-error);
    }

    input[type='radio']:disabled {
        cursor: not-allowed;

    }

    .th.error:hover .col-error {
        display: block;
        z-index: 2000;
        background-color: var(--color-error);
        width: 100%;
        min-height: 25%;
        bottom: -25%;
        transition: all 1s;
    }

    .col-error {
        position: absolute;
        display: none;
    }

    .mass {
        display: flex;
        justify-content: space-evenly;
        align-items: center;
    }

    .mass input {
        outline: none;
        border: none;
    }

    .rbtn:disabled {
        opacity: 0.7;
    }

    .td.etat {
        box-sizing: border-box;
        -moz-box-sizing: border-box;
        -webkit-box-sizing: border-box;
        border: 10px solid white;
    }
</style>

<script>
    const assi_etat_defaut = "{{assi_etat_defaut}}";
    {% if scu.is_assiduites_module_forced(request.args.get('formsemestre_id', None)) %}
    window.forceModule = true;
    {% else %}
    window.forceModule = false;
    {% endif %}

    let colCount = 1;

    let currentDate = "{{date}}";
    if (currentDate == "") {
        currentDate = new Date();
        currentDate = currentDate.toFakeIso();
    } else {
        currentDate = new Date(currentDate);
        currentDate = currentDate.toFakeIso();
    }


    function createColumn(dateStart = "", dateEnd = "", moduleimpl_id = "") {
        let table = document.getElementById("studentTable");
        let th = document.createElement("div");
        th.classList.add("th", "error");
        const col_id = `${colCount++}`;
        th.setAttribute("col", col_id);
        th.setAttribute("activated", "true");
        th.innerHTML = `
        <div class="col-error">La période n'est pas valide</div>
      <div class="mini-form">
          <div class="btngroup" style="justify-content: flex-end;">
                <button class="closeCol" onclick="removeColumn(this)">x</button>
          </div>
          <input type="datetime-local" id="dateStart" value="${dateStart}">
          <input type="datetime-local" id="dateEnd" value="${dateEnd}">
          {{moduleimpl_select|safe}}
          <div id="mass_action_${col_id}" class="mass">
          <input disabled="" type="radio" class="rbtn present" name="mass_action_${col_id}" value="present" onclick="massCol(this)">
          <input disabled="" type="radio" class="rbtn retard" name="mass_action_${col_id}" value="retard" onclick="massCol(this)">
          <input disabled="" type="radio" class="rbtn absent" name="mass_action_${col_id}" value="absent" onclick="massCol(this)">
          <input disabled="" type="radio" class="rbtn aucun" name="mass_action_${col_id}" value="remove" onclick="massCol(this)">
          
          </div>
      </div>
      `;
        table
            .querySelector(".thead .tr")
            .insertBefore(th, document.querySelector("#addColumn"));



        if (dateStart == "") {
            const last = [...document.querySelectorAll("#dateStart")].pop();
            defaultDate(last);
        }

        try {
            const sl = th.querySelector('.dynaSelect');
            sl.id = `dynaSelect_${col_id}`;
            const miniform = sl.parentElement;
            const dateIso = miniform.querySelector("#dateStart").value;
            if (dateIso != "") {
                updateSelect("", `#${sl.id}`, dateIso)
            }

            miniform.querySelector("#dateStart").addEventListener('focusout', (el) => {
                updateSelect("", `#${sl.id}`, el.target.value);
            })




        } catch {
        }

        th.querySelectorAll('input, select.dynaSelect, select#moduleimpl_select').forEach((el) => {
            el.addEventListener("change", () => {
                getAndUpdateCol(col_id);
            })
        })
        const sl = th.querySelector('select');
        sl.addEventListener('change', () => {
            editModuleImpl(sl);
        })

        if (moduleimpl_id != "") {
            sl.value = moduleimpl_id;
        }

        let rows = table.querySelector(".tbody").querySelectorAll(".tr");
        for (let i = 0; i < rows.length; i++) {
            let td = document.createElement("div");
            td.setAttribute("colid", col_id)
            td.classList.add("td", "etat");
            const etudid = rows[i].getAttribute("etudid");
            td.innerHTML = `
              <div class="assi_rbtn" etat="">
                <input class="rbtn present" type="radio" name="etat_${col_id}_${etudid}" value="present" disabled onclick="updateEtudAssiduite(this)">
                <input class="rbtn retard" type="radio" name="etat_${col_id}_${etudid}" value="retard" disabled onclick="updateEtudAssiduite(this)">
                <input class="rbtn absent" type="radio" name="etat_${col_id}_${etudid}" value="absent" disabled onclick="updateEtudAssiduite(this)">
              </div>
              <br/>
            `;


            rows[i].appendChild(td);
            if (assi_etat_defaut != "" && assi_etat_defaut != "aucun") {
                const inp = td.querySelector(`[value='${assi_etat_defaut}']`).checked = true;
            }
        }
    }

    function reOrderEtudiants() {
        const th = document.querySelector(".th.sticky");
        let lines = [...document.querySelectorAll('.tr[etudid]')];
        const tbody = document.querySelector('.tbody')

        let order = (a, b) => { return a > b }

        if (th.getAttribute("order") == "ASC") {
            order = (a, b) => { return b > a }
            th.setAttribute("order", "DESC")
        } else {
            th.setAttribute("order", "ASC")
        }

        lines = lines.sort((a, b) => {
            const nameA = a.querySelector(".td.sticky").textContent.split(" ").pop();
            const nameB = b.querySelector(".td.sticky").textContent.split(" ").pop();
            return order(nameA, nameB)
        })

        tbody.innerHTML = "";
        tbody.append(...lines)
    }

    function previousCol(column) {
        const cols = [...document.querySelectorAll("[col]")]
        let previousCol = null;

        let i = 1;

        while (i < cols.length) {
            previousCol = cols[i - 1];
            if (cols[i] == column)
                break;
            i++;
        }

        return previousCol

    }

    function removeColumn(element) {
        const col = element.parentElement.parentElement.parentElement;
        const col_id = col.getAttribute("col");
        document.querySelectorAll(`[col='${col_id}'],[colid='${col_id}']`).forEach((el) => { el.remove() })
    }

    function defaultDate(element) {
        const num = previousCol(element.parentElement.parentElement)?.getAttribute("col");
        const last = document.querySelector(`[col='${num}'] #dateEnd`);
        let date = undefined;
        if (last == undefined) {
            date = new Date(currentDate);
            const start = typeof mt_start !== 'undefined' ? mt_start : 0
            date.setHours(start);
            date = date.toFakeIso()
        } else {
            date = last.value;
        }

        element.value = date;

        element.addEventListener(
            "focusout",
            () => {
                const el = element.parentElement.querySelector("#dateEnd");
                const el2 = element.parentElement.querySelector("#dateStart");
                const newDate = new Date(el2.valueAsDate)
                    .add(2, "hours");
                el.valueAsDate = newDate;

                const colid = element.parentElement.parentElement.getAttribute('col');
                getAndUpdateCol(colid);
            },
            { once: true }
        );
    }

    function setEtatCol(colId, etatId) {
        const tds = [...document.querySelectorAll(`.td[colid='${colId}']`)]
        tds.forEach((td) => {
            setEtatLine(td, etatId);
        })
    }

    function setEtatLine(line, etatId) {

        let inputs = [...line.querySelectorAll("input")]
        inputs.forEach((el) => { el.checked = false })
        if (etatId !== "") {
            inputs[Number.parseInt(etatId)].checked = true;
            inputs[Number.parseInt(etatId)].parentElement.setAttribute('etat', inputs[Number.parseInt(etatId)].value)
        }

        let color;
        switch (etatId) {
            case 0:
                color = "var(--color-present)";
                break
            case 1:
                color = "var(--color-retard)";
                break
            case 2:
                color = "var(--color-absent)";
                break
            default:
                color = "var(--color-defaut)";
                break;
        }

        line.style.borderColor = color;
    }

    function _createAssiduites(inputDeb, inputFin, moduleSelect, etudid, etat, colId) {
        if (moduleSelect == "") {
            return {
                "date_debut": inputDeb,
                "date_fin": inputFin,
                "etudid": etudid,
                "etat": etat,
                "colid": colId,
            }
        } else {
            return {
                "date_debut": inputDeb,
                "date_fin": inputFin,
                "etudid": etudid,
                "moduleimpl_id": moduleSelect,
                "etat": etat,
                "colid": colId,
            }
        }
    }

    function getAssiduitesCol(col_id, get = true) {
        const col = document.querySelector(`[col='${col_id}']`);
        const colErr = col.querySelector('.col-error')

        const inputDeb = col.querySelector("#dateStart").value;
        const inputFin = col.querySelector("#dateEnd").value;
        const moduleSelect = col.querySelector("#moduleimpl_select,.dynaSelect").value;
        const d_debut = new Date(inputDeb);
        const d_fin = new Date(inputFin);


        if (inputDeb == "" || inputFin == "" || d_debut >= d_fin) {
            colErr.textContent = `La période de la colonne n'est pas valide`;
            return 0x2;
        }

        {% if periode %}
        const t_before = "{{periode.deb}}T00:00";
        const t_after = "{{periode.fin}}T23:59";
        const testPeriode = [
            d_debut.isBefore(t_before),
            d_debut.isAfter(t_after),
            d_fin.isBefore(t_before),
            d_fin.isAfter(t_after),
        ]
        if (testPeriode.some((e) => e)) {
            colErr.textContent = `La période de la colonne n'est pas dans le semestre`;
            return 0x3;
        }
        {% endif %}

        if (window.forceModule && moduleSelect == "") {
            colErr.textContent = `Le module de la colonne n'a pas été entré. (Préférence de semestre)`;
            return 0x4;
        }

        if (get) {
            getAssiduitesFromEtuds(false, d_debut.toFakeIso(), d_fin.toFakeIso())
            return 0x0;
        }

        return {
            moduleimpl: moduleSelect,
            deb: d_debut.toFakeIso(),
            fin: d_fin.toFakeIso(),
        }




    }

    function updateAssiduitesCol(col_id) {
        const col = document.querySelector(`[col='${col_id}']`);
        const tds = [...document.querySelectorAll(`.td[colid='${col_id}']`)]

        const inputDeb = col.querySelector("#dateStart").value;
        const inputFin = col.querySelector("#dateEnd").value;
        const d_debut = new Date(inputDeb);
        const d_fin = new Date(inputFin);

        const moduleimpl_id = col.querySelector("#moduleimpl_select,.dynaSelect").value;

        const periode = {
            deb: d_debut,
            fin: d_fin,
        }

        tds.forEach((td) => {
            tds.forEach((el) => {
                const inputs = [...el.querySelectorAll('input')];
                inputs.forEach((i) => { i.disabled = false })
            });
            setEtatLine(td, "")
            const etu = td.parentElement.getAttribute('etudid');
            const inscriptionModule = ["", "autre"].indexOf(moduleimpl_id) !== -1 ? true : checkInscriptionModule(moduleimpl_id, etu);
            const conflits = getAssiduitesConflict(etu, periode);
            if (!inscriptionModule) {
                td.setAttribute('assiduite_id', "insc");
            }
            else if (conflits.length == 0) {
                td.setAttribute('assiduite_id', "-1");
            } else if (conflits.length == 1 && isConflictSameAsPeriod(conflits[0], periode)) {
                const assi = conflits[0];
                td.setAttribute('assiduite_id', assi.assiduite_id);
                const ind = ["PRESENT", "RETARD", "ABSENT"].indexOf(assi.etat.toUpperCase());
                setEtatLine(td, ind)
            } else {
                td.setAttribute('assiduite_id', "conflit");
                const inputs = [...td.querySelectorAll('input')];
                inputs.forEach((i) => {
                    i.disabled = true;
                })
            }
        })
    }

    function setEtuds() {
        if (!isSingleEtud()) {
            const etudids = [...document.querySelectorAll("[etudid]")]
                .map((el) => Number.parseInt(el.getAttribute("etudid")))
                .filter((value, index, array) => array.indexOf(value) === index);

            etudids.forEach((etu) => {
                etuds[etu] = { etudid: etu }
            })
        }
    }

    function getAndUpdateCol(colid) {
        const column = document.querySelector(`[col='${colid}']`);
        if (getAssiduitesCol(colid) == 0) {
            column.classList.remove('error');
            document.getElementById(`mass_action_${colid}`).querySelectorAll('.rbtn').forEach((el) => {
                el.removeAttribute('disabled');
            })
            updateAssiduitesCol(colid)
        } else {
            document.getElementById(`mass_action_${colid}`).querySelectorAll('.rbtn').forEach((el) => {
                el.setAttribute('disabled', '');
            })
            column.classList.add('error');
            const tds = [...document.querySelectorAll(`.td[colid='${colid}']`)]
            tds.forEach((el) => {
                const inputs = [...el.querySelectorAll('input')];
                inputs.forEach((i) => { i.disabled = true })
            });
        }
    }

    function updateAllCol() {
        const colIds = [...document.querySelectorAll("[col]")].map((col) => { return col.getAttribute('col') });
        colIds.forEach((colid) => {
            getAndUpdateCol(colid)
        })

        if (isSingleEtud()) {
            actualizeEtud(etudid);
        }
    }

    function launchToast(etudid, etat) {
        let etatAffiche;

        switch (etat.toUpperCase()) {
            case "PRESENT":
                etatAffiche =
                    "%etud% a été noté(e) <u><strong>présent(e)</strong></u>";
                break;
            case "RETARD":
                etatAffiche =
                    "%etud% a été noté(e) <u><strong>en retard</strong></u>";
                break;
            case "ABSENT":
                etatAffiche =
                    "%etud% a été noté(e) <u><strong>absent(e)</strong></u>";
                break;
            case "REMOVE":
                etatAffiche = "L'assiduité de %etud% a été retirée.";
        }

        let color;

        switch (etat.toUpperCase()) {
            case "PRESENT":
                color = "var(--color-present)";
                break;
            case "ABSENT":
                color = "var(--color-absent)";
                break;
            case "RETARD":
                color = "var(--color-retard)";
                break;
            default:
                color = "#AAA";
                break;
        }

        const nom_prenom = document.querySelector(`.tr[etudid="${etudid}"] .td span`).textContent
        const span = document.createElement("span");
        span.innerHTML = etatAffiche.replace("%etud%", nom_prenom);

        pushToast(generateToast(span, color, 5));
    }

    function updateEtudAssiduite(rbtn) {
        const [_, colid, etudid] = rbtn.name.split("_");

        const etat = rbtn.value;

        const etudLine = rbtn.parentElement.parentElement;

        const assi = etudLine.getAttribute('assiduite_id');

        const { moduleimpl, deb, fin } = getAssiduitesCol(colid, false);

        switch (assi) {
            case "-1":
                // création d'une nouvelle assiduité
                const assiduite = _createAssiduites(deb, fin, moduleimpl, etudid, etat, colid);
                rbtn.parentElement.setAttribute('etat', etat);
                asyncCreateAssiduite(assiduite, (data) => {
                    if (Object.keys(data.success).length > 0) {
                        const assi_id = data.success['0'].message.assiduite_id;
                        etudLine.setAttribute('assiduite_id', assi_id);
                        assiduite["assiduite_id"] = assi_id;
                        assiduites[etudid].push(assiduite);
                        updateAllCol()
                        launchToast(etudid, etat);
                    } else {
                        let error = data.errors[Object.keys(data.errors)[0]];
                        if (error.message.indexOf("Module") != -1) {
                            const html = `
                            <h3>Aucun module n'a été spécifié (préférence du semestre concerné)</h3>
                            `;
                            const div = document.createElement("div");
                            div.innerHTML = html;
                            openAlertModal("Erreur Module", div);
                            rbtn.checked = false;
                        }
                    }


                })
                break;
            case "conflit":
                // Conflit, afficher résolveur
                const assiduitesList = assiduites[etudid];
                const d_debut = new Date(deb);
                const d_fin = new Date(fin);

                const period = {
                    deb: deb,
                    fin: fin,
                }
                const conflitResolver = new ConflitResolver(
                    assiduites[etudid],
                    period,
                    {
                        deb: d_debut.startOf('day'),
                        fin: d_fin.endOf('day'),
                    }
                );
                const update = () => {
                    assiduites = {}
                    const cols = [...document.querySelectorAll("[col]")].map((col) => col.getAttribute('col'));

                    cols.forEach((c) => getAndUpdateCol(c));

                };
                conflitResolver.callbacks = {
                    delete: update,
                    edit: update,
                    split: update,
                };

                conflitResolver.open();
                rbtn.checked = false;
                break;
            default:
                // Une assiduité est déjà connue -> modifier assiduité

                if (etat == rbtn.parentElement.getAttribute('etat')) {
                    asyncRemoveAssiduite(assi, () => {
                        etudLine.setAttribute('assiduite_id', "-1");
                        rbtn.parentElement.setAttribute('etat', "")
                        assiduites[etudid] = assiduites[etudid].filter((el) => { return el.assiduite_id != assi })
                        updateAllCol()
                        launchToast(etudid, "remove");
                    })
                } else {
                    const edit = {
                        moduleimpl_id: moduleimpl == "" ? null : moduleimpl,
                        etat: etat,
                        assiduite_id: Number.parseInt(assi),
                    }

                    asyncEditAssiduite(edit, (data) => {
                        const obj = structuredClone(getAssiduite(etudid, assi)[0])
                        obj.moduleimpl = edit.moduleimpl_id;
                        obj.etat = edit.etat;
                        replaceAssiduite(etudid, assi, obj)
                        launchToast(etudid, etat);
                        updateAllCol()
                    })
                }
                break;
        }

    }

    function getAssiduite(etudid, id) {
        return assiduites[etudid].filter((a) => a.assiduite_id == id)
    }

    function replaceAssiduite(etudid, id, obj) {
        assiduites[etudid] = assiduites[etudid].filter((a) => a.assiduite_id != id);
        assiduites[etudid].push(obj)
    }

    function asyncCreateAssiduite(assi, callback = () => { }) {
        const path = getUrl() + `/api/assiduite/${assi.etudid}/create`;
        async_post(
            path,
            [assi],
            callback,
            (data, status) => {
                //error
                console.error(data, status);
                errorAlert();
            }
        );
    }

    function asyncRemoveAssiduite(assi, callback = () => { }) {
        const path = getUrl() + `/api/assiduite/delete`;
        async_post(
            path,
            [assi],
            callback,
            (data, status) => {
                //error
                console.error(data, status);
                errorAlert();
            }
        );
    }

    function asyncEditAssiduite(assi, callback = () => { }) {
        const path = getUrl() + `/api/assiduite/${assi.assiduite_id}/edit`;
        async_post(
            path,
            assi,
            callback,
            (data, status) => {
                //error
                console.error(data, status);
                errorAlert();
            }
        );
    }

    function asyncCreateAssiduiteGroup(assis, callback = () => { }) {
        const path = getUrl() + `/api/assiduites/create`;
        return async_post(
            path,
            assis,
            callback,
            (data, status) => {
                //error
                console.error(data, status);
                errorAlert();
            }
        );
    }

    function asyncEditAssiduiteGroup(assis, callback = () => { }) {
        const path = getUrl() + `/api/assiduites/edit`;
        return async_post(
            path,
            assis,
            callback,
            (data, status) => {
                console.error(data, status);
                errorAlert();
            }
        );
    }

    function asyncDeleteAssiduiteGroup(assis, callback = () => { }) {
        const path = getUrl() + `/api/assiduite/delete`;
        async_post(
            path,
            assis,
            callback,
            (data, status) => {
                //error
                console.error(data, status);
                errorAlert();
            }
        );
    }

    function massCol(rbtn) {
        const colid = rbtn.name.replace("mass_action_", "");
        const col = document.querySelector(`[col="${colid}"]`);
        const etat = rbtn.value;

        const { moduleimpl, deb, fin } = getAssiduitesCol(colid, false);

        const lines = [...document.querySelectorAll(`[assiduite_id][colid='${colid}']`)].filter((el) => {
            return ["conflit", "insc"].indexOf(el.getAttribute('assiduite_id')) == -1;
        })

        const toCreate = lines.filter((el) => { return el.getAttribute('assiduite_id') == '-1' })
        const toEdit = lines.filter((el) => { return el.getAttribute('assiduite_id') != '-1' })

        if (etat == "remove") {
            const removeList = []
            toEdit.forEach((el) => {
                removeList.push(Number.parseInt(el.getAttribute('assiduite_id')))
            })

            asyncDeleteAssiduiteGroup(removeList, () => {
                const span = document.createElement("span");
                if (removeList.length > 0) {
                    span.innerHTML = `${removeList.length} assiduités ont été supprimées.`;
                } else {
                    span.innerHTML = `Aucune assiduité n'a été supprimée.`;
                }

                toEdit.forEach((el) => {
                    const assi_id = Number.parseInt(el.getAttribute("assiduite_id"));
                    const etudid = Number.parseInt(el.parentElement.getAttribute('etudid'));
                    assiduites[etudid] = assiduites[etudid].filter((a) => { return a.assiduite_id != assi_id });
                })

                updateAllCol()

                pushToast(generateToast(span, getToastColorFromEtat("remove"), 5));
            })
        } else {

            const createList = []
            const editList = []

            toCreate.forEach((el) => {
                const etudid = Number.parseInt(el.parentElement.getAttribute('etudid'));
                createList.push(_createAssiduites(deb, fin, moduleimpl, etudid, etat, colid))
            })
            toEdit.forEach((el) => {
                const edit = {
                    moduleimpl_id: moduleimpl == "" ? null : moduleimpl,
                    etat: etat,
                    assiduite_id: Number.parseInt(el.getAttribute('assiduite_id')),
                    etudid: Number.parseInt(el.parentElement.getAttribute('etudid')),
                }

                editList.push(edit);
            })
            const values = { "create": {}, "edit": {} };
            Promise.all(
                [asyncCreateAssiduiteGroup(createList, (data) => {
                    values.create = data;
                }),

                asyncEditAssiduiteGroup(editList, (data) => {
                    values.edit = data;

                })]
            ).then(() => {
                const c = values.create;
                const e = values.edit;
                let error;
                Object.keys(c.success).forEach((k) => {
                    const assiduite = createList[Number.parseInt(k)];
                    assiduite["assiduite_id"] = c.success[k].message.assiduite_id;
                    assiduites[assiduite.etudid].push(assiduite);
                })
                if (c.errors.length > 0) {
                    error = c.errors[Object.keys(c.errors)[0]];
                    if (error.message.indexOf("Module") != -1) {
                        const html = `
                            <h3>Aucun module n'a été spécifié (préférence du semestre concerné)</h3>
                            `;
                        const div = document.createElement("div");
                        div.innerHTML = html;
                        openAlertModal("Erreur Module", div);
                        toCreate.length = 0
                    }
                }
                Object.keys(e.success).forEach((k) => {
                    const { etudid, assiduite_id, moduleimpl_id, etat } = editList[Number.parseInt(k)]
                    assiduites[etudid].map((a) => {
                        if (a.assiduite_id == assiduite_id) {
                            a.moduleimpl_id = moduleimpl_id
                            a.etat = etat.toUpperCase();
                        } else {
                            return a
                        }
                    })
                })

                updateAllCol();


                const count = toCreate.length + toEdit.length;
                const etatAffiche =
                    etat.toUpperCase() == "RETARD"
                        ? "En retard"
                        : etat;
                const span = document.createElement("span");
                if (count > 0) {
                    span.innerHTML = `${count} étudiants ont été mis <u><strong>${etatAffiche
                        .capitalize()
                        .trim()}</strong></u>`;
                } else {
                    span.innerHTML = `Aucun étudiant n'a été mis <u><strong>${etatAffiche
                        .capitalize()
                        .trim()}</strong></u>`;
                }

                pushToast(
                    generateToast(
                        span,
                        getToastColorFromEtat(etat.toUpperCase()),
                        5
                    )
                );
            })
        }
        rbtn.checked = false;
    }

    function editModuleImpl(select) {
        const col = select.parentElement.parentElement
        const colid = col.getAttribute('col')
        const value = select.value;

        const lines = [...document.querySelectorAll(`[assiduite_id][colid='${colid}']`)].filter((el) => {
            return el.getAttribute('assiduite_id') != "conflit";
        })

        const toEdit = lines.filter((el) => { return el.getAttribute('assiduite_id') != '-1' })

        let editList = toEdit.map((e) => {
            return {
                assiduite_id: Number.parseInt(e.getAttribute('assiduite_id')),
                etudid: Number.parseInt(e.parentElement.getAttribute('etudid')),
                moduleimpl_id: value,
            }
        });

        asyncEditAssiduiteGroup(editList, (data) => {
            Object.keys(data.success).forEach((k) => {
                const { etudid, assiduite_id, moduleimpl_id } = editList[Number.parseInt(k)]
                assiduites[etudid].map((a) => {
                    if (a.assiduite_id == assiduite_id) {
                        a.moduleimpl_id = moduleimpl_id
                    } else {
                        return a
                    }
                })
            })

            if (Object.keys(data.success).length > 0) {
                const span = document.createElement("span");
                span.innerHTML = `Le module a bien été changé.`;

                pushToast(generateToast(span, getToastColorFromEtat("remove"), 5));
            }

        })
    }



    window.addEventListener('load', () => {
        document.getElementById("addColumn").addEventListener("click", () => {
            createColumn();
        });

        setEtuds();

        document.querySelectorAll('.pdp-hover').forEach((el) => {
            el.src = getUrl() + `/api/etudiant/etudid/${el.getAttribute('etudid')}/photo?size=small`;
        })
    }, { once: true });

</script>