<div class="timeline-container">
    <div class="period" style="left: 0%; width: 20%">
        <div class="period-handle left"></div>
        <div class="period-handle right"></div>
    </div>
</div>
<script>


    const timelineContainer = document.querySelector(".timeline-container");
    const periodTimeLine = document.querySelector(".period");

    function createTicks() {
        for (let i = 8; i <= 18; i++) {
            const hourTick = document.createElement("div");
            hourTick.classList.add("tick", "hour");
            hourTick.style.left = `${((i - 8) / 10) * 100}%`;
            timelineContainer.appendChild(hourTick);

            const tickLabel = document.createElement("div");
            tickLabel.classList.add("tick-label");
            tickLabel.style.left = `${((i - 8) / 10) * 100}%`;
            tickLabel.textContent = i < 10 ? `0${i}:00` : `${i}:00`;
            timelineContainer.appendChild(tickLabel);

            if (i < 18) {
                for (let j = 1; j < 4; j++) {
                    const quarterTick = document.createElement("div");
                    quarterTick.classList.add("tick", "quarter");
                    quarterTick.style.left = `${((i - 8 + j / 4) / 10) * 100}%`;
                    timelineContainer.appendChild(quarterTick);
                }
            }
        }
    }

    function snapToQuarter(value) {
        return Math.round(value * 4) / 4;
    }

    function setupTimeLine(callback) {
        const func_call = callback ? callback : () => { }
        timelineContainer.addEventListener("mousedown", (event) => {
            const startX = event.clientX;

            if (event.target === periodTimeLine) {
                const startLeft = parseFloat(periodTimeLine.style.left);

                const onMouseMove = (moveEvent) => {
                    const deltaX = moveEvent.clientX - startX;
                    const containerWidth = timelineContainer.clientWidth;
                    const newLeft = startLeft + (deltaX / containerWidth) * 100;

                    adjustPeriodPosition(newLeft, parseFloat(periodTimeLine.style.width));
                };

                document.addEventListener("mousemove", onMouseMove);
                document.addEventListener(
                    "mouseup",
                    () => {
                        generateAllEtudRow();
                        snapHandlesToQuarters()
                        document.removeEventListener("mousemove", onMouseMove);
                        func_call()
                    },
                    { once: true }
                );
            } else if (event.target.classList.contains("period-handle")) {
                const startWidth = parseFloat(periodTimeLine.style.width);
                const startLeft = parseFloat(periodTimeLine.style.left);
                const isLeftHandle = event.target.classList.contains("left");

                const onMouseMove = (moveEvent) => {
                    const deltaX = moveEvent.clientX - startX;
                    const containerWidth = timelineContainer.clientWidth;
                    const newWidth =
                        startWidth + ((isLeftHandle ? -deltaX : deltaX) / containerWidth) * 100;

                    if (isLeftHandle) {
                        const newLeft = startLeft + (deltaX / containerWidth) * 100;
                        adjustPeriodPosition(newLeft, newWidth);
                    } else {
                        adjustPeriodPosition(parseFloat(periodTimeLine.style.left), newWidth);
                    }
                };

                document.addEventListener("mousemove", onMouseMove);
                document.addEventListener(
                    "mouseup",
                    () => {
                        snapHandlesToQuarters()
                        generateAllEtudRow();

                        document.removeEventListener("mousemove", onMouseMove);

                        func_call()

                    },
                    { once: true }
                );
            }
        });
    }

    function adjustPeriodPosition(newLeft, newWidth) {

        const snappedLeft = snapToQuarter(newLeft);
        const snappedWidth = snapToQuarter(newWidth);
        const minLeft = 0;
        const maxLeft = 100 - snappedWidth;

        const clampedLeft = Math.min(Math.max(snappedLeft, minLeft), maxLeft);

        periodTimeLine.style.left = `${clampedLeft}%`;
        periodTimeLine.style.width = `${snappedWidth}%`;
    }

    function getPeriodValues() {
        const leftPercentage = parseFloat(periodTimeLine.style.left);
        const widthPercentage = parseFloat(periodTimeLine.style.width);

        const startHour = (leftPercentage / 100) * 10 + 8;
        const endHour = ((leftPercentage + widthPercentage) / 100) * 10 + 8;

        const startValue = Math.round(startHour * 4) / 4;
        const endValue = Math.round(endHour * 4) / 4;

        return [startValue, endValue]
    }

    function setPeriodValues(deb, fin) {
        let leftPercentage = (deb - 8) / 10 * 100
        let widthPercentage = (fin - deb) / 10 * 100
        periodTimeLine.style.left = `${leftPercentage}%`
        periodTimeLine.style.width = `${widthPercentage}%`

        snapHandlesToQuarters()
        generateAllEtudRow();
    }

    function snapHandlesToQuarters() {
        const periodValues = getPeriodValues();
        let lef = Math.min((periodValues[0] - 8) * 10, 97.5)
        if (lef < 0) {
            lef = 0;
        }
        const left = `${lef}%`
        let wid = Math.max((periodValues[1] - periodValues[0]) * 10, 2.5)
        if (wid > 100) {
            wid = 100;
        }
        const width = `${wid}%`
        periodTimeLine.style.left = left;
        periodTimeLine.style.width = width;
    }

    createTicks();

</script>
<style>
    .timeline-container {
        width: 75%;
        margin-left: 5%;
        background-color: white;
        border-radius: 15px;
        position: relative;
        height: 40px;
    }

    /* ... */
    .tick {
        position: absolute;
        bottom: 0;
        width: 1px;
        background-color: rgba(0, 0, 0, 0.5);
    }

    .tick.hour {
        height: 100%;
    }

    .tick.quarter {
        height: 50%;
    }

    .tick-label {
        position: absolute;
        bottom: 0;
        font-size: 12px;
        text-align: center;
        transform: translateY(100%) translateX(-50%);
        user-select: none;
        -webkit-user-select: none;
        -moz-user-select: none;
        -ms-user-select: none;
    }


    .period {
        position: absolute;
        height: 100%;
        background-color: rgba(0, 183, 255, 0.5);
        border-radius: 15px;
    }

    .period-handle {
        position: absolute;
        top: 0;
        bottom: 0;
        width: 8px;
        border-radius: 0 4px 4px 0;
        cursor: col-resize;
    }

    .period-handle.right {
        right: 0;
        border-radius: 4px 0 0 4px;
    }
</style>