/**
 * 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 uuidv4 from "../../../global/js/utils/uuidv4.js";
import { deepCloneObject } from "../../../global/js/utils/deepCloneObject.js";
import { removeCellSelections } from "./removeCellSelections.js";
import { handleMultipleKeys, includesResourceKey, includesShift } from "./handleMultipleKeys.js";
import { checkForHoldingKey } from "./checkForHoldingKey.js";
import { handleHeaderCellSelection } from "./handleHeaderCellSelection.js";
import { handleActiveCellInSelectionEnter } from "./handleActiveCellInSelectionEnter.js";
import { handleActiveCellInSelectionTab } from "./handleActiveCellInSelectionTab.js";
import { handleCellDeletion } from "./handleCellDeletion.js";

//#region src/components/DataSpreadsheet/utils/commonEventHandlers.js
/**
* Copyright IBM Corp. 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.
*/
const blockClass = `${pkg.prefix}--data-spreadsheet`;
const handleBodyCellClick = (cell, columnIndex, event, ...rest) => {
	const [currentMatcher, activeCellCoordinates, selectionAreas, setActiveCellCoordinates, setSelectionAreas, setContainerHasFocus, setClickAndHoldActive, setCurrentMatcher, ref, setSelectionAreaData, setActiveCellInsideSelectionArea, activeCellRef, setValidStartingPoint] = rest;
	event.preventDefault();
	setValidStartingPoint(event.target.closest(`.${blockClass}__body--td`).classList.contains(`${blockClass}__body--td`));
	const isHoldingCommandKey = checkForHoldingKey(event, "cmd");
	const isHoldingShiftKey = checkForHoldingKey(event, "shiftKey");
	setContainerHasFocus(true);
	const activeCoordinates = {
		row: cell.row.index,
		column: columnIndex
	};
	const tempMatcher = uuidv4();
	setClickAndHoldActive(true);
	if (isHoldingCommandKey) {
		ref.current.querySelector(`.${blockClass}__active-cell--highlight`).setAttribute("data-selection-id", tempMatcher);
		setActiveCellInsideSelectionArea(true);
		setActiveCellCoordinates(activeCoordinates);
		setCurrentMatcher(tempMatcher);
		setSelectionAreas((prev) => [...prev, {
			point1: activeCoordinates,
			matcher: tempMatcher
		}]);
	} else if (isHoldingShiftKey) {
		setContainerHasFocus(true);
		const selectionAreaClone = deepCloneObject(selectionAreas);
		const indexOfItemToUpdate = selectionAreaClone.findIndex((item) => item.matcher === currentMatcher);
		if (indexOfItemToUpdate === -1) return;
		else {
			selectionAreaClone[indexOfItemToUpdate].point1 = activeCellCoordinates;
			selectionAreaClone[indexOfItemToUpdate].point2 = activeCoordinates;
			selectionAreaClone[indexOfItemToUpdate].areaCreated = false;
			selectionAreaClone[indexOfItemToUpdate].matcher = currentMatcher;
			setSelectionAreas(selectionAreaClone);
		}
	} else {
		activeCellRef.current.style.display = "none";
		setActiveCellInsideSelectionArea(false);
		setActiveCellCoordinates(activeCoordinates);
		removeCellSelections({ spreadsheetRef: ref });
		setSelectionAreas([{
			point1: activeCoordinates,
			matcher: tempMatcher
		}]);
		setCurrentMatcher(tempMatcher);
		setSelectionAreaData([]);
	}
};
const handleBodyCellHover = (cell, columnIndex, ...rest) => {
	const [clickAndHoldActive, currentMatcher, setSelectionAreas] = rest;
	if (clickAndHoldActive) {
		const cellCoordinates = {
			row: cell.row.index,
			column: columnIndex
		};
		setSelectionAreas((prev) => {
			const selectionAreaClone = deepCloneObject(prev);
			const indexOfItemToUpdate = selectionAreaClone.findIndex((item) => item.matcher === currentMatcher);
			if (indexOfItemToUpdate === -1) return prev;
			if (selectionAreaClone[indexOfItemToUpdate].point2?.row === cellCoordinates.row && selectionAreaClone[indexOfItemToUpdate].point2?.column === cellCoordinates.column) return prev;
			selectionAreaClone[indexOfItemToUpdate].point2 = cellCoordinates;
			selectionAreaClone[indexOfItemToUpdate].areaCreated = false;
			return selectionAreaClone;
		});
	}
};
const handleRowHeaderClick = (index, event, ...rest) => {
	const [columns, ref, setSelectionAreas, setCurrentMatcher, setActiveCellCoordinates, activeCellCoordinates, rows, setSelectionAreaData] = rest;
	handleHeaderCellSelection({
		type: "row",
		activeCellCoordinates,
		rows,
		columns,
		setActiveCellCoordinates,
		setCurrentMatcher,
		setSelectionAreas,
		spreadsheetRef: ref,
		index,
		setSelectionAreaData,
		isHoldingCommandKey: checkForHoldingKey(event, "cmd")
	});
};
const handleKeyPress = (event, ...rest) => {
	const [activeCellInsideSelectionArea, updateActiveCellCoordinates, activeCellCoordinates, removeActiveCell, columns, rows, spreadsheetRef, currentMatcher, removeCellEditor, selectionAreas, handleHomeEndKey, keysPressedList, usingMac, updateData, checkForReturnCondition, handleArrowKeyPress, setSelectionAreas, setSelectionAreaData, setCurrentMatcher, activeCellRef, setActiveCellCoordinates, setContainerHasFocus, setActiveCellContent] = rest;
	const { key } = event;
	if (checkForReturnCondition(key)) return;
	if ([
		"ArrowLeft",
		"ArrowUp",
		"ArrowRight",
		"ArrowDown"
	].indexOf(key) > -1) {
		if (selectionAreas?.length && keysPressedList.length < 2 && !includesShift(keysPressedList)) {
			setSelectionAreas([]);
			setSelectionAreaData([]);
			removeCellSelections({ spreadsheetRef });
		}
	}
	if (keysPressedList?.length > 1) handleMultipleKeys({
		activeCellCoordinates,
		event,
		keysPressedList,
		selectionAreas,
		currentMatcher,
		rows,
		setSelectionAreas,
		columns,
		updateActiveCellCoordinates,
		spreadsheetRef,
		removeCellSelections,
		blockClass,
		setCurrentMatcher,
		usingMac
	});
	if (keysPressedList.length < 2 && !includesShift(keysPressedList) || activeCellCoordinates.row === "header" || activeCellCoordinates.column === "header") switch (key) {
		case "Backspace":
		case "Delete":
			handleCellDeletion({
				selectionAreas,
				currentMatcher,
				rows,
				setActiveCellContent,
				updateData,
				activeCellCoordinates
			});
			break;
		case "Enter":
			handleActiveCellInSelectionEnter({
				activeCellInsideSelectionArea,
				activeCellCoordinates,
				activeCellRef,
				selectionAreas,
				updateActiveCellCoordinates
			});
			break;
		case "Home":
		case "End":
			event.preventDefault();
			if (includesResourceKey(keysPressedList, usingMac)) return;
			handleHomeEndKey({ type: key });
			break;
		case "Tab":
			if (activeCellInsideSelectionArea) {
				event.preventDefault();
				return handleActiveCellInSelectionTab({
					activeCellInsideSelectionArea,
					activeCellCoordinates,
					activeCellRef,
					selectionAreas,
					updateActiveCellCoordinates
				});
			}
			setSelectionAreas([]);
			removeActiveCell();
			removeCellEditor();
			setContainerHasFocus(false);
			setActiveCellCoordinates(null);
			break;
		case "ArrowLeft":
		case "ArrowUp":
		case "ArrowRight":
		case "ArrowDown": handleArrowKeyPress(key);
	}
};

//#endregion
export { handleBodyCellClick, handleBodyCellHover, handleKeyPress, handleRowHeaderClick };