
document.addEventListener("DOMContentLoaded", function () {
    const tableBody = document.querySelector("table tbody");
    let draggingEle;
    let placeholder;
    let isDraggingStarted = false;
    let x = 0;
    let y = 0;

    const swap = function (nodeA, nodeB) {
        const parentA = nodeA.parentNode;
        const siblingA = nodeA.nextSibling === nodeB ? nodeA : nodeA.nextSibling;
        nodeB.parentNode.insertBefore(nodeA, nodeB);
        parentA.insertBefore(nodeB, siblingA);
    };

    const mouseDownHandler = function (e) {
        draggingEle = e.target.parentNode;
        x = e.clientX;
        y = e.clientY;

        const rect = draggingEle.getBoundingClientRect();
        placeholder = document.createElement("tr");
        placeholder.classList.add("placeholder");
        placeholder.style.height = `${rect.height}px`;
        draggingEle.parentNode.insertBefore(placeholder, draggingEle.nextSibling);

        draggingEle.classList.add("dragging");
        document.addEventListener("mousemove", mouseMoveHandler);
        document.addEventListener("mouseup", mouseUpHandler);
    };

    const mouseMoveHandler = function (e) {
        const dx = e.clientX - x;
        const dy = e.clientY - y;

        if (!isDraggingStarted) {
            isDraggingStarted = true;
            draggingEle.style.position = "absolute";
            draggingEle.style.zIndex = 1000;
        }

        draggingEle.style.top = `${draggingEle.offsetTop + dy}px`;
        draggingEle.style.left = `${draggingEle.offsetLeft + dx}px`;

        x = e.clientX;
        y = e.clientY;

        const prevEle = placeholder.previousElementSibling;
        const nextEle = placeholder.nextElementSibling;

        if (prevEle && isAbove(draggingEle, prevEle)) {
            swap(placeholder, prevEle);
            return;
        }

        if (nextEle && isAbove(nextEle, draggingEle)) {
            swap(nextEle, placeholder);
        }
    };

    const mouseUpHandler = function () {
        placeholder.parentNode.insertBefore(draggingEle, placeholder);
        draggingEle.style.removeProperty("top");
        draggingEle.style.removeProperty("left");
        draggingEle.style.removeProperty("position");
        draggingEle.classList.remove("dragging");
        placeholder && placeholder.remove();

        isDraggingStarted = false;
        draggingEle = null;

        document.removeEventListener("mousemove", mouseMoveHandler);
        document.removeEventListener("mouseup", mouseUpHandler);

        // Save new order
        let order = [];
        document.querySelectorAll("table tbody tr").forEach((row) => {
            if (row.dataset.id) order.push(row.dataset.id);
        });

        fetch("ajax_save_reorder.php", {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({ order: order })
        }).then(res => res.json()).then(data => {
            if (data.success) {
                console.log("Order saved.");
            }
        });
    };

    const isAbove = function (nodeA, nodeB) {
        const rectA = nodeA.getBoundingClientRect();
        const rectB = nodeB.getBoundingClientRect();
        return rectA.top + rectA.height / 2 < rectB.top + rectB.height / 2;
    };

    document.querySelectorAll("table tbody tr").forEach(row => {
        row.addEventListener("mousedown", mouseDownHandler);
    });
});
