/* COPYRIGHT Esri - https://js.arcgis.com/5.1/LICENSE.txt */
import { makeGenericController } from "@arcgis/lumina/controllers";
import Sortable from "sortablejs";
const sortableComponentSet = /* @__PURE__ */ new Set();
const CSS = {
  ghostClass: "calcite-sortable--ghost",
  chosenClass: "calcite-sortable--chosen",
  dragClass: "calcite-sortable--drag",
  fallbackClass: "calcite-sortable--fallback"
};
function onGlobalDragStart() {
  Array.from(sortableComponentSet).forEach((component) => component.onGlobalDragStart());
}
function onGlobalDragEnd() {
  Array.from(sortableComponentSet).forEach((component) => component.onGlobalDragEnd());
}
const globalDragState = { active: false };
function createSortable(component) {
  const dataIdAttr = "id";
  const { el, group, handleSelector: handle, dragSelector: draggable, sortDisabled } = component;
  return Sortable.create(el, {
    dataIdAttr,
    swapThreshold: 0.5,
    ...CSS,
    ...!!draggable && { draggable },
    ...!!group && {
      sort: !sortDisabled,
      group: {
        name: group,
        ...!!component.canPull && {
          pull: (to, from, dragEl, { newDraggableIndex: newIndex, oldDraggableIndex: oldIndex }) => {
            return component.canPull({
              toEl: to.el,
              fromEl: from.el,
              dragEl,
              newIndex,
              oldIndex
            });
          }
        },
        ...!!component.canPut && {
          put: (to, from, dragEl, { newDraggableIndex: newIndex, oldDraggableIndex: oldIndex }) => {
            return component.canPut({
              toEl: to.el,
              fromEl: from.el,
              dragEl,
              newIndex,
              oldIndex
            });
          }
        }
      }
    },
    onMove: ({ from: fromEl, dragged: dragEl, to: toEl, related: relatedEl }) => {
      if (!component.onDragMove) {
        return;
      }
      component.onDragMove({ fromEl, dragEl, toEl, relatedEl });
    },
    handle,
    filter: `${handle}[disabled]`,
    onStart: ({ from: fromEl, item: dragEl, to: toEl, newDraggableIndex: newIndex, oldDraggableIndex: oldIndex }) => {
      globalDragState.active = true;
      onGlobalDragStart();
      component.onDragStart({ fromEl, dragEl, toEl, newIndex, oldIndex });
    },
    onEnd: ({ from: fromEl, item: dragEl, to: toEl, newDraggableIndex: newIndex, oldDraggableIndex: oldIndex }) => {
      globalDragState.active = false;
      onGlobalDragEnd();
      component.onDragEnd({ fromEl, dragEl, toEl, newIndex, oldIndex });
    },
    onSort: ({ from: fromEl, item: dragEl, to: toEl, newDraggableIndex: newIndex, oldDraggableIndex: oldIndex }) => {
      component.onDragSort({ fromEl, dragEl, toEl, newIndex, oldIndex });
    }
  });
}
const useSortable = () => {
  return makeGenericController((component, controller) => {
    let sortable;
    function dragActive(component2) {
      return component2.dragEnabled && globalDragState.active;
    }
    function setUpSortable(component2) {
      if (dragActive(component2)) {
        return;
      }
      tearDownSortable(component2);
      if (!component2.dragEnabled) {
        return;
      }
      sortableComponentSet.add(component2);
      sortable = createSortable(component2);
    }
    function tearDownSortable(component2) {
      if (dragActive(component2)) {
        return;
      }
      sortableComponentSet.delete(component2);
      sortable?.destroy();
      sortable = void 0;
    }
    controller.onConnected(() => {
      setUpSortable(component);
    });
    controller.onDisconnected(() => {
      tearDownSortable(component);
    });
    return {
      reset: () => {
        setUpSortable(component);
      }
    };
  });
};
export {
  useSortable as u
};
