/**
 * 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 uuidv4 from "../../../global/js/utils/uuidv4.js";
import { blockClass } from "../utils/util.js";
import { ConditionBuilderContext, getEmptyState } from "../ConditionBuilderContext/ConditionBuilderProvider.js";
import { ConditionBuilderButton } from "../ConditionBuilderButton/ConditionBuilderButton.js";
import { useTranslations } from "../utils/useTranslations.js";
import ConditionPreview from "../ConditionPreview/ConditionPreview.js";
import ConditionGroupBuilder from "../ConditionGroupBuilder/ConditionGroupBuilder.js";
import GroupConnector from "../ConditionBuilderConnector/GroupConnector.js";
import ConditionBuilderActions from "../ConditionBuilderActions/ConditionBuilderActions.js";
import React, { useCallback, useContext, useEffect, useRef, useState } from "react";
import PropTypes from "prop-types";
import { Button, Heading, Section } from "@carbon/react";
import { Add, TextNewLine } from "@carbon/react/icons";
//#region src/components/ConditionBuilder/ConditionBuilderContent/ConditionBuilderContent.tsx
/**
* 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.
*/
/**@ts-ignore */
const ConditionBuilderContent = ({ startConditionLabel, getConditionState, getActionsState, initialState, actions }) => {
	const { rootState, setRootState, variant, actionState, onAddItem, onRemoveItem, readOnly, statementConfigCustom } = useContext(ConditionBuilderContext);
	const initialConditionState = useRef(initialState?.state ? JSON.parse(JSON.stringify(initialState?.state)) : null);
	const [isConditionBuilderActive, setIsConditionBuilderActive] = useState(false);
	const [showConditionGroupPreview, setShowConditionGroupPreview] = useState(false);
	const [addConditionGroupText, conditionHeadingText, conditionBuilderHierarchicalText] = useTranslations([
		"addConditionGroupText",
		"conditionHeadingText",
		"conditionBuilderHierarchicalText"
	]);
	const showConditionGroupPreviewHandler = () => {
		setShowConditionGroupPreview(true);
	};
	const hideConditionGroupPreviewHandler = () => {
		setShowConditionGroupPreview(false);
	};
	useEffect(() => {
		if (rootState?.groups?.length) setIsConditionBuilderActive(true);
		else setIsConditionBuilderActive(false);
		if (getConditionState) getConditionState(rootState ?? {});
	}, [rootState]);
	useEffect(() => {
		getActionsState?.(actionState ?? []);
	}, [actionState]);
	useEffect(() => {
		if (initialState?.enabledDefault) setRootState?.(initialState.state);
	}, [initialState]);
	const onStartConditionBuilder = () => {
		setIsConditionBuilderActive(true);
		if (initialConditionState?.current?.groups?.length) {
			setRootState?.(initialConditionState.current);
			initialConditionState.current = null;
		} else setRootState?.(getEmptyState(statementConfigCustom));
	};
	const onRemove = useCallback((groupId) => {
		const groupToRemove = rootState?.groups?.find((group) => group?.id === groupId);
		const { preventRemove } = onRemoveItem?.({
			type: "group",
			state: rootState,
			item: groupToRemove
		}) ?? {};
		if (!preventRemove) {
			const groups = rootState?.groups?.filter((group) => groupId !== group?.id);
			setRootState?.({
				...rootState,
				groups: rootState ? groups : []
			});
			if (groups?.length === 0) initialConditionState.current = null;
		}
	}, [
		setRootState,
		rootState,
		onRemoveItem
	]);
	const onChangeHandler = (updatedGroup, groupIndex) => {
		/**
		* This method is triggered from inner components. This will be called every time when any change is to be updated in the rootState.
		* This gets the updated group as argument.
		*/
		if (rootState && rootState.groups) {
			const groups = [
				...rootState.groups ? rootState.groups.slice(0, groupIndex) : [],
				updatedGroup,
				...rootState.groups ? rootState.groups.slice(groupIndex + 1) : []
			];
			setRootState?.({
				...rootState,
				groups
			});
		}
	};
	const addConditionGroupHandler = () => {
		const { preventAdd } = onAddItem?.({
			type: "group",
			state: rootState
		}) ?? {};
		if (!preventAdd) {
			const newGroup = getEmptyState(statementConfigCustom).groups?.[0];
			setRootState?.({
				...rootState,
				groups: rootState && rootState.groups ? [...rootState.groups, newGroup] : [newGroup]
			});
		}
	};
	const getColorIndex = () => {
		return (rootState?.groups?.length ?? 0) % 5;
	};
	if (!isConditionBuilderActive) return /* @__PURE__ */ React.createElement(Button, {
		className: `${blockClass}__addConditionText-button`,
		renderIcon: (props) => /* @__PURE__ */ React.createElement(Add, props),
		iconDescription: startConditionLabel,
		kind: "ghost",
		size: "sm",
		onClick: onStartConditionBuilder
	}, startConditionLabel);
	const wrapperRole = variant === "Hierarchical" ? {
		role: "treegrid",
		"aria-label": conditionBuilderHierarchicalText
	} : null;
	return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Section, {
		className: `${blockClass}__heading`,
		level: 4
	}, /* @__PURE__ */ React.createElement(Heading, null, conditionHeadingText)), /* @__PURE__ */ React.createElement("div", {
		className: `${blockClass}__content-container`,
		...wrapperRole
	}, rootState && rootState?.groups?.map((eachGroup, groupIndex) => /* @__PURE__ */ React.createElement("div", {
		key: eachGroup.id,
		className: `${blockClass}__group-wrapper`
	}, /* @__PURE__ */ React.createElement(ConditionGroupBuilder, {
		className: `${blockClass}__group`,
		aria: {
			level: 1,
			posinset: groupIndex * 2 + 1,
			setsize: (rootState.groups && rootState.groups.length * 2) ?? 0
		},
		group: eachGroup,
		onRemove: () => {
			onRemove(eachGroup.id);
		},
		onChange: (updatedGroup) => {
			onChangeHandler(updatedGroup, groupIndex);
		}
	}), rootState.groups && groupIndex < rootState.groups.length - 1 && /* @__PURE__ */ React.createElement(GroupConnector, null))), !readOnly && variant == "Hierarchical" && /* @__PURE__ */ React.createElement("div", {
		role: "row",
		tabIndex: -1,
		"aria-level": 1,
		className: `${blockClass}__add-group`
	}, /* @__PURE__ */ React.createElement(ConditionBuilderButton, {
		renderIcon: TextNewLine,
		onClick: addConditionGroupHandler,
		onMouseEnter: showConditionGroupPreviewHandler,
		onMouseLeave: hideConditionGroupPreviewHandler,
		onFocus: showConditionGroupPreviewHandler,
		onBlur: hideConditionGroupPreviewHandler,
		className: `${blockClass}__add-condition-group `,
		hideLabel: true,
		label: addConditionGroupText,
		wrapperProps: {
			role: "gridcell",
			"aria-label": addConditionGroupText
		}
	})), variant === "Hierarchical" ? /* @__PURE__ */ React.createElement(ConditionPreview, {
		previewType: "newGroup",
		colorIndex: getColorIndex(),
		className: showConditionGroupPreview ? `${blockClass}__visible` : `${blockClass}__hidden`,
		group: {
			groupOperator: rootState?.operator,
			id: uuidv4()
		}
	}) : null), actions && /* @__PURE__ */ React.createElement(ConditionBuilderActions, {
		actions,
		className: `${blockClass}__actions-container`
	}));
};
ConditionBuilderContent.propTypes = {
	/**
	* optional array of object that give the list of actions.
	*/
	actions: PropTypes.arrayOf(PropTypes.shape({
		id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
		label: PropTypes.string.isRequired
	})),
	/**
	* callback functions that will provide the updated action state back.
	*/
	getActionsState: PropTypes.func,
	/**
	* This is a callback function that returns the updated state
	*/
	getConditionState: PropTypes.func.isRequired,
	/**
	* Optional prop if the condition building need to start from a predefined initial state
	*/
	initialState: PropTypes.shape({
		state: PropTypes.shape({
			groups: PropTypes.arrayOf(PropTypes.shape({
				groupOperator: PropTypes.string,
				statement: PropTypes.string,
				conditions: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.shape({
					property: PropTypes.string,
					operator: PropTypes.string,
					value: PropTypes.oneOfType([
						PropTypes.string,
						PropTypes.arrayOf(PropTypes.shape({
							id: PropTypes.string,
							label: PropTypes.string
						})),
						PropTypes.shape({
							id: PropTypes.string,
							label: PropTypes.string
						})
					])
				}), PropTypes.object]))
			})),
			operator: PropTypes.string
		}),
		enabledDefault: PropTypes.bool
	}),
	startConditionLabel: PropTypes.string.isRequired
};
//#endregion
export { ConditionBuilderContent as default };
