<!--

    Queue - A Queueing system that can be used to handle labs in higher education
    Copyright (C) 2016-2024  Delft University of Technology

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.

-->
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{lab/enqueue}">
    <!--@thymesVar id="edition" type="nl.tudelft.labracore.api.dto.EditionDetailsDTO"-->

    <!--@thymesVar id="qSession" type="nl.tudelft.queue.model.labs.Lab"-->
    <!--@thymesVar id="request" type="nl.tudelft.queue.dto.create.requests.LabRequestCreateDTO"-->

    <!--@thymesVar id="rooms" type="java.util.List<nl.tudelft.labracore.api.dto.RoomDetailsDTO>"-->
    <!--@thymesVar id="assignments" type="java.util.Map<nl.tudelft.labracore.api.dto
.AssignmentSummaryDTO, java.lang.String>"-->
    <!--@thymesVar id="types" type="java.util.Map<java.lang.Long, java.util.Set<java.lang.String>>"-->

    <!--@thymesVar id="message" type="java.lang.String"-->

    <head>
        <script src="/webjars/fullcalendar/index.global.js"></script>
        <script src="/webjars/momentjs/min/moment.min.js"></script>
        <script src="/js/time_slots.js"></script>

        <style>
            .fc-event:not(.disabled) {
                cursor: pointer;
            }
            .fc-event:not(.disabled):where(:hover, :focus-visible) {
                background-color: var(--primary-active-colour) !important;
            }
        </style>
    </head>

    <body>
        <th:block th:obj="${request}">
            <div class="flex vertical gap-3" layout:fragment="enqueue-body">
                <div th:if="${qSession.type != T(nl.tudelft.queue.model.enums.QueueSessionType).REGULAR}">
                    <div class="grid col-2 gap-1 | md:col-1" style="--col-1: 14rem">
                        <span>Select a time slot</span>
                        <div id="slot-select" style="max-height: 30rem"></div>
                    </div>
                    <p class="fw-500 colour-error" hidden id="time-slot-warning">Please select a time slot</p>
                    <div>
                        <span>Selected time slot:</span>
                        <span id="selected-slot" class="fw-500">none</span>
                        <input type="hidden" name="timeSlot.id" required />
                    </div>
                    <script th:inline="javascript">
                        document.addEventListener("DOMContentLoaded", function () {
                            let timeSlots = new TimeSlotCollection();

                            // All slots from DTO
                            const slotDTOs = /*[[${qSession.timeSlots}]]*/ [];
                            const canTake = /*[[${qSession.timeSlots.![#this.canTakeSlot()]}]]*/ [];
                            for (let i = 0; i < slotDTOs.length; i++) {
                                let slot = TimeSlot.fromDTO(slotDTOs[i]);
                                slot.disabled = !canTake[i];
                                slot.untakable = !canTake[i];
                                timeSlots.addSlot(slot);
                            }

                            let range = timeSlots.range;

                            // Calendar for selecting a slot
                            const slotSelect = new Calendar(
                                new FullCalendar.Calendar(document.getElementById("slot-select"), {
                                    initialView: "timeGridSomeDays",
                                    locale: "gb",
                                    firstDay: 1,
                                    slotDuration: "00:10",
                                    allDaySlot: false,
                                    nowIndicator: true,
                                    headerToolbar: {
                                        left: "title",
                                        right: "prev,next",
                                    },
                                    validRange: {
                                        start: range.start.toDate(),
                                        end: range.end.toDate(),
                                    },
                                    views: {
                                        timeGridSomeDays: {
                                            type: "timeGrid",
                                            duration: { days: Math.min(7, range.end.diff(range.start, "days")) },
                                        },
                                    },
                                    scrollTime: timeSlots.timeRange.start,
                                }),
                                timeSlots,
                                {
                                    onSelect: ts => {
                                        const day = ts.start.format("dddd D MMMM");
                                        const from = ts.start.format("H:mm");
                                        const to = ts.end.format("H:mm");

                                        document.getElementById("selected-slot").innerText = `${day} ${from} - ${to}`;

                                        document.getElementById("enqueue").removeAttribute("disabled");
                                        document.getElementById("time-slot-warning").setAttribute("hidden", "");
                                        document.querySelector("[name='timeSlot.id']").setAttribute("value", timeSlots.selected.id);
                                    },
                                }
                            );
                            slotSelect.show();

                            // Show error if trying to enqueue without slot
                            document.getElementById("enqueue-form").addEventListener("submit", function (event) {
                                if (timeSlots.selected === undefined) {
                                    document.getElementById("time-slot-warning").removeAttribute("hidden");
                                    event.preventDefault();
                                    event.stopPropagation();
                                }
                            });
                        });
                    </script>
                </div>

                <div>
                    <label for="input-assignment">Assignment</label>

                    <div>
                        <select id="input-assignment" th:field="*{assignment}" data-placeholder="Pick an assignment" data-select required>
                            <option th:each="entry : ${assignments}" th:value="${entry.key}" th:text="${entry.value}"></option>
                        </select>
                    </div>
                    <div
                        th:each="entry : ${assignments}"
                        th:if="${notEnqueueAble.getOrDefault(entry.key, null) != null}"
                        class="colour-error"
                        style="display: none"
                        th:id="|not-enrolled-${entry.key}|">
                        You're not enrolled for the course containing this assignment. Click
                        <a class="link" th:href="@{/edition/{id}/enrol(id=${notEnqueueAble.get(entry.key)})}">here</a>
                        to enrol.
                    </div>
                    <div
                        th:each="entry : ${assignments}"
                        th:if="${needToJoinGroup.contains(entry.key)}"
                        class="colour-error"
                        style="display: none"
                        th:id="|need-group-${entry.key}|">
                        This assignment uses groups. Join a group
                        <a class="link" th:href="@{/assignment/{id}/groups(id=${entry.key})}">here</a>
                        first to enqueue.
                    </div>
                    <div class="colour-error" th:if="${#fields.hasErrors('assignment')}" th:errors="*{assignment}">Assignment error</div>
                </div>

                <div>
                    <label for="input-type">Type</label>

                    <div>
                        <select
                            class="textfield"
                            id="input-type"
                            th:field="*{requestType}"
                            data-placeholder="Pick a type"
                            data-select
                            required
                            disabled>
                            <option
                                th:each="type : ${T(nl.tudelft.queue.model.enums.RequestType).values()}"
                                th:id="|input-type-${type.name()}|"
                                th:value="${type}"
                                th:text="${type.displayName()}"
                                th:disabled="${qSession.allowedRequests.contains(type)}"></option>
                        </select>
                    </div>

                    <div th:unless="${#sets.isEmpty(qSession.onlineModes)}">
                        <label for="mode-select">Mode:</label>
                        <select id="mode-select" data-select required>
                            <option value="room">In-person</option>
                            <option value="onlineMode">Online</option>
                        </select>
                    </div>

                    <div class="colour-error" th:if="${#fields.hasErrors('requestType')}" th:errors="*{requestType}">Type error</div>
                </div>

                <div
                    id="room-div"
                    th:class="${qSession.enableExperimental ? 'd-none' : ''} + ${#lists.isEmpty(rooms) or not #sets.isEmpty(qSession.onlineModes) ? 'hidden' : '' }">
                    <label for="input-room">Room</label>

                    <div>
                        <select class="textfield" id="input-room" th:field="*{room}" data-select required>
                            <optgroup th:each="building : ${buildings}" th:label="${building.name}">
                                <option
                                    th:each="room : ${rooms.?[#this.building.id == #root.building.id]}"
                                    th:value="${room.id}"
                                    th:text="${room.name}"></option>
                            </optgroup>
                        </select>
                    </div>
                    <div class="colour-error" th:if="${#fields.hasErrors('room')}" th:errors="*{room}">Room error</div>
                </div>

                <div
                    id="onlineMode-div"
                    class="hidden"
                    th:unless="${#sets.isEmpty(qSession.onlineModes)}"
                    th:classappend="${qSession.enableExperimental ? 'd-none' : ''}">
                    <label for="input-onlineMode">Online Mode</label>

                    <div>
                        <select class="textfield" id="input-onlineMode" th:field="*{onlineMode}" data-select required>
                            <option
                                th:each="onlineMode : ${qSession.onlineModes}"
                                th:id="|input-onlineMode-${onlineMode.name()}|"
                                th:value="${onlineMode}"
                                th:text="|${onlineMode.getDisplayName()}|"></option>
                        </select>
                    </div>
                    <div class="colour-error" th:if="${#fields.hasErrors('onlineMode')}" th:errors="*{onlineMode}">Online Mode error</div>
                </div>

                <div id="language-div" th:if="${qSession.isBilingual}">
                    <label for="input-language">Language</label>
                    <div>
                        <select id="input-language" data-select name="language">
                            <option selected value="ANY">English</option>
                            <option value="DUTCH_ONLY">Dutch</option>
                        </select>
                    </div>
                </div>

                <div id="question-div" th:classappend="${qSession.enableExperimental ? 'd-none' : ''}">
                    <label for="input-question" class="col-sm-2 control-label">Question</label>
                    <div class="flex vertical gap-1">
                        <textarea
                            minlength="15"
                            maxlength="500"
                            class="textfield"
                            onkeyup="countChar(this)"
                            id="input-question"
                            th:field="*{question}"
                            placeholder="Write your question here"
                            required
                            disabled></textarea>
                        <p id="charCount">0/500</p>
                    </div>
                </div>

                <div
                    id="comment-div"
                    th:class="${qSession.enableExperimental ? 'd-none' : ''} + ${#lists.isEmpty(rooms) or not #sets.isEmpty(qSession.onlineModes) ? 'hidden' : '' }">
                    <div class="flex vertical gap-1">
                        <label for="input-comment" id="labelComment">Help your TA find you!</label>

                        <div id="image-holder" class="mt-1 mb-3" hidden>
                            <img alt="Room map" />
                        </div>

                        <textarea
                            maxlength="250"
                            th:classappend="${#fields.hasErrors('comment')} ? 'is-invalid'"
                            class="textfield"
                            id="input-comment"
                            th:field="*{comment}"
                            th:text="${lastKnownLocation}"
                            th:placeholder="'You can use this field to specify a location within the room, e.g. your cubicle number.'"></textarea>

                        <div class="colour-error" th:if="${#fields.hasErrors('comment')}" th:errors="*{comment}">Comment error</div>
                    </div>
                </div>

                <script src="/webjars/momentjs/min/moment.min.js"></script>
                <script src="/js/map_loader.js"></script>

                <script type="text/javascript" th:inline="javascript">
                    function checkEnrolled(val) {
                        $(".enrollment-status").css("display", "none");
                        $("#enqueue").prop("disabled", false);
                        const divError = $(`#not-enrolled-${val}`);
                        if (divError.length) {
                            $("#not-enrolled-" + val).css("display", "block");
                            $("#enqueue").prop("disabled", true);
                        }
                    }

                    function checkGroup(val) {
                        const enqueue = document.getElementById("enqueue");
                        const error = document.getElementById(`need-group-${val}`);
                        enqueue.removeAttribute("disabled");
                        if (error) {
                            error.style.setProperty("display", "block");
                            enqueue.setAttribute("disabled", "");
                        }
                    }

                    document.addEventListener("ComponentsLoaded", function () {
                        //<![CDATA[
                        const typesPerAssignment = /*[[${types}]]*/ { 1: ["bla"] };
                        //]]>

                        const assignmentSelect = document.getElementById("input-assignment");
                        const typeSelect = document.getElementById("input-type");

                        const questionInput = document.getElementById("input-question");

                        const modeSelect = document.getElementById("mode-select");

                        assignmentSelect.addEventListener("change", function () {
                            checkEnrolled(this.value);
                            checkGroup(this.value);

                            typeSelect.querySelectorAll("option").forEach(opt => opt.removeAttribute("selected"));
                            typeSelect.removeAttribute("disabled");

                            const types = typesPerAssignment[this.value].map(s => s.toLowerCase());
                            typeSelect.querySelectorAll("option").forEach(opt => {
                                if (types.includes(opt.value.toLowerCase())) {
                                    opt.removeAttribute("disabled");
                                } else {
                                    opt.setAttribute("disabled", "");
                                }
                            });

                            typeSelect.update();

                            if (/*[[${qSession.enableExperimental}]]*/ false) {
                                $("#room-div")[0].classList.add("d-none");
                                $("#comment-div")[0].classList.add("d-none");
                                $("#enqueue")[0].innerText = "Enqueue";
                                $("#input-room").prop("disabled", false);
                            }
                        });

                        typeSelect.addEventListener("change", function () {
                            if (this.value.toLowerCase() === "question") {
                                questionInput.removeAttribute("disabled");
                            } else {
                                questionInput.setAttribute("disabled", "");
                            }

                            if (/*[[${qSession.enableExperimental}]]*/ false) {
                                if (this.value.toLowerCase() === "question") {
                                    $("#room-div")[0].classList.add("d-none");
                                    $("#comment-div")[0].classList.add("d-none");
                                    $("#enqueue")[0].innerText = "Continue";
                                    $("#input-room").prop("disabled", true);
                                    questionInput.setAttribute("disabled", "");
                                } else {
                                    $("#room-div")[0].classList.remove("d-none");
                                    $("#comment-div")[0].classList.remove("d-none");
                                    $("#enqueue")[0].innerText = "Enqueue";
                                    $("#input-room").prop("disabled", false);
                                }
                            }
                        });

                        if (modeSelect != null) {
                            modeSelect.addEventListener("change", function () {
                                const selectedMode = modeSelect.value;
                                const selectedSection = document.getElementById(selectedMode + "-div");
                                const unselectedSection = document.getElementById(selectedMode === "room" ? "onlineMode-div" : "room-div");
                                const commentDiv = document.getElementById("comment-div");
                                const commentInput = document.getElementById("input-comment");
                                const selectedInput = document.getElementById("input-" + selectedMode);
                                const unselectedInput = document.getElementById("input-" + (selectedMode === "room" ? "onlineMode" : "room"));
                                if (selectedSection) {
                                    selectedSection.classList.remove("hidden");
                                    selectedInput.setAttribute("required", "");
                                    selectedInput.setAttribute("data-select", "true");
                                    selectedInput.update();
                                }
                                if (unselectedSection) {
                                    unselectedSection.classList.add("hidden");
                                    unselectedInput.querySelectorAll("option").forEach(opt => (opt.selected = false));
                                    unselectedInput.querySelectorAll("option").forEach(opt => opt.removeAttribute("selected"));
                                    selectedInput.setAttribute("data-select", "false");
                                    unselectedInput.removeAttribute("required");
                                    unselectedInput.update();
                                }

                                if (selectedMode === "room") {
                                    commentDiv.classList.remove("hidden");
                                } else {
                                    commentDiv.classList.add("hidden");
                                }

                                if (selectedMode !== "room" && commentInput) {
                                    commentInput.value = "";
                                    commentInput.removeAttribute("disabled");
                                }
                            });
                        }
                    });
                </script>
            </div>
        </th:block>
    </body>
</html>
