/**
 * 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 { __toESM } from "../../../../../../_virtual/_rolldown/runtime.js";
import { require_classnames } from "../../../../../../node_modules/classnames/index.js";
import { pkg } from "../../../../../../settings.js";
import { useIsomorphicEffect } from "../../../../../../global/js/hooks/useIsomorphicEffect.js";
import { usePreviousValue } from "../../../../../../global/js/hooks/usePreviousValue.js";
import { prepareProps } from "../../../../../../global/js/utils/props-helper.js";
import { InlineEditContext } from "../InlineEditContext/InlineEditContext.js";
import { InlineEditButton } from "../InlineEditButton/InlineEditButton.js";
import React, { useCallback, useContext, useEffect, useRef, useState } from "react";
import PropTypes from "prop-types";
import { Checkbox, DatePicker, DatePickerInput, Dropdown, NumberInput, TextInput } from "@carbon/react";
import { Calendar, CaretSort, ChevronDown, Edit } from "@carbon/react/icons";
//#region src/components/Datagrid/Datagrid/addons/InlineEdit/InlineEditCell/InlineEditCell.jsx
/**
* Copyright IBM Corp. 2022, 2024
*
* 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__ */ __toESM(require_classnames());
const blockClass = `${pkg.prefix}--datagrid`;
const InlineEditCell = ({ cell, config, disabledCell = false, instance, placeholder = "", tabIndex, value, nonEditCell = false, type }) => {
	const columnId = cell.column.id;
	const columnIndex = instance.columns.findIndex((col) => col.id === columnId);
	const rowIndex = cell.row.index;
	const cellId = `column-${columnIndex}-row-${rowIndex}`;
	const { state, dispatch } = useContext(InlineEditContext);
	const [inEditMode, setInEditMode] = useState(false);
	const [cellValue, setCellValue] = useState(value);
	const [initialValue, setInitialValue] = useState();
	const [cellLabel, setCellLabel] = useState();
	const { activeCellId, editId } = state;
	const previousState = usePreviousValue({
		editId,
		activeCellId
	});
	const { inputProps } = config || {};
	const textInputRef = useRef(void 0);
	const checkboxRef = useRef(void 0);
	const numberInputRef = useRef(void 0);
	const dropdownRef = useRef(void 0);
	const outerButtonElement = useRef(void 0);
	const { rowSize, onDataUpdate } = instance;
	let saveCellData;
	if (inEditMode) instance.cellEditing = {
		cellId,
		columnIndex,
		rowIndex,
		curCellValue: cellValue
	};
	useEffect(() => {
		setInitialValue(value);
		const columnId = cell.column.id;
		const columnLabel = instance.columns.find((item) => item.id === columnId);
		setCellLabel(typeof columnLabel.Header === "string" ? columnLabel.Header : "Inline edit cell label");
	}, []);
	useEffect(() => {
		if (previousState?.editId === cellId && !editId || previousState?.editId === cellId && cellId !== editId) {
			const { validator } = config || {};
			if (validator?.(cellValue)) {
				setCellValue(initialValue);
				saveCellData(initialValue);
				return;
			}
		}
	}, [
		previousState?.editId,
		editId,
		cellId,
		cellValue,
		config,
		initialValue,
		saveCellData
	]);
	useEffect(() => {
		if (activeCellId !== cellId || !editId) setInEditMode(false);
		if (activeCellId === cellId && editId === cellId && !nonEditCell) {
			setInEditMode(true);
			saveCellData(cellValue);
		}
	}, [
		activeCellId,
		cellId,
		nonEditCell,
		editId,
		cellValue,
		saveCellData
	]);
	const openDropdown = (type) => {
		const datePickerInputElement = document.querySelector(`#${blockClass}__inline-edit--date-picker--${cell.row.index}`);
		const dropdownTrigger = type === "selection" ? dropdownRef?.current : datePickerInputElement;
		dropdownTrigger.click();
		if (type === "date") dropdownTrigger?.focus();
	};
	useEffect(() => {
		if (previousState?.editId === cellId && previousState?.activeCellId === cellId && activeCellId !== cellId) {
			const { validator } = config || {};
			if (!validator?.(cellValue)) setInitialValue(cellValue);
		}
	}, [
		previousState,
		cellId,
		cellValue,
		activeCellId,
		config
	]);
	const handleInlineCellClick = () => {
		if (!inEditMode) {
			dispatch({
				type: "ENTER_EDIT_MODE",
				payload: {
					activeCellId: cellId,
					editId: cellId
				}
			});
			setInEditMode(true);
			setTimeout(() => {
				if (type === "selection" || type === "date") openDropdown(type);
			}, 1);
		}
	};
	useEffect(() => {
		if (inEditMode) {
			if (type === "text") textInputRef.current.focus();
			if (type === "number") numberInputRef.current.focus();
			if (type === "selection") dropdownRef?.current?.focus();
		}
	}, [inEditMode, type]);
	saveCellData = useCallback((newValue) => {
		const columnId = cell.column.id;
		const rowIndex = cell.row.index;
		onDataUpdate((prev) => prev.map((row, index) => {
			if (index === rowIndex) return {
				...prev[rowIndex],
				[columnId]: newValue
			};
			return row;
		}));
	}, [cell, onDataUpdate]);
	useEffect(() => {
		setCellValue(value);
	}, [value]);
	const sendFocusBackToGrid = () => {
		document.querySelector(`#${instance.tableId} .${blockClass}__table-with-inline-edit`).focus();
	};
	const getNewCellId = (key) => {
		const totalRows = instance.rows.length;
		return key === "Enter" ? `column-${columnIndex}-row-${cell.row.index < totalRows - 1 && type === "checkbox" ? cell.row.index + 1 : cell.row.index}` : `column-${columnIndex < instance.columns.length - 1 ? columnIndex + 1 : columnIndex}-row-${cell.row.index}`;
	};
	const handleKeyDown = (event) => {
		const { key } = event;
		switch (key) {
			case "ArrowRight":
			case "ArrowLeft":
			case "ArrowUp":
			case "ArrowDown":
				if (inEditMode && event.target.type === "checkbox") {
					const newCellId = getNewCellId(key);
					saveCellData(cellValue);
					setInitialValue(cellValue);
					dispatch({
						type: "EXIT_EDIT_MODE",
						payload: newCellId
					});
					setInEditMode(false);
					sendFocusBackToGrid();
				}
				break;
			case "Tab":
			case "Enter":
				if (type === "checkbox") {
					dispatch({
						type: "EXIT_EDIT_MODE",
						payload: getNewCellId(key)
					});
					setInEditMode(false);
					sendFocusBackToGrid();
				}
				if (inEditMode) {
					if (type === "selection" || type === "date") return;
					const { validator } = config || {};
					if (validator?.(cellValue)) return;
					const newCellId = getNewCellId(key);
					saveCellData(cellValue);
					setInitialValue(cellValue);
					dispatch({
						type: "EXIT_EDIT_MODE",
						payload: newCellId
					});
					setInEditMode(false);
					sendFocusBackToGrid();
				}
				break;
			case "Escape":
				if (inEditMode) {
					dispatch({
						type: "EXIT_EDIT_MODE",
						payload: cellId
					});
					setCellValue(initialValue);
					saveCellData(initialValue);
					setInEditMode(false);
					sendFocusBackToGrid();
				}
				break;
			default: return;
		}
	};
	const addActiveState = () => {
		dispatch({
			type: "UPDATE_ACTIVE_CELL_ID",
			payload: cellId
		});
	};
	const renderDropdownItem = (item) => {
		return !!item?.icon ? /* @__PURE__ */ React.createElement(React.Fragment, null, React.createElement(item.icon), /* @__PURE__ */ React.createElement("span", { className: (0, import_classnames.default)(`${blockClass}__inline-edit--select-item`) }, item?.text)) : item?.text;
	};
	const handleTransformedItem = (items) => {
		return items?.length && typeof items[0] === "object" ? (item) => renderDropdownItem(item) : null;
	};
	useIsomorphicEffect(() => {
		if (dropdownRef.current && dropdownRef.current.style) {
			const closestElement = dropdownRef.current.closest(`.${blockClass}__inline-edit--select`);
			closestElement.style.width = `${cell.column.totalWidth}px`;
		}
	}, [dropdownRef.current, cell.column.totalWidth]);
	const renderSelectCell = () => {
		const { inputProps } = config || {};
		return /* @__PURE__ */ React.createElement(Dropdown, {
			id: cellId,
			label: cellLabel || "Dropdown menu options",
			ariaLabel: cellLabel || "Dropdown menu options",
			...inputProps,
			hideLabel: true,
			className: (0, import_classnames.default)(`${blockClass}__inline-edit--select`, { [`${blockClass}__inline-edit--select-${rowSize}`]: rowSize }),
			items: inputProps?.items || [],
			initialSelectedItem: cell.value,
			itemToElement: handleTransformedItem(inputProps?.items),
			renderSelectedItem: handleTransformedItem(inputProps?.items),
			onChange: (item) => {
				const newCellId = getNewCellId("Enter");
				saveCellData(item.selectedItem);
				setCellValue(item.selectedItem);
				dispatch({
					type: "EXIT_EDIT_MODE",
					payload: newCellId
				});
				setInEditMode(false);
				sendFocusBackToGrid();
				inputProps?.onChange?.(item.selectedItem);
			},
			downshiftProps: { onStateChange: (downshiftState) => {
				const { isOpen } = downshiftState || {};
				if (isOpen === false) {
					dispatch({
						type: "EXIT_EDIT_MODE",
						payload: cellId
					});
					setInEditMode(false);
					sendFocusBackToGrid();
				}
			} },
			ref: dropdownRef,
			autoAlign: true
		});
	};
	const setRenderIcon = () => {
		if (type === "text") return Edit;
		if (type === "number") return CaretSort;
		if (type === "selection") return ChevronDown;
		if (type === "date") return Calendar;
	};
	const renderDateCell = () => {
		const datePickerPreparedProps = prepareProps(config.inputProps, ["datePickerInputProps"]);
		const datePickerInputProps = config?.inputProps?.datePickerInputProps;
		return /* @__PURE__ */ React.createElement(DatePicker, {
			...datePickerPreparedProps,
			appendTo: outerButtonElement?.current?.parentElement,
			ref: (el) => {
				if (el && el.style) {
					el.style.width = `${cell.column.totalWidth}px`;
					const elementId = `${blockClass}__inline-edit--date-picker--${cell.row.index}`;
					const element = el.querySelector(`input#${elementId}`);
					if (element) element.style.position = "static";
				}
			},
			datePickerType: "single",
			className: (0, import_classnames.default)(`${blockClass}__inline-edit--date`, { [`${blockClass}__inline-edit--date-${rowSize}`]: rowSize }),
			onChange: (newDate) => {
				const newDateObj = newDate[0];
				datePickerPreparedProps?.onChange?.(newDateObj, cell);
				const newCellId = getNewCellId("Enter");
				saveCellData(newDateObj);
				setCellValue(newDateObj);
				setTimeout(() => {
					setInEditMode(false);
					sendFocusBackToGrid();
					dispatch({
						type: "EXIT_EDIT_MODE",
						payload: newCellId
					});
				}, 1);
			},
			value: cell.value
		}, /* @__PURE__ */ React.createElement(DatePickerInput, {
			...datePickerInputProps,
			placeholder: datePickerInputProps?.placeholder || "mm/dd/yyyy",
			labelText: datePickerInputProps?.labelText || cellLabel || "Set date",
			id: `${blockClass}__inline-edit--date-picker--${cell.row.index}`,
			hideLabel: true
		}));
	};
	const padTo2Digits = (num) => {
		return num.toString().padStart(2, "0");
	};
	const buildDate = (value) => {
		const dateFormat = config?.inputProps?.dateFormat;
		if (value instanceof Date) {
			const maskedFullYear = value.getFullYear();
			const maskedMonth = padTo2Digits(value.getMonth() + 1);
			const maskedDay = padTo2Digits(value.getDate());
			if (dateFormat === "m/d/Y" || value === "m/d/y") return [
				maskedMonth,
				maskedDay,
				maskedFullYear
			].join("/");
			if (dateFormat === "d/m/Y" || dateFormat === "d/m/y" || dateFormat === void 0) return [
				maskedDay,
				maskedMonth,
				maskedFullYear
			].join("/");
		} else return value;
		return null;
	};
	const renderNumberInput = () => {
		const { validator } = config || {};
		return /* @__PURE__ */ React.createElement(NumberInput, {
			placeholder,
			label: cellLabel,
			...inputProps,
			id: cellId,
			hideLabel: true,
			defaultValue: cellValue,
			invalid: validator?.(cellValue),
			invalidText: inputProps?.invalidText || "Provide missing invalidText",
			onChange: (event, { value }) => {
				setCellValue(value);
				if (inputProps.onChange) inputProps.onChange(value);
			},
			ref: numberInputRef
		});
	};
	const renderCheckBoxCell = () => {
		return /* @__PURE__ */ React.createElement(Checkbox, {
			labelText: cellLabel || "Checkbox",
			...inputProps,
			className: (0, import_classnames.default)(`${blockClass}__inline-edit--outer-cell-checkbox`, { [`${blockClass}__inline-edit--outer-cell-checkbox-focus`]: activeCellId === cellId }),
			id: cellId,
			hideLabel: true,
			checked: cellValue,
			onChange: (event, { checked }) => {
				setCellValue(checked);
				if (inputProps.onChange) inputProps.onChange(checked);
			},
			ref: checkboxRef
		});
	};
	const renderTextInput = () => {
		const { validator } = config || {};
		const isInvalid = validator?.(cellValue);
		return /* @__PURE__ */ React.createElement(TextInput, {
			labelText: cellLabel,
			placeholder,
			...inputProps,
			id: cellId,
			hideLabel: true,
			defaultValue: cellValue,
			invalid: isInvalid,
			invalidText: inputProps?.invalidText || "Provide missing invalidText",
			onChange: (event) => {
				setCellValue(event.target.value);
				if (inputProps.onChange) inputProps.onChange(event.target.value);
			},
			ref: textInputRef
		});
	};
	const getLabel = () => {
		const checkStaticCell = (val) => {
			if (typeof val === "object" && val?.isStaticCell) return val?.value;
		};
		switch (type) {
			case "selection":
				checkStaticCell(value);
				return value?.text ?? value;
			case "date":
				checkStaticCell(value);
				return buildDate(value);
			default: return checkStaticCell(value) ?? value;
		}
	};
	return /* @__PURE__ */ React.createElement("div", {
		ref: outerButtonElement,
		"data-cell-id": cellId,
		"data-column-index": columnIndex,
		"data-row-index": cell.row.index,
		"data-disabled": disabledCell || nonEditCell,
		"data-inline-type": type,
		onClick: !nonEditCell ? handleInlineCellClick : addActiveState,
		onKeyDown: !nonEditCell ? handleKeyDown : null,
		className: (0, import_classnames.default)(`${blockClass}__inline-edit--outer-cell-button`, {
			[`${blockClass}__inline-edit--outer-cell-button--${rowSize}`]: rowSize,
			[`${blockClass}__inline-edit--outer-cell-button--lg`]: !rowSize,
			[`${blockClass}__inline-edit--outer-cell-button--invalid`]: inEditMode && config?.validator?.(cellValue),
			[`${blockClass}__static--outer-cell`]: !disabledCell
		})
	}, (!inEditMode || disabledCell) && type !== "checkbox" && /* @__PURE__ */ React.createElement(InlineEditButton, {
		isActiveCell: cellId === activeCellId,
		renderIcon: setRenderIcon(),
		label: getLabel(),
		disabledCell,
		labelIcon: value?.icon || null,
		placeholder,
		tabIndex,
		nonEditCell,
		columnConfig: cell.column,
		type
	}), type === "checkbox" && renderCheckBoxCell(), !nonEditCell && inEditMode && cellId === activeCellId && /* @__PURE__ */ React.createElement(React.Fragment, null, type === "text" && renderTextInput(), type === "number" && renderNumberInput(), type === "selection" && renderSelectCell(), type === "date" && renderDateCell()));
};
InlineEditCell.propTypes = {
	cell: PropTypes.object,
	config: PropTypes.object,
	disabledCell: PropTypes.bool,
	instance: PropTypes.shape({
		columns: PropTypes.arrayOf(PropTypes.object),
		onDataUpdate: PropTypes.func,
		rows: PropTypes.arrayOf(PropTypes.object),
		rowSize: PropTypes.string,
		tableId: PropTypes.string,
		cellEditing: PropTypes.object
	}),
	nonEditCell: PropTypes.bool,
	placeholder: PropTypes.string,
	tabIndex: PropTypes.number,
	type: PropTypes.oneOf([
		"text",
		"number",
		"selection",
		"date",
		"checkbox"
	]),
	value: PropTypes.oneOfType([
		PropTypes.string,
		PropTypes.node,
		PropTypes.object
	])
};
//#endregion
export { InlineEditCell };
