/**
 * Copyright IBM Corp. 2020, 2026
 *
 * This source code is licensed under the Apache-2.0 license found in the
 * LICENSE file in the root directory of this source tree.
 */

import { pkg } from "../../../../../settings.js";
import { getNodeTextContent } from "../../../../../global/js/utils/getNodeTextContent.js";
import { useId } from "../../../../../global/js/utils/useId.js";
import { isColumnVisible } from "./common.js";
import DraggableElement from "../../DraggableElement.js";
import React from "react";
import { PropTypes as PropTypes$1 } from "prop-types";
import { Checkbox } from "@carbon/react";
import { SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable";
import { DndContext, KeyboardSensor, PointerSensor, closestCenter, useSensor, useSensors } from "@dnd-kit/core";
import { restrictToParentElement, restrictToVerticalAxis } from "@dnd-kit/modifiers";
//#region src/components/Datagrid/Datagrid/addons/CustomizeColumns/DraggableItemsList.jsx
/**
* Copyright IBM Corp. 2023, 2023
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
const blockClass = `${pkg.prefix}--datagrid`;
const matchedColsById = (col1, col2) => col1 && col2 && col1.id === col2.id;
const DraggableItemsList = ({ columns, filterString, id, moveElement, onSelectColumn, setAriaRegionText }) => {
	const draggableClass = `${blockClass}__draggable-item`;
	const generatedId = useId();
	const visibleCols = columns.filter((colDef) => getNodeTextContent(colDef.Header).trim().length !== 0).filter(Boolean).filter((colDef) => !colDef.isAction).filter((colDef) => colDef.id !== "spacer").filter((colDef) => {
		return filterString.length === 0 || getNodeTextContent(colDef.Header).toLowerCase().includes(filterString);
	});
	const getUpdatedDragCols = () => {
		const tempCols = [...visibleCols];
		tempCols.forEach((col) => {
			if (col.sticky) col.disabled = true;
		});
		return tempCols;
	};
	const updatedDragCols = getUpdatedDragCols();
	const handleDragEnd = (event) => {
		const { active, over } = event;
		const destOverCol = updatedDragCols.filter((item) => item.id === over.id);
		if (destOverCol?.length && destOverCol[0]?.disabled) return;
		const fromVisibleIndex = updatedDragCols.findIndex((col) => matchedColsById(col, active));
		const toVisibleIndex = updatedDragCols.findIndex((col) => matchedColsById(col, over));
		setAriaRegionText(`${getNodeTextContent(updatedDragCols[fromVisibleIndex].Header)} dropped. New position ${toVisibleIndex + 1} of ${updatedDragCols.length}.`);
		moveElement(columns.findIndex((col) => matchedColsById(col, active)), columns.findIndex((col) => matchedColsById(col, over)));
	};
	const handleDragStart = (event) => {
		const { active } = event;
		const fromIndex = updatedDragCols.findIndex((col) => matchedColsById(col, active));
		setAriaRegionText(`${getNodeTextContent(updatedDragCols[fromIndex].Header)} grabbed. Current position ${fromIndex + 1} of ${updatedDragCols.length}.`);
	};
	const handleDragUpdate = (event) => {
		const { active, over } = event;
		const fromIndex = updatedDragCols.findIndex((col) => matchedColsById(col, active));
		const toIndex = updatedDragCols.findIndex((col) => matchedColsById(col, over));
		setAriaRegionText(`${getNodeTextContent(updatedDragCols[fromIndex].Header)} grabbed. Original position ${fromIndex + 1}, new position ${toIndex + 1} of ${updatedDragCols.length}.`);
	};
	const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 4 } }), useSensor(KeyboardSensor, { coordinateGetter: (event, args) => {
		const { currentCoordinates } = args;
		let target = event.target;
		while (target && !target.classList.contains(draggableClass)) target = target.parentNode;
		const delta = target.offsetHeight;
		switch (event.code) {
			case "ArrowRight":
			case "ArrowLeft": return currentCoordinates;
			case "ArrowUp": return {
				...currentCoordinates,
				y: currentCoordinates.y - delta
			};
			case "ArrowDown": return {
				...currentCoordinates,
				y: currentCoordinates.y + delta
			};
			case "Space": break;
		}
	} }));
	const handleCheckboxKeydown = (event, colDef) => {
		if (event.code === "Space") {
			onSelectColumn(colDef, !isColumnVisible(colDef));
			event.preventDefault();
			event.stopPropagation();
			return false;
		}
	};
	return /* @__PURE__ */ React.createElement(DndContext, {
		collisionDetection: closestCenter,
		onDragEnd: handleDragEnd,
		onDragStart: handleDragStart,
		onDragMove: handleDragUpdate,
		sensors,
		modifiers: [restrictToParentElement, restrictToVerticalAxis]
	}, /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", {
		className: `${blockClass}__draggable-underlay`,
		"aria-hidden": "true",
		key: `draggable-underlay-${id}`
	}, visibleCols.map((colDef) => /* @__PURE__ */ React.createElement("div", {
		className: `${blockClass}__draggable-underlay-item`,
		key: colDef.id
	}))), /* @__PURE__ */ React.createElement(SortableContext, {
		items: updatedDragCols,
		strategy: verticalListSortingStrategy
	}, visibleCols.map((colDef) => {
		const colHeaderTitle = getNodeTextContent(colDef.Header);
		const isFrozenColumn = !!colDef.sticky;
		const isDisabled = colDef.disabled;
		const listContents = /* @__PURE__ */ React.createElement(Checkbox, {
			checked: isColumnVisible(colDef),
			disabled: isDisabled || isFrozenColumn,
			onChange: (_, { checked }) => onSelectColumn(colDef, checked),
			id: `${blockClass}__customization-column-${colDef.id}`,
			labelText: colHeaderTitle,
			className: `${blockClass}__customize-columns-checkbox`,
			onKeyDown: (event) => handleCheckboxKeydown(event, colDef)
		});
		return /* @__PURE__ */ React.createElement(DraggableElement, {
			classList: draggableClass,
			key: colDef.id,
			id: colDef.id,
			elementId: `${colDef.id}-${generatedId}`,
			disabled: filterString.length > 0 || isFrozenColumn,
			ariaLabel: colHeaderTitle,
			isSticky: isFrozenColumn,
			selected: isColumnVisible(colDef)
		}, listContents);
	}))));
};
DraggableItemsList.propTypes = {
	columns: PropTypes$1.array.isRequired,
	filterString: PropTypes$1.string.isRequired,
	id: PropTypes$1.string.isRequired,
	moveElement: PropTypes$1.func.isRequired,
	onSelectColumn: PropTypes$1.func.isRequired,
	setAriaRegionText: PropTypes$1.func.isRequired
};
//#endregion
export { DraggableItemsList };
