/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-a795c5b | Cube Dev Team */
import { isDevEnv } from "./is-dev-env.js";
import { isSelector } from "../pipeline/index.js";

//#region src/tasty/utils/merge-styles.ts
const devMode = isDevEnv();
const INHERIT_VALUE = "@inherit";
/**
* Check if a value is a state map (object, not array).
*/
function isStateMap(value) {
	return typeof value === "object" && value !== null && !Array.isArray(value);
}
/**
* Normalize a parent value to a state map.
* - Already a state map → return as-is
* - Non-null, non-false primitive → wrap as `{ '': value }`
* - null / undefined / false → return null (no parent to merge with)
*/
function normalizeToStateMap(value) {
	if (isStateMap(value)) return value;
	if (value != null && value !== false) return { "": value };
	return null;
}
/**
* Resolve a child state map against a parent value.
*
* Mode is determined by whether the child contains a `''` (default) key:
* - No `''` → extend mode: parent entries preserved, child adds/overrides/repositions
* - Has `''` → replace mode: child defines everything, `@inherit` cherry-picks from parent
*
* In both modes:
* - `@inherit` value → resolve from parent state map
* - `null` value → remove this state from the result
* - `false` value → tombstone, persists through all layers, blocks recipe
*/
function resolveStateMap(parentValue, childMap) {
	const isExtend = !("" in childMap);
	const parentMap = normalizeToStateMap(parentValue);
	if (!parentMap) {
		const result = {};
		for (const key of Object.keys(childMap)) {
			const val = childMap[key];
			if (val === null || val === INHERIT_VALUE) continue;
			result[key] = val;
		}
		return result;
	}
	if (isExtend) return resolveExtendMode(parentMap, childMap);
	return resolveReplaceMode(parentMap, childMap);
}
/**
* Extend mode: parent entries are preserved, child entries add/override/reposition.
*/
function resolveExtendMode(parentMap, childMap) {
	const inheritKeys = /* @__PURE__ */ new Set();
	const removeKeys = /* @__PURE__ */ new Set();
	const overrideKeys = /* @__PURE__ */ new Map();
	for (const key of Object.keys(childMap)) {
		const val = childMap[key];
		if (val === INHERIT_VALUE) {
			if (key in parentMap) inheritKeys.add(key);
			else if (devMode) console.warn(`[Tasty] @inherit used for state '${key}' that does not exist in the parent style map. Entry skipped.`);
		} else if (val === null) removeKeys.add(key);
		else if (key in parentMap) overrideKeys.set(key, val);
	}
	const result = {};
	for (const key of Object.keys(parentMap)) {
		if (removeKeys.has(key)) continue;
		if (inheritKeys.has(key)) continue;
		if (overrideKeys.has(key)) result[key] = overrideKeys.get(key);
		else result[key] = parentMap[key];
	}
	for (const key of Object.keys(childMap)) if (inheritKeys.has(key)) result[key] = parentMap[key];
	else if (!removeKeys.has(key) && !overrideKeys.has(key) && childMap[key] !== INHERIT_VALUE) result[key] = childMap[key];
	return result;
}
/**
* Replace mode: child entries define the result, `@inherit` pulls from parent.
*/
function resolveReplaceMode(parentMap, childMap) {
	const result = {};
	for (const key of Object.keys(childMap)) {
		const val = childMap[key];
		if (val === INHERIT_VALUE) {
			if (key in parentMap) result[key] = parentMap[key];
			else if (devMode) console.warn(`[Tasty] @inherit used for state '${key}' that does not exist in the parent style map. Entry skipped.`);
		} else if (val !== null) result[key] = val;
	}
	return result;
}
/**
* Merge sub-element properties with state map / null / undefined support.
*/
function mergeSubElementStyles(parentSub, childSub) {
	const parent = parentSub;
	const child = childSub;
	const merged = {
		...parent,
		...child
	};
	for (const key of Object.keys(child)) {
		const val = child[key];
		if (val === void 0) {
			if (parent && key in parent) merged[key] = parent[key];
		} else if (val === null) delete merged[key];
		else if (isStateMap(val)) merged[key] = resolveStateMap(parent ? parent[key] : void 0, val);
	}
	return merged;
}
function mergeStyles(...objects) {
	let styles = objects[0] ? { ...objects[0] } : {};
	let pos = 1;
	while (pos in objects) {
		const selectorKeys = Object.keys(styles).filter((key) => isSelector(key) && styles[key]);
		const newStyles = objects[pos];
		if (newStyles) {
			const resultStyles = {
				...styles,
				...newStyles
			};
			const newSelectorKeys = Object.keys(newStyles).filter(isSelector);
			const allSelectorKeys = new Set([...selectorKeys, ...newSelectorKeys]);
			for (const key of allSelectorKeys) {
				const newValue = newStyles?.[key];
				if (newValue === false || newValue === null) delete resultStyles[key];
				else if (newValue === void 0) resultStyles[key] = styles[key];
				else if (newValue) resultStyles[key] = mergeSubElementStyles(styles[key], newValue);
			}
			for (const key of Object.keys(newStyles)) {
				if (isSelector(key)) continue;
				const newValue = newStyles[key];
				if (newValue === void 0) if (key in styles) resultStyles[key] = styles[key];
				else delete resultStyles[key];
				else if (newValue === null) delete resultStyles[key];
				else if (isStateMap(newValue)) resultStyles[key] = resolveStateMap(styles[key], newValue);
			}
			styles = resultStyles;
		}
		pos++;
	}
	return styles;
}

//#endregion
export { mergeStyles };
//# sourceMappingURL=merge-styles.js.map