/**
 * useDraggableList — drag-drop HTML5 nativo pra reordenação de listas.
 * Sem deps externas.
 *
 * Uso:
 *   const { onDragStart, onDragOver, onDrop, onDragEnd, dragIdx, overIdx, isDragging } = useDraggableList({
 *     onReorder: async (fromIdx, toIdx) => { ... }
 *   });
 *
 *   <li
 *     v-for="(item, i) in list"
 *     draggable="true"
 *     @dragstart="onDragStart($event, i)"
 *     @dragover.prevent="onDragOver($event, i)"
 *     @drop="onDrop($event, i)"
 *     @dragend="onDragEnd"
 *     :class="{ dragging: dragIdx === i, 'drop-target': overIdx === i && dragIdx !== i }"
 *   >...</li>
 */
import { ref } from 'vue';

export function useDraggableList({ onReorder } = {}) {
    const dragIdx = ref(null);
    const overIdx = ref(null);

    const isDragging = () => dragIdx.value !== null;

    function onDragStart(e, index) {
        dragIdx.value = index;
        overIdx.value = null;
        if (e.dataTransfer) {
            e.dataTransfer.effectAllowed = 'move';
            // Firefox exige payload pra drag iniciar
            try {
                e.dataTransfer.setData('text/plain', String(index));
            } catch {}
        }
        // Adiciona classe pro cursor mudar
        if (e.target?.classList) e.target.classList.add('is-dragging');
    }

    function onDragOver(e, index) {
        if (e.dataTransfer) e.dataTransfer.dropEffect = 'move';
        overIdx.value = index;
    }

    function onDragLeave() {
        // Opcional: limpar overIdx quando sair da lista inteira
    }

    async function onDrop(e, toIndex) {
        e.preventDefault();
        const fromIndex = dragIdx.value;
        dragIdx.value = null;
        overIdx.value = null;

        if (fromIndex === null || fromIndex === toIndex) return;
        if (typeof onReorder === 'function') {
            await onReorder(fromIndex, toIndex);
        }
    }

    function onDragEnd(e) {
        dragIdx.value = null;
        overIdx.value = null;
        if (e?.target?.classList) e.target.classList.remove('is-dragging');
    }

    return {
        dragIdx,
        overIdx,
        isDragging,
        onDragStart,
        onDragOver,
        onDragLeave,
        onDrop,
        onDragEnd
    };
}

/**
 * Reordena um array local (imutável) movendo item de `from` pra `to`.
 */
export function reorderArray(arr, from, to) {
    const copy = [...arr];
    const [item] = copy.splice(from, 1);
    copy.splice(to, 0, item);
    return copy;
}

/**
 * Atualiza o campo `ordem` de cada item após reorder, e retorna o array
 * com ordem já atualizada (para persistir no banco).
 */
export function reorderWithIndexes(arr, from, to, orderField = 'ordem') {
    const reordered = reorderArray(arr, from, to);
    return reordered.map((item, idx) => ({ ...item, [orderField]: idx + 1 }));
}
