import { n as __exportAll } from "./chunk-B-1-B7_t.js";
import { n as Button_default } from "./button-B9CnnuTu.js";
import { t as Input_default } from "./input-CwDp-vE8.js";
import { n as Label_default } from "./label-C5K3zowH.js";
import { r as Switch_default } from "./switch-E1QdwZg_.js";
import { Fragment, computed, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, normalizeClass, openBlock, renderList, resolveComponent, toDisplayString, unref, withCtx } from "vue";
import { Plus, Trash2 } from "@lucide/vue";
//#region src/components/compositions/elements/builder/ConditionsEditor.vue?vue&type=script&setup=true&lang.ts
var _hoisted_1 = {
	class: "flex flex-col gap-2",
	"data-testid": "form-builder-conditions-editor"
};
var _hoisted_2 = {
	key: 0,
	class: "flex items-center justify-between gap-2 rounded border bg-background px-2 py-1"
};
var _hoisted_3 = ["id", "value"];
var _hoisted_4 = {
	key: 1,
	class: "rounded border border-dashed bg-muted/30 px-2.5 py-3 text-center text-[11px] leading-snug text-muted-foreground",
	"data-testid": "form-builder-conditions-empty"
};
var _hoisted_5 = ["data-testid", "data-sub-condition"];
var _hoisted_6 = { class: "flex items-center justify-between gap-1" };
var _hoisted_7 = { class: "text-[10px] font-semibold uppercase tracking-wider text-muted-foreground" };
var _hoisted_8 = { class: "flex items-center justify-between rounded border bg-background px-2 py-1" };
var _hoisted_9 = { class: "flex flex-col gap-1" };
var _hoisted_10 = { class: "flex flex-col gap-1" };
var _hoisted_11 = [
	"id",
	"value",
	"data-testid",
	"onChange"
];
var _hoisted_12 = ["value"];
var _hoisted_13 = {
	key: 0,
	class: "flex flex-col gap-1"
};
var _hoisted_14 = ["data-testid"];
var ConditionsEditor_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
	__name: "ConditionsEditor",
	props: {
		modelValue: {},
		groupLogic: {},
		idPrefix: { default: "fb-cond" },
		depth: { default: 0 }
	},
	emits: ["update:modelValue", "update:groupLogic"],
	setup(__props, { emit: __emit }) {
		/**
		* ConditionsEditor — inspector pane for editing a `conditionParams` array
		* (and the surrounding `conditionGroupLogic`) on any element, card, or tab
		* container. Mirrors the legacy `Components/Mod/v2` JSON shape so the
		* resulting object slots straight back into v2 JSON without translation.
		*
		* Each row edits one `ConditionParam`:
		*   - `name`  — data field name to compare against
		*   - `logic` — the operator
		*   - `value` — comparison value (hidden for unary operators)
		*
		* A row can also be a **sub-condition** group: flipping the "Group of
		* conditions" switch sets `subCondition: true`, hides the name/logic/value
		* inputs, and reveals a recursive ConditionsEditor for the row's nested
		* `conditionParams` (with its own `conditionGroupLogic`). The engine in
		* `useDisplayConditions.ts` already evaluates this shape — see the
		* `param.subCondition` branch there.
		*/
		const props = __props;
		const emit = __emit;
		const rows = computed(() => props.modelValue ?? []);
		/** Logic operators surfaced in the dropdown. Mirrors the v2 schema. */
		const LOGIC_OPTIONS = [
			{
				value: "==",
				label: "Equals (==)"
			},
			{
				value: "!=",
				label: "Not equals (!=)"
			},
			{
				value: ">",
				label: "Greater than (>)"
			},
			{
				value: ">=",
				label: "Greater than or equal (>=)"
			},
			{
				value: "<",
				label: "Less than (<)"
			},
			{
				value: "<=",
				label: "Less than or equal (<=)"
			},
			{
				value: "in-array",
				label: "In array"
			},
			{
				value: "not-in-array",
				label: "Not in array"
			},
			{
				value: "starts-with",
				label: "Starts with"
			},
			{
				value: "ends-with",
				label: "Ends with"
			},
			{
				value: "contains",
				label: "Contains"
			},
			{
				value: "not-contains",
				label: "Does not contain"
			},
			{
				value: "matches",
				label: "Matches regex"
			},
			{
				value: "is-truthy",
				label: "Is truthy"
			},
			{
				value: "is-falsy",
				label: "Is falsy"
			},
			{
				value: "is-null",
				label: "Is null"
			},
			{
				value: "is-not-null",
				label: "Is not null"
			},
			{
				value: "is-odd",
				label: "Is odd"
			},
			{
				value: "is-even",
				label: "Is even"
			},
			{
				value: "g0length",
				label: "Length > 0"
			},
			{
				value: "zero-length",
				label: "Length == 0"
			},
			{
				value: "length-eq-value",
				label: "Length equals value"
			},
			{
				value: "length-gt-value",
				label: "Length greater than value"
			},
			{
				value: "length-lt-value",
				label: "Length less than value"
			}
		];
		/** Operators that don't read a `value` from the user. */
		const UNARY_LOGICS = new Set([
			"is-truthy",
			"is-falsy",
			"is-null",
			"is-not-null",
			"is-odd",
			"is-even",
			"g0length",
			"n0length",
			"zero-length"
		]);
		function isUnary(logic) {
			return Boolean(logic && UNARY_LOGICS.has(logic));
		}
		function emitRows(next) {
			emit("update:modelValue", next);
		}
		function onAddRow() {
			emitRows([...rows.value, {
				name: "",
				logic: "==",
				value: ""
			}]);
		}
		function onRemoveRow(index) {
			const next = rows.value.slice();
			next.splice(index, 1);
			emitRows(next);
		}
		function onFieldUpdate(index, patch) {
			emitRows(rows.value.map((row, i) => i === index ? {
				...row,
				...patch
			} : row));
		}
		function onGroupLogicChange(value) {
			if (value === "AND" || value === "OR") emit("update:groupLogic", value);
		}
		/**
		* Toggle a row between flat condition and nested sub-condition group. When
		* turning ON we seed an empty nested group with AND logic; when turning OFF
		* we discard the nested config (the row reverts to its existing name/logic/
		* value, which were preserved through the toggle).
		*/
		function onSubConditionToggle(index, value) {
			if (value) onFieldUpdate(index, {
				subCondition: true,
				conditionParams: rows.value[index]?.conditionParams ?? [],
				conditionGroupLogic: rows.value[index]?.conditionGroupLogic ?? "AND"
			});
			else emitRows(rows.value.map((row, i) => {
				if (i !== index) return row;
				const copy = { ...row };
				delete copy.subCondition;
				delete copy.conditionParams;
				delete copy.conditionGroupLogic;
				return copy;
			}));
		}
		function onNestedConditionsUpdate(index, next) {
			onFieldUpdate(index, { conditionParams: next });
		}
		function onNestedGroupLogicUpdate(index, next) {
			onFieldUpdate(index, { conditionGroupLogic: next });
		}
		const inputId = (suffix, index) => `${props.idPrefix}-${suffix}-${index}`;
		return (_ctx, _cache) => {
			const _component_ConditionsEditor = resolveComponent("ConditionsEditor", true);
			return openBlock(), createElementBlock("div", _hoisted_1, [
				rows.value.length >= 2 ? (openBlock(), createElementBlock("div", _hoisted_2, [createVNode(unref(Label_default), {
					for: `${props.idPrefix}-group-logic`,
					class: "text-xs"
				}, {
					default: withCtx(() => [..._cache[1] || (_cache[1] = [createTextVNode(" Match ", -1)])]),
					_: 1
				}, 8, ["for"]), createElementVNode("select", {
					id: `${props.idPrefix}-group-logic`,
					class: "h-7 rounded-md border border-input bg-background px-2 text-xs shadow-sm focus:outline-none focus:ring-1 focus:ring-ring",
					value: props.groupLogic ?? "AND",
					"data-testid": "form-builder-conditions-group-logic",
					onChange: _cache[0] || (_cache[0] = (e) => onGroupLogicChange(e.target.value))
				}, [..._cache[2] || (_cache[2] = [createElementVNode("option", { value: "AND" }, "All (AND)", -1), createElementVNode("option", { value: "OR" }, "Any (OR)", -1)])], 40, _hoisted_3)])) : createCommentVNode("", true),
				rows.value.length === 0 ? (openBlock(), createElementBlock("p", _hoisted_4, [props.depth === 0 ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createTextVNode(" No conditions — this always renders. Add a condition to control when it's shown. ")], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createTextVNode(" Empty group — add nested conditions below. ")], 64))])) : createCommentVNode("", true),
				(openBlock(true), createElementBlock(Fragment, null, renderList(rows.value, (row, index) => {
					return openBlock(), createElementBlock("div", {
						key: index,
						class: normalizeClass(["flex flex-col gap-1.5 rounded border bg-background p-2", row.subCondition ? "border-primary/40 bg-primary/[0.03]" : ""]),
						"data-testid": `form-builder-condition-row-${index}`,
						"data-sub-condition": row.subCondition ? "true" : void 0
					}, [
						createElementVNode("div", _hoisted_6, [createElementVNode("span", _hoisted_7, toDisplayString(row.subCondition ? "Group" : "Condition") + " " + toDisplayString(index + 1), 1), createVNode(unref(Button_default), {
							type: "button",
							variant: "ghost",
							size: "icon-sm",
							class: "h-6 w-6 text-destructive",
							"aria-label": "Remove condition",
							"data-testid": `form-builder-condition-remove-${index}`,
							onClick: ($event) => onRemoveRow(index)
						}, {
							default: withCtx(() => [createVNode(unref(Trash2), { class: "h-3 w-3" })]),
							_: 1
						}, 8, ["data-testid", "onClick"])]),
						createElementVNode("div", _hoisted_8, [createVNode(unref(Label_default), {
							for: inputId("sub", index),
							class: "cursor-pointer text-[11px]"
						}, {
							default: withCtx(() => [..._cache[3] || (_cache[3] = [createTextVNode(" Group of conditions ", -1)])]),
							_: 1
						}, 8, ["for"]), createVNode(unref(Switch_default), {
							id: inputId("sub", index),
							"model-value": Boolean(row.subCondition),
							"data-testid": `form-builder-condition-sub-${index}`,
							"onUpdate:modelValue": (v) => onSubConditionToggle(index, v)
						}, null, 8, [
							"id",
							"model-value",
							"data-testid",
							"onUpdate:modelValue"
						])]),
						!row.subCondition ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
							createElementVNode("div", _hoisted_9, [createVNode(unref(Label_default), {
								for: inputId("name", index),
								class: "text-[11px]"
							}, {
								default: withCtx(() => [..._cache[4] || (_cache[4] = [createTextVNode(" Field name ", -1)])]),
								_: 1
							}, 8, ["for"]), createVNode(unref(Input_default), {
								id: inputId("name", index),
								"model-value": row.name,
								placeholder: "e.g. first_name",
								"data-testid": `form-builder-condition-name-${index}`,
								onInput: (e) => onFieldUpdate(index, { name: e.target.value })
							}, null, 8, [
								"id",
								"model-value",
								"data-testid",
								"onInput"
							])]),
							createElementVNode("div", _hoisted_10, [createVNode(unref(Label_default), {
								for: inputId("logic", index),
								class: "text-[11px]"
							}, {
								default: withCtx(() => [..._cache[5] || (_cache[5] = [createTextVNode(" Logic ", -1)])]),
								_: 1
							}, 8, ["for"]), createElementVNode("select", {
								id: inputId("logic", index),
								class: "flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm shadow-sm transition-colors focus:outline-none focus:ring-1 focus:ring-ring",
								value: row.logic,
								"data-testid": `form-builder-condition-logic-${index}`,
								onChange: (e) => onFieldUpdate(index, { logic: e.target.value })
							}, [(openBlock(), createElementBlock(Fragment, null, renderList(LOGIC_OPTIONS, (opt) => {
								return createElementVNode("option", {
									key: opt.value,
									value: opt.value
								}, toDisplayString(opt.label), 9, _hoisted_12);
							}), 64))], 40, _hoisted_11)]),
							!isUnary(row.logic) ? (openBlock(), createElementBlock("div", _hoisted_13, [createVNode(unref(Label_default), {
								for: inputId("value", index),
								class: "text-[11px]"
							}, {
								default: withCtx(() => [..._cache[6] || (_cache[6] = [createTextVNode(" Value ", -1)])]),
								_: 1
							}, 8, ["for"]), createVNode(unref(Input_default), {
								id: inputId("value", index),
								"model-value": row.value == null ? "" : String(row.value),
								placeholder: "Comparison value",
								"data-testid": `form-builder-condition-value-${index}`,
								onInput: (e) => onFieldUpdate(index, { value: e.target.value })
							}, null, 8, [
								"id",
								"model-value",
								"data-testid",
								"onInput"
							])])) : createCommentVNode("", true)
						], 64)) : (openBlock(), createElementBlock("div", {
							key: 1,
							class: "ml-2 mt-1 border-l-2 border-primary/30 pl-2",
							"data-testid": `form-builder-condition-nested-${index}`
						}, [createVNode(_component_ConditionsEditor, {
							"model-value": row.conditionParams ?? [],
							"group-logic": row.conditionGroupLogic ?? "AND",
							"id-prefix": `${props.idPrefix}-${index}`,
							depth: props.depth + 1,
							"onUpdate:modelValue": (next) => onNestedConditionsUpdate(index, next),
							"onUpdate:groupLogic": (next) => onNestedGroupLogicUpdate(index, next)
						}, null, 8, [
							"model-value",
							"group-logic",
							"id-prefix",
							"depth",
							"onUpdate:modelValue",
							"onUpdate:groupLogic"
						])], 8, _hoisted_14))
					], 10, _hoisted_5);
				}), 128)),
				createVNode(unref(Button_default), {
					type: "button",
					variant: "outline",
					size: "sm",
					class: "self-start",
					"data-testid": "form-builder-condition-add",
					onClick: onAddRow
				}, {
					default: withCtx(() => [createVNode(unref(Plus), { class: "h-3.5 w-3.5" }), _cache[7] || (_cache[7] = createTextVNode(" Add condition ", -1))]),
					_: 1
				})
			]);
		};
	}
});
//#endregion
//#region src/components/compositions/elements/builder/ConditionsEditor.vue
var ConditionsEditor_exports = /* @__PURE__ */ __exportAll({ default: () => ConditionsEditor_default });
var ConditionsEditor_default = ConditionsEditor_vue_vue_type_script_setup_true_lang_default;
//#endregion
export { ConditionsEditor_exports as n, ConditionsEditor_default as t };

//# sourceMappingURL=ConditionsEditor-BICfvLu6.js.map