/**
 * 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.
 */

const require_runtime = require("../../_virtual/_rolldown/runtime.js");
const require_index = require("../../node_modules/classnames/index.js");
const require_settings = require("../../settings.js");
const require_usePreviousValue = require("../../global/js/hooks/usePreviousValue.js");
const require_props_helper = require("../../global/js/utils/props-helper.js");
const require_deepCloneObject = require("../../global/js/utils/deepCloneObject.js");
const require_removeCellSelections = require("./utils/removeCellSelections.js");
const require_useSpreadsheetMouseUp = require("./hooks/useSpreadsheetMouseUp.js");
const require_createCellSelectionArea = require("./utils/createCellSelectionArea.js");
const require_checkActiveHeaderCell = require("./utils/checkActiveHeaderCell.js");
const require_checkSelectedHeaderCell = require("./utils/checkSelectedHeaderCell.js");
const require_getSpreadsheetWidth = require("./utils/getSpreadsheetWidth.js");
const require_commonEventHandlers = require("./utils/commonEventHandlers.js");
let react = require("react");
react = require_runtime.__toESM(react);
let prop_types = require("prop-types");
prop_types = require_runtime.__toESM(prop_types);
let _carbon_layout = require("@carbon/layout");
let react_window = require("react-window");
//#region src/components/DataSpreadsheet/DataSpreadsheetBody.tsx
/**
* Copyright IBM Corp. 2022, 2022
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
var import_classnames = /* @__PURE__ */ require_runtime.__toESM(require_index.default);
const blockClass = `${require_settings.pkg.prefix}--data-spreadsheet`;
const DataSpreadsheetBody = (0, react.forwardRef)(({ activeCellRef, columns, activeCellCoordinates, defaultColumn, defaultEmptyRowCount, getTableBodyProps, headerGroups, setCurrentColumns, id, onDataUpdate, renderRowHeader, renderRowHeaderDirection, hasCustomRowHeader, prepareRow, rows, selectionAreaData, setSelectionAreaData, setActiveCellCoordinates, selectedHeaderReorderActive, setSelectedHeaderReorderActive, selectionAreas, setContainerHasFocus, setSelectionAreas, scrollBarSize, totalColumnsWidth, clickAndHoldActive, setClickAndHoldActive, currentMatcher, setCurrentMatcher, onSelectionAreaChange, setActiveCellInsideSelectionArea, totalVisibleColumns, setHeaderCellHoldActive, setColumnOrder, visibleColumns }, ref) => {
	const [validStartingPoint, setValidStartingPoint] = (0, react.useState)(false);
	const contentScrollRef = (0, react.useRef)(void 0);
	const previousState = require_usePreviousValue.usePreviousValue({
		selectionAreaData,
		clickAndHoldActive,
		rowHeight: defaultColumn?.rowHeight
	}) || {};
	(0, react.useEffect)(() => {
		ref?.current.style.setProperty(`--${blockClass}--total-width`, (0, _carbon_layout.px)((totalColumnsWidth || 0) + (scrollBarSize || 0)));
	}, [
		ref,
		scrollBarSize,
		totalColumnsWidth
	]);
	(0, react.useEffect)(() => {
		if (selectionAreaData?.length) {
			let selectionChanged = false;
			if (previousState?.selectionAreaData?.length !== selectionAreaData?.length || selectionAreaData?.[0]?.cells.length !== previousState?.selectionAreaData?.[0]?.cells.length) selectionChanged = true;
			if (!clickAndHoldActive && previousState?.clickAndHoldActive || selectionChanged) onSelectionAreaChange?.(selectionAreaData);
		}
	}, [
		previousState?.selectionAreaData,
		selectionAreaData,
		onSelectionAreaChange,
		clickAndHoldActive,
		previousState?.clickAndHoldActive
	]);
	(0, react.useEffect)(() => {
		if (selectionAreas && selectionAreas.length) selectionAreas.map((area) => {
			if (area.areaCreated) {
				const rowStart = Math.min(area.point1.row, area.point2.row);
				const rowEnd = Math.max(area.point1.row, area.point2.row);
				const columnStart = Math.min(area.point1.column, area.point2.column);
				const columnEnd = Math.max(area.point1.column, area.point2.column);
				const selectionData = {
					rows: {
						start: rowStart,
						end: rowEnd
					},
					columns: {
						start: columnStart,
						end: columnEnd
					},
					cells: populateSelectionAreaCellData({
						rowStart,
						rowEnd,
						columnStart,
						columnEnd
					}),
					selectionId: area.matcher
				};
				setSelectionAreaData?.((prev) => {
					return [...require_deepCloneObject.deepCloneObject(prev).filter((item) => item.selectionId !== area.matcher), selectionData];
				});
			}
			if (!area.areaCreated && area.point1 && area.point2 && area.matcher) require_createCellSelectionArea.createCellSelectionArea({
				ref,
				area,
				blockClass,
				defaultColumn,
				selectionAreas,
				setSelectionAreas,
				setActiveCellInsideSelectionArea,
				visibleColumns
			});
		});
	}, [
		selectionAreas,
		setSelectionAreas,
		defaultColumn,
		onSelectionAreaChange,
		setSelectionAreaData,
		ref,
		activeCellCoordinates,
		setActiveCellInsideSelectionArea,
		visibleColumns,
		hasCustomRowHeader
	]);
	const populateSelectionAreaCellData = ({ rowStart, rowEnd, columnStart, columnEnd }) => {
		const cellContainer = [];
		for (let rowIndex = rowStart; rowIndex <= rowEnd; rowIndex++) for (let columnIndex = columnStart; columnIndex <= columnEnd; columnIndex++) cellContainer.push([
			rowIndex,
			columnIndex,
			`${blockClass}__cell--${rowIndex}--${columnIndex}`
		]);
		return cellContainer;
	};
	require_useSpreadsheetMouseUp.useSpreadsheetMouseUp({
		currentMatcher,
		setClickAndHoldActive,
		setSelectionAreas,
		setValidStartingPoint,
		selectedHeaderReorderActive,
		setSelectedHeaderReorderActive,
		validStartingPoint,
		ref,
		setHeaderCellHoldActive,
		setColumnOrder,
		visibleColumns,
		setActiveCellCoordinates,
		rows,
		activeCellCoordinates,
		defaultColumn,
		selectionAreas
	});
	(0, react.useEffect)(() => {
		let listContainer;
		let activeCellButton;
		if (spreadsheetBodyRef?.current) {
			listContainer = spreadsheetBodyRef?.current;
			activeCellButton = listContainer?.querySelector(`.${blockClass}__active-cell--highlight`);
		}
		if (activeCellButton && defaultColumn?.rowHeight !== previousState.rowHeight) {
			activeCellButton.style.height = `${defaultColumn?.rowHeight}px`;
			if (activeCellCoordinates) {
				const activeTargetElement = ref?.current.querySelector(`[data-row-index="${activeCellCoordinates.row}"][data-column-index="${activeCellCoordinates.column}"]`);
				const listContainer = ref?.current.querySelector(`.${blockClass}__list--container`);
				let newActiveCellTopPosition;
				if (activeTargetElement && listContainer) newActiveCellTopPosition = activeTargetElement?.getBoundingClientRect().top - listContainer.getBoundingClientRect().top;
				activeCellButton.style.top = (0, _carbon_layout.px)(newActiveCellTopPosition);
				require_removeCellSelections.removeCellSelections({
					matcher: void 0,
					spreadsheetRef: ref
				});
				selectionAreas?.map((area) => {
					if (!area.areaCreated && area.point1 && area.point2 && area.matcher) return require_createCellSelectionArea.createCellSelectionArea({
						ref,
						area,
						blockClass,
						defaultColumn,
						selectionAreas,
						setSelectionAreas,
						setActiveCellInsideSelectionArea,
						visibleColumns
					});
				});
			}
		}
	}, [
		defaultColumn,
		ref,
		activeCellCoordinates,
		previousState?.rowHeight,
		selectionAreas,
		setActiveCellInsideSelectionArea,
		setSelectionAreas,
		visibleColumns,
		hasCustomRowHeader
	]);
	const removeDuplicateSelections = (0, react.useCallback)(() => {
		const uniqueAttrArray = [], removedSelectionAreaMatcherArr = [];
		ref?.current.querySelectorAll(`.${blockClass}__selection-area--element`).forEach((selectorEl) => {
			const { top, left, height, width } = selectorEl.style;
			const uniqueAttrStr = `${top}${left}${height}${width}`;
			if (uniqueAttrArray.indexOf(uniqueAttrStr) == -1) uniqueAttrArray.push(uniqueAttrStr);
			else {
				selectorEl.remove();
				removedSelectionAreaMatcherArr.push(selectorEl.getAttribute("data-matcher-id"));
			}
		});
		if (removedSelectionAreaMatcherArr.length) {
			setSelectionAreas?.((prev) => {
				return require_deepCloneObject.deepCloneObject(prev).filter((item) => !removedSelectionAreaMatcherArr.includes(item.matcher));
			});
			setSelectionAreaData?.((prev) => {
				return require_deepCloneObject.deepCloneObject(prev).filter((item) => !removedSelectionAreaMatcherArr.includes(item.selectionId));
			});
		}
	}, [
		ref,
		setSelectionAreas,
		setSelectionAreaData
	]);
	(0, react.useEffect)(() => {
		removeDuplicateSelections();
	}, [selectionAreas, removeDuplicateSelections]);
	const handleBodyCellClickEvent = (0, react.useCallback)((cell, columnIndex) => {
		return (event) => {
			require_commonEventHandlers.handleBodyCellClick(cell, columnIndex, event, currentMatcher, activeCellCoordinates, selectionAreas, setActiveCellCoordinates, setSelectionAreas, setContainerHasFocus, setClickAndHoldActive, setCurrentMatcher, ref, setSelectionAreaData, setActiveCellInsideSelectionArea, activeCellRef, setValidStartingPoint);
		};
	}, [
		currentMatcher,
		activeCellCoordinates,
		selectionAreas,
		setActiveCellCoordinates,
		setSelectionAreas,
		setContainerHasFocus,
		setClickAndHoldActive,
		setCurrentMatcher,
		ref,
		setSelectionAreaData,
		setActiveCellInsideSelectionArea,
		activeCellRef
	]);
	const handleBodyScroll = () => {
		const headerRowElement = ref.current.querySelector(`
        .${blockClass}__header--container .${blockClass}__tr`) || new HTMLDivElement();
		headerRowElement.scrollLeft = contentScrollRef?.current.scrollLeft;
	};
	(0, react.useEffect)(() => {
		contentScrollRef.current.addEventListener("scroll", () => handleBodyScroll());
		const contentScrollElementRef = contentScrollRef.current || new HTMLElement();
		return () => {
			contentScrollElementRef.removeEventListener("scroll", handleBodyScroll);
		};
	});
	const handleBodyCellHoverEvent = (0, react.useCallback)((cell, columnIndex) => {
		return () => {
			require_commonEventHandlers.handleBodyCellHover(cell, columnIndex, clickAndHoldActive, currentMatcher, setSelectionAreas);
		};
	}, [
		clickAndHoldActive,
		currentMatcher,
		setSelectionAreas
	]);
	const handleRowHeaderClickEvent = (0, react.useCallback)((index) => {
		return (event) => {
			require_commonEventHandlers.handleRowHeaderClick(index, event, columns, ref, setSelectionAreas, setCurrentMatcher, setActiveCellCoordinates, activeCellCoordinates, rows, setSelectionAreaData);
		};
	}, [
		columns,
		ref,
		setSelectionAreas,
		setCurrentMatcher,
		setActiveCellCoordinates,
		activeCellCoordinates,
		rows,
		setSelectionAreaData
	]);
	(0, react.useEffect)(() => {
		if (!rows?.length) {
			const buildEmptyRows = () => {
				const emptyRowData = [];
				[...Array(defaultEmptyRowCount)].map(() => {
					const emptyCell = {};
					headerGroups?.[0]?.headers.map((header) => {
						emptyCell[header.id] = null;
					});
					emptyRowData.push(emptyCell);
				});
				onDataUpdate?.(emptyRowData);
			};
			buildEmptyRows();
		}
		if (headerGroups?.[0] && typeof setCurrentColumns === "function") {
			const headers = headerGroups[0].headers;
			setCurrentColumns(headers);
		}
	}, [
		rows,
		headerGroups,
		defaultEmptyRowCount,
		onDataUpdate,
		setCurrentColumns
	]);
	const RenderEmptyRows = () => {
		return /* @__PURE__ */ react.default.createElement("div", null);
	};
	const RenderRow = (0, react.useCallback)(({ index, style }) => {
		const row = rows?.[index];
		if (rows && rows.length) {
			prepareRow?.(row);
			const rowProps = require_props_helper.prepareProps(row.getRowProps({ style }), "key");
			return /* @__PURE__ */ react.default.createElement("div", {
				key: { ...row.getRowProps().key },
				...rowProps,
				className: (0, import_classnames.default)(`${blockClass}__tr`),
				"data-row-index": index,
				"aria-rowindex": index + 1,
				"aria-owns": `${blockClass}__cell-editor-text-area`
			}, /* @__PURE__ */ react.default.createElement("div", {
				role: "rowheader",
				className: `${blockClass}__td-th--cell-container`
			}, /* @__PURE__ */ react.default.createElement("button", {
				id: `${blockClass}__cell--${index}--header`,
				tabIndex: -1,
				"data-row-index": index,
				"data-column-index": "header",
				type: "button",
				onClick: handleRowHeaderClickEvent(index),
				className: (0, import_classnames.default)(`${blockClass}__td`, `${blockClass}__td-th`, `${blockClass}--interactive-cell-element`, {
					[`${blockClass}__td_custom`]: hasCustomRowHeader ? true : false,
					[`${blockClass}__td-th--active-header`]: !hasCustomRowHeader && (activeCellCoordinates?.row === index || require_checkActiveHeaderCell.checkActiveHeaderCell(index, selectionAreas, "row")),
					[`${blockClass}__td-th--selected-header`]: !hasCustomRowHeader && require_checkSelectedHeaderCell.checkSelectedHeaderCell(index, selectionAreas, "row", columns)
				}),
				style: {
					width: defaultColumn?.rowHeaderWidth,
					flexDirection: hasCustomRowHeader ? renderRowHeaderDirection === "Left" ? "row-reverse" : row : void 0
				}
			}, index + 1, hasCustomRowHeader && typeof renderRowHeader === "function" && renderRowHeader(index))), row.cells.map((cell, index) => {
				const cellProps = require_props_helper.prepareProps(cell.getCellProps(), "key");
				return /* @__PURE__ */ react.default.createElement("div", {
					key: `cell_${index}`,
					"aria-colindex": index + 1,
					...cellProps,
					role: "gridcell",
					style: {
						...cell.getCellProps().style,
						display: "grid",
						minWidth: cell?.column?.width || defaultColumn?.width
					}
				}, /* @__PURE__ */ react.default.createElement("button", {
					id: `${blockClass}__cell--${cell.row.index}--${index}`,
					tabIndex: -1,
					"data-row-index": cell.row.index,
					"data-column-index": index,
					className: (0, import_classnames.default)(`${blockClass}__td`, `${blockClass}__body--td`, `${blockClass}--interactive-cell-element`),
					onMouseDown: handleBodyCellClickEvent(cell, index),
					onMouseOver: handleBodyCellHoverEvent(cell, index),
					onFocus: () => {},
					type: "button"
				}, cell.render("Cell")));
			}));
		}
	}, [
		prepareRow,
		renderRowHeader,
		rows,
		hasCustomRowHeader,
		activeCellCoordinates?.row,
		selectionAreas,
		handleRowHeaderClickEvent,
		handleBodyCellClickEvent,
		handleBodyCellHoverEvent,
		columns,
		defaultColumn,
		renderRowHeaderDirection
	]);
	const spreadsheetBodyRef = (0, react.useRef)(void 0);
	return /* @__PURE__ */ react.default.createElement("div", {
		ref: spreadsheetBodyRef,
		className: (0, import_classnames.default)(`${blockClass}__body--container`),
		...getTableBodyProps?.()
	}, /* @__PURE__ */ react.default.createElement(react_window.FixedSizeList, {
		className: (0, import_classnames.default)(`${blockClass}__list--container`, `${blockClass}__list--container--${id}`),
		height: 400,
		itemCount: rows?.length || defaultEmptyRowCount,
		itemSize: defaultColumn?.rowHeight,
		width: require_getSpreadsheetWidth.getSpreadsheetWidth({
			headerGroup: void 0,
			type: void 0,
			scrollBarSizeValue: scrollBarSize,
			totalVisibleColumns,
			defaultColumn,
			totalColumnsWidth,
			visibleColumns
		}),
		outerRef: contentScrollRef
	}, rows?.length ? RenderRow : RenderEmptyRows));
});
DataSpreadsheetBody.propTypes = {
	/**
	* Object containing the active cell coordinates
	*/
	/**@ts-ignore */
	activeCellCoordinates: prop_types.default.shape({
		row: prop_types.default.oneOfType([prop_types.default.string, prop_types.default.number]),
		column: prop_types.default.oneOfType([prop_types.default.string, prop_types.default.number])
	}),
	/**
	*This is the ref of the button input, which is the active cell element
	*/
	/**@ts-ignore */
	activeCellRef: prop_types.default.object,
	/**
	* Is the user clicking and holding in the data spreadsheet body
	*/
	clickAndHoldActive: prop_types.default.bool,
	/**
	* All of the spreadsheet columns
	*/
	columns: prop_types.default.array,
	/**
	* This represents the id of the current cell selection area
	*/
	currentMatcher: prop_types.default.string,
	/**
	* Default spreadsheet sizing values
	*/
	/**@ts-ignore */
	defaultColumn: prop_types.default.shape({
		rowHeight: prop_types.default.number,
		rowHeaderWidth: prop_types.default.number,
		width: prop_types.default.number
	}),
	/**
	* Sets the number of empty rows to be created when there is no data provided
	*/
	defaultEmptyRowCount: prop_types.default.number,
	/**
	* Function to set table body prop values
	*/
	/**@ts-ignore */
	getTableBodyProps: prop_types.default.func,
	/**
	* Check if spreadsheet is using custom row header component attached
	*/
	hasCustomRowHeader: prop_types.default.bool,
	/**
	* Headers provided from useTable hook
	*/
	headerGroups: prop_types.default.arrayOf(prop_types.default.object),
	/**
	* The spreadsheet id
	*/
	id: prop_types.default.oneOfType([prop_types.default.number, prop_types.default.string]),
	/**
	* The event handler that is called when the active cell changes
	*/
	onActiveCellChange: prop_types.default.func,
	/**
	* The event handler that is called to set the rows for the empty spreadsheet
	*/
	onDataUpdate: prop_types.default.func,
	/**
	* The event handler that is called when the selection areas change
	*/
	onSelectionAreaChange: prop_types.default.func,
	/**
	* Prepare row function from react-table
	*/
	prepareRow: prop_types.default.func,
	/**
	* Component next to numbering rows
	*/
	renderRowHeader: prop_types.default.func,
	/**
	* Component next to numbering rows
	*/
	renderRowHeaderDirection: prop_types.default.string,
	/**
	* All of the spreadsheet row data
	*/
	rows: prop_types.default.arrayOf(prop_types.default.object),
	/**
	* The scrollbar width
	*/
	scrollBarSize: prop_types.default.number,
	/**
	* Header reordering is active
	*/
	selectedHeaderReorderActive: prop_types.default.bool,
	/**
	* Array of selection area data
	*/
	selectionAreaData: prop_types.default.array,
	/**
	* Array of selection areas
	*/
	selectionAreas: prop_types.default.array,
	/**
	* Setter fn for activeCellCoordinates state value
	*/
	setActiveCellCoordinates: prop_types.default.func,
	/**
	* Setter fn for active cell inside of selection area
	*/
	setActiveCellInsideSelectionArea: prop_types.default.func,
	/**
	* Setter fn for clickAndHold state value
	*/
	setClickAndHoldActive: prop_types.default.func,
	/**
	* Setter fn for column ordering, provided from react-table
	*/
	setColumnOrder: prop_types.default.func,
	/**
	* Setter fn for containerHasFocus state value
	*/
	setContainerHasFocus: prop_types.default.func,
	/**
	* Set current columns after drag drop
	*/
	setCurrentColumns: prop_types.default.func,
	/**
	* Setter fn for currentMatcher state value
	*/
	setCurrentMatcher: prop_types.default.func,
	/**
	* Setter fn for header cell hold active value
	*/
	setHeaderCellHoldActive: prop_types.default.func,
	/**
	* Set header reordering active or not
	*/
	setSelectedHeaderReorderActive: prop_types.default.func,
	/**
	* Setter fn for selectionAreaData state value
	*/
	setSelectionAreaData: prop_types.default.func,
	/**
	* Setter fn for selectionAreas state value
	*/
	setSelectionAreas: prop_types.default.func,
	/**
	* The total columns width
	*/
	totalColumnsWidth: prop_types.default.number,
	/**
	* The total number of columns to be initially visible, additional columns will be rendered and
	* visible via horizontal scrollbar
	*/
	totalVisibleColumns: prop_types.default.number,
	/**
	* Prop from react-table used to reorder columns
	*/
	/**@ts-ignore */
	visibleColumns: prop_types.default.array
};
//#endregion
exports.DataSpreadsheetBody = DataSpreadsheetBody;
