import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { ChevronDown, ChevronUp, X } from "lucide-react";
import { Button } from "../../components/ui/button";
import { RuleElementPicker } from "./RuleElementPicker";
import { RuleParameterInput } from "./RuleParameterInput";
import { createLeafCondition } from "./utils";
function getElement(elements, id) {
    return elements.find((element) => element.id === id);
}
function isNotWrapper(node) {
    return (node.kind === "composite" && node.op === "not" && node.children.length === 1);
}
function unwrapNot(node) {
    if (isNotWrapper(node) && node.kind === "composite" && node.children[0]) {
        return { inner: node.children[0], negated: true };
    }
    return { inner: node, negated: false };
}
function rewrapNot(inner, negated) {
    if (!negated)
        return inner;
    return { kind: "composite", op: "not", children: [inner] };
}
export function ConditionTreeEditor({ condition, elements, disabled, onChange, }) {
    if (!condition) {
        return (_jsxs("div", { className: "space-y-2", children: [_jsx("div", { className: "border-border-default text-2xs text-neutral-grey-50 rounded border border-dashed px-3 py-2", children: "Without conditions, this rule always applies. Add a condition to target a specific audience." }), _jsx(RuleElementPicker, { elements: elements, kind: "condition", label: "Add condition", disabled: disabled, fullWidth: true, onPick: (element) => onChange(createLeafCondition(element.id)) })] }));
    }
    // Treat the top level as a flat AND/OR list of children. A standalone NOT
    // wrapping a single leaf at the very top is treated as a one-child list
    // with that child negated; anything else is a single-child list.
    const isFlatComposite = condition.kind === "composite" &&
        (condition.op === "and" || condition.op === "or");
    const children = isFlatComposite
        ? condition.children
        : [condition];
    const op = isFlatComposite
        ? condition.op
        : "and";
    const commit = (nextChildren, nextOp = op) => {
        if (nextChildren.length === 0) {
            onChange(null);
            return;
        }
        if (nextChildren.length === 1) {
            onChange(nextChildren[0]);
            return;
        }
        onChange({
            kind: "composite",
            op: nextOp,
            children: nextChildren,
        });
    };
    return (_jsx(ConditionList, { op: op, children: children, elements: elements, disabled: disabled, onOpChange: (next) => commit(children, next), onChildrenChange: (next) => commit(next) }));
}
function ConditionList({ op, children, elements, disabled, onOpChange, onChildrenChange, }) {
    const updateChild = (index, next) => {
        if (next === null) {
            onChildrenChange(children.filter((_, i) => i !== index));
            return;
        }
        onChildrenChange(children.map((existing, i) => (i === index ? next : existing)));
    };
    const moveChild = (index, direction) => {
        const target = index + direction;
        if (target < 0 || target >= children.length)
            return;
        const next = [...children];
        const [moved] = next.splice(index, 1);
        if (!moved)
            return;
        next.splice(target, 0, moved);
        onChildrenChange(next);
    };
    return (_jsxs("div", { className: "space-y-0.5", children: [children.map((child, index) => (_jsx(ConditionRow, { isFirst: index === 0, isLast: index === children.length - 1, op: op, child: child, elements: elements, disabled: disabled, onOpChange: onOpChange, onChange: (next) => updateChild(index, next), onMove: (direction) => moveChild(index, direction) }, index))), _jsx("div", { className: "pt-1", children: _jsx(RuleElementPicker, { elements: elements, kind: "condition", label: "Add condition", disabled: disabled, fullWidth: true, onPick: (element) => onChildrenChange([...children, createLeafCondition(element.id)]) }) })] }));
}
function ConditionRow({ isFirst, isLast, op, child, elements, disabled, onOpChange, onChange, onMove, }) {
    const { inner, negated } = unwrapNot(child);
    const setNegated = (n) => onChange(rewrapNot(inner, n));
    const setInner = (next) => {
        if (next === null) {
            onChange(null);
            return;
        }
        onChange(rewrapNot(next, negated));
    };
    const prefix = (_jsx(ConnectorPrefix, { isFirst: isFirst, op: op, negated: negated, disabled: disabled, onOpChange: onOpChange, onNegatedChange: setNegated }));
    const trailing = (_jsx(RowActions, { isFirst: isFirst, isLast: isLast, disabled: disabled, onMove: onMove, onRemove: () => onChange(null) }));
    if (inner.kind === "composite" && inner.op !== "not") {
        return (_jsxs("div", { className: "group hover:bg-neutral-grey-5 rounded px-1 py-1", children: [_jsxs("div", { className: "flex items-start justify-between gap-2", children: [_jsx("div", { className: "text-neutral-grey-100 flex-1 text-xs leading-7", children: prefix }), trailing] }), _jsx("div", { className: "border-border-default bg-neutral-grey-5/60 mt-1 ml-3 rounded border p-2", children: _jsx(ConditionList, { op: inner.op === "or" ? "or" : "and", children: inner.children, elements: elements, disabled: disabled, onOpChange: (nextOp) => setInner({ ...inner, op: nextOp }), onChildrenChange: (nextChildren) => setInner({ ...inner, children: nextChildren }) }) })] }));
    }
    if (inner.kind === "unsupported") {
        return (_jsxs("div", { className: "group border-feedback-orange bg-feedback-orange-light text-2xs text-feedback-orange hover:bg-feedback-orange-light flex items-start justify-between gap-2 rounded border p-2", children: [_jsxs("div", { className: "flex-1 leading-6", children: [prefix, _jsx("span", { children: "this condition cannot be edited in Parhelia yet." })] }), trailing] }));
    }
    if (inner.kind === "leaf") {
        const leaf = inner;
        const element = getElement(elements, leaf.definitionItemId);
        const setLeafParameters = (parameters) => setInner({ ...leaf, parameters });
        return (_jsxs("div", { className: "group hover:bg-neutral-grey-5 flex items-start gap-2 rounded px-1 py-1", children: [_jsx("div", { className: "min-w-0 flex-1", children: element ? (_jsx(RuleParameterInput, { element: element, values: leaf.parameters, disabled: disabled, onChange: setLeafParameters, prefix: prefix, stripLeadingWhere: true })) : (_jsxs("div", { className: "text-neutral-grey-50 text-xs leading-7", children: [prefix, _jsxs("span", { children: ["unknown condition (", leaf.definitionItemId, ")"] })] })) }), trailing] }));
    }
    // Fallback for unexpected shapes (e.g. degenerate double-NOT) — render the
    // raw inner via a recursive ConditionList so it's still editable.
    return (_jsxs("div", { className: "group hover:bg-neutral-grey-5 rounded px-1 py-1", children: [_jsxs("div", { className: "flex items-start justify-between gap-2", children: [_jsx("div", { className: "text-neutral-grey-100 flex-1 text-xs leading-7", children: prefix }), trailing] }), _jsx("div", { className: "border-border-default bg-neutral-grey-5/60 mt-1 ml-3 rounded border p-2", children: _jsx(ConditionList, { op: "and", children: [inner], elements: elements, disabled: disabled, onOpChange: () => undefined, onChildrenChange: (next) => setInner(next[0] ?? null) }) })] }));
}
function ConnectorPrefix({ isFirst, op, negated, disabled, onOpChange, onNegatedChange, }) {
    return (_jsxs("span", { className: "mr-1 whitespace-nowrap select-none", children: [!isFirst && (_jsxs(_Fragment, { children: [_jsx(ConnectorLink, { disabled: disabled, onClick: () => onOpChange(op === "and" ? "or" : "and"), title: "Toggle AND / OR", children: op }), " "] })), _jsx(ConnectorLink, { disabled: disabled, onClick: () => onNegatedChange(!negated), title: negated ? "Remove negation" : "Negate condition", children: negated ? "except where" : "where" }), " "] }));
}
function ConnectorLink({ children, disabled, onClick, title, }) {
    return (_jsx("button", { type: "button", disabled: disabled, onClick: onClick, title: title, className: "text-feedback-blue cursor-pointer underline-offset-2 hover:underline disabled:cursor-not-allowed disabled:opacity-60", children: children }));
}
function RowActions({ isFirst, isLast, disabled, onMove, onRemove, }) {
    return (_jsxs("div", { className: "flex shrink-0 items-center opacity-0 transition-opacity group-hover:opacity-100 focus-within:opacity-100", children: [_jsx(RowIconButton, { label: "Move up", disabled: disabled || isFirst, onClick: () => onMove(-1), children: _jsx(ChevronUp, { className: "size-3" }) }), _jsx(RowIconButton, { label: "Move down", disabled: disabled || isLast, onClick: () => onMove(1), children: _jsx(ChevronDown, { className: "size-3" }) }), _jsx(RowIconButton, { label: "Remove condition", danger: true, disabled: disabled, onClick: onRemove, children: _jsx(X, { className: "size-3" }) })] }));
}
function RowIconButton({ label, disabled, danger, onClick, children, }) {
    return (_jsx(Button, { type: "button", size: "xxs", variant: "ghost", disabled: disabled, onClick: onClick, "aria-label": label, title: label, className: `size-6 rounded-md p-0 ${danger ? "hover:bg-feedback-red-light hover:text-feedback-red" : ""}`, children: children }));
}
//# sourceMappingURL=ConditionTreeEditor.js.map