/**
 * Shared drag-and-drop handler factory for Block Registry
 * Used by both field ordering (edit.js) and repeater row ordering (edit-data.js)
 *
 * @param {string} itemSelector - CSS selector for draggable items (e.g. '.field-item', '.repeater-row')
 * @param {Function} onReindex - callback invoked after a drop to reindex items
 * @returns {object} handler with init(), start(), end(), over(), drop() methods
 */
function createDragDropHandler(itemSelector, onReindex) {
    let draggedEl = null;

    function handleDragStart(e) {
        let item = e.target.closest(itemSelector);
        if (!item) return;

        draggedEl = item;
        item.classList.add('dragging');
        e.dataTransfer.effectAllowed = 'move';
        e.dataTransfer.setData('text/html', item.innerHTML);

        setTimeout(function () {
            item.style.opacity = '0.5';
        }, 0);
    }

    function handleDragEnd(e) {
        let item = e.target.closest(itemSelector);
        if (item) {
            item.classList.remove('dragging');
            item.style.opacity = '1';
        }
        draggedEl = null;

        // Remove all drag-over states
        document.querySelectorAll(itemSelector + '.drag-over').forEach(function (el) {
            el.classList.remove('drag-over');
        });
    }

    function handleDragOver(e) {
        e.preventDefault();
        e.dataTransfer.dropEffect = 'move';

        let target = e.target.closest(itemSelector);
        if (!target || target === draggedEl) return;

        // Remove drag-over from siblings
        let container = target.parentNode;
        container.querySelectorAll(itemSelector).forEach(function (el) {
            el.classList.remove('drag-over');
        });

        target.classList.add('drag-over');
    }

    function handleDrop(e) {
        e.preventDefault();

        let target = e.target.closest(itemSelector);
        if (!target || !draggedEl || target === draggedEl) return;

        let container = target.parentNode;
        let items = Array.from(container.querySelectorAll(itemSelector));
        let draggedIndex = items.indexOf(draggedEl);
        let targetIndex = items.indexOf(target);

        if (draggedIndex < targetIndex) {
            target.parentNode.insertBefore(draggedEl, target.nextSibling);
        } else {
            target.parentNode.insertBefore(draggedEl, target);
        }

        target.classList.remove('drag-over');

        if (typeof onReindex === 'function') {
            onReindex(container);
        }
    }

    function init(container) {
        if (!container) return;

        container.addEventListener('dragstart', handleDragStart);
        container.addEventListener('dragend', handleDragEnd);
        container.addEventListener('dragover', handleDragOver);
        container.addEventListener('drop', handleDrop);

        // Make existing items draggable
        container.querySelectorAll(itemSelector).forEach(function (item) {
            item.setAttribute('draggable', 'true');
        });
    }

    return {
        init: init,
        start: handleDragStart,
        end: handleDragEnd,
        over: handleDragOver,
        drop: handleDrop,
        makeDraggable: function (container) {
            container.querySelectorAll(itemSelector).forEach(function (item) {
                item.setAttribute('draggable', 'true');
            });
        }
    };
}
