import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
import { FormItem, FormLabel, FormControl, FormDescription } from '../../../components/form.mjs';
import { ChildrenSearchableSelect } from '../../../components/ui-builder/internal/form-fields/children-searchable-select.mjs';
import IconNameField from '../../../components/ui-builder/internal/form-fields/iconname-field.mjs';
import { Textarea } from '../../../components/textarea.mjs';
import { MinimalTiptapEditor } from '../../../components/minimal-tiptap/minimal-tiptap.mjs';
import { Tooltip, TooltipTrigger, TooltipContent } from '../../../components/tooltip.mjs';
import { useLayerStore } from '../store/layer-store.mjs';
import 'react';
import { isVariableReference } from '../../../components/ui-builder/types.mjs';
import { Link, LockKeyhole, Unlink } from 'lucide-react';
import { Button } from '../../../components/button.mjs';
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from '../../../components/dropdown-menu.mjs';
import 'clsx';
import 'tailwind-merge';
import { useEditorStore } from '../store/editor-store.mjs';
import { Card, CardContent } from '../../../components/card.mjs';
import { BreakpointClassNameControl } from '../../../components/ui-builder/internal/form-fields/classname-control/breakpoint-classname-control.mjs';
import { Label } from '../../../components/label.mjs';
import { Badge } from '../../../components/badge.mjs';
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from '../../../components/select.mjs';

const classNameFieldOverrides = (layer) => {
  return {
    fieldType: ({
      label,
      isRequired,
      field,
      fieldConfigItem
    }) => /* @__PURE__ */ jsx(
      FormFieldWrapper,
      {
        label,
        isRequired,
        fieldConfigItem,
        children: /* @__PURE__ */ jsx(
          BreakpointClassNameControl,
          {
            value: field.value,
            onChange: field.onChange
          }
        )
      }
    )
  };
};
const childrenFieldOverrides = (layer, allowVariableBinding = true) => {
  return {
    renderParent: allowVariableBinding ? ({ children }) => /* @__PURE__ */ jsx(ChildrenVariableBindingWrapper, { children }) : void 0,
    fieldType: ({
      label,
      isRequired,
      fieldConfigItem,
      field,
      fieldProps
    }) => /* @__PURE__ */ jsx(
      FormFieldWrapper,
      {
        label,
        isRequired,
        fieldConfigItem,
        children: /* @__PURE__ */ jsx(
          ChildrenSearchableSelect,
          {
            layer,
            onChange: field.onChange,
            ...fieldProps
          }
        )
      }
    )
  };
};
const iconNameFieldOverrides = (layer) => {
  return {
    fieldType: ({
      label,
      isRequired,
      field,
      fieldProps
    }) => /* @__PURE__ */ jsx(
      IconNameField,
      {
        label,
        isRequired,
        value: layer.props.iconName,
        onChange: field.onChange,
        ...fieldProps
      }
    )
  };
};
const childrenAsTextareaFieldOverrides = (layer, allowVariableBinding = true) => {
  return {
    renderParent: allowVariableBinding ? ({ children }) => /* @__PURE__ */ jsx(ChildrenVariableBindingWrapper, { children }) : void 0,
    fieldType: ({
      label,
      isRequired,
      fieldConfigItem,
      field,
      fieldProps
    }) => /* @__PURE__ */ jsx(
      FormFieldWrapper,
      {
        label,
        isRequired,
        fieldConfigItem,
        children: /* @__PURE__ */ jsx(
          Textarea,
          {
            value: typeof layer.children === "string" ? layer.children : "",
            onChange: field.onChange,
            ...fieldProps
          }
        )
      }
    )
  };
};
const childrenAsTipTapFieldOverrides = (layer, allowVariableBinding = true) => {
  return {
    renderParent: allowVariableBinding ? ({ children }) => /* @__PURE__ */ jsx(ChildrenVariableBindingWrapper, { children }) : void 0,
    fieldType: ({
      label,
      isRequired,
      fieldConfigItem,
      field,
      fieldProps
    }) => /* @__PURE__ */ jsx(
      FormFieldWrapper,
      {
        label,
        isRequired,
        fieldConfigItem,
        children: /* @__PURE__ */ jsx(
          MinimalTiptapEditor,
          {
            immediatelyRender: false,
            output: "markdown",
            editable: true,
            value: typeof layer.children === "string" ? layer.children : "",
            editorClassName: "focus:outline-none px-4 py-2 h-full",
            onChange: (content) => {
              if (typeof content === "string") {
                field.onChange(content);
              } else {
                console.warn("Tiptap content is not a string");
              }
            },
            ...fieldProps
          }
        )
      }
    )
  };
};
const memoizedCommonFieldOverrides = /* @__PURE__ */ new Map();
const commonFieldOverrides = (allowBinding = true) => {
  if (memoizedCommonFieldOverrides.has(allowBinding)) {
    return memoizedCommonFieldOverrides.get(allowBinding);
  }
  const overrides = {
    className: (layer) => classNameFieldOverrides(),
    children: (layer) => childrenFieldOverrides(layer, allowBinding)
  };
  memoizedCommonFieldOverrides.set(allowBinding, overrides);
  return overrides;
};
function FunctionPropField({
  propName,
  label,
  isRequired,
  fieldConfigItem
}) {
  const selectedLayerId = useLayerStore((state) => state.selectedLayerId);
  const findLayerById = useLayerStore((state) => state.findLayerById);
  const updateLayer = useLayerStore((state) => state.updateLayer);
  const incrementRevision = useEditorStore((state) => state.incrementRevision);
  const functionRegistry = useEditorStore((state) => state.functionRegistry);
  const unbindPropFromVariable = useLayerStore(
    (state) => state.unbindPropFromVariable
  );
  const selectedLayer = findLayerById(selectedLayerId);
  if (!selectedLayer || !functionRegistry) {
    return /* @__PURE__ */ jsx(
      FormFieldWrapper,
      {
        label,
        isRequired,
        fieldConfigItem,
        children: /* @__PURE__ */ jsx(Select, { disabled: true, children: /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "No function registry available" }) }) })
      }
    );
  }
  const functionEntries = Object.entries(functionRegistry);
  const getCurrentFunctionId = () => {
    const directFuncId = selectedLayer.props[`__function_${propName}`];
    if (typeof directFuncId === "string") {
      return directFuncId;
    }
    return "";
  };
  const handleValueChange = (value) => {
    if (value === "__none__") {
      unbindPropFromVariable(selectedLayer.id, propName);
      updateLayer(selectedLayer.id, {
        [`__function_${propName}`]: void 0,
        [propName]: void 0
      });
      incrementRevision();
      return;
    }
    const funcDef = functionRegistry[value];
    if (funcDef) {
      unbindPropFromVariable(selectedLayer.id, propName);
      updateLayer(selectedLayer.id, {
        [propName]: funcDef.fn,
        [`__function_${propName}`]: value
      });
      incrementRevision();
    }
  };
  const currentFunctionId = getCurrentFunctionId();
  const getDisplayText = () => {
    if (currentFunctionId) {
      const funcDef = functionRegistry[currentFunctionId];
      return funcDef?.name || currentFunctionId;
    }
    return "Select a function...";
  };
  return /* @__PURE__ */ jsx(
    FormFieldWrapper,
    {
      label,
      isRequired,
      fieldConfigItem,
      children: /* @__PURE__ */ jsxs(
        Select,
        {
          value: currentFunctionId,
          onValueChange: handleValueChange,
          children: [
            /* @__PURE__ */ jsx(SelectTrigger, { className: "w-full mb-0", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select a function...", children: getDisplayText() }) }),
            /* @__PURE__ */ jsxs(SelectContent, { children: [
              /* @__PURE__ */ jsx(SelectItem, { value: "__none__", children: /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "None (clear)" }) }),
              functionEntries.length > 0 && /* @__PURE__ */ jsx(Fragment, { children: functionEntries.map(([id, funcDef]) => /* @__PURE__ */ jsx(SelectItem, { value: id, children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
                /* @__PURE__ */ jsx("span", { children: funcDef.name }),
                funcDef.description && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: funcDef.description })
              ] }) }, id)) })
            ] })
          ]
        }
      )
    }
  );
}
const functionPropFieldOverrides = (propName) => {
  return {
    renderParent: ({ children }) => /* @__PURE__ */ jsx(VariableBindingWrapper, { propName, isFunctionProp: true, children }),
    fieldType: (props) => /* @__PURE__ */ jsx(FunctionPropField, { propName, ...props })
  };
};
function VariableBindingWrapper({
  propName,
  children,
  isFunctionProp = false
}) {
  const variables = useLayerStore((state) => state.variables);
  const selectedLayerId = useLayerStore((state) => state.selectedLayerId);
  const findLayerById = useLayerStore((state) => state.findLayerById);
  const isBindingImmutable = useLayerStore((state) => state.isBindingImmutable);
  const incrementRevision = useEditorStore((state) => state.incrementRevision);
  const functionRegistry = useEditorStore((state) => state.functionRegistry);
  const unbindPropFromVariable = useLayerStore(
    (state) => state.unbindPropFromVariable
  );
  const bindPropToVariable = useLayerStore((state) => state.bindPropToVariable);
  const selectedLayer = findLayerById(selectedLayerId);
  if (!selectedLayer) {
    return /* @__PURE__ */ jsx(Fragment, { children });
  }
  const filteredVariables = variables.filter(
    (v) => isFunctionProp ? v.type === "function" : v.type !== "function"
  );
  const currentValue = selectedLayer.props[propName];
  const isCurrentlyBound = isVariableReference(currentValue);
  const boundVariable = isCurrentlyBound ? variables.find((v) => v.id === currentValue.__variableRef) : null;
  const isImmutable = isBindingImmutable(selectedLayer.id, propName);
  const getFunctionDisplayValue = (variable) => {
    if (variable.type === "function" && functionRegistry) {
      const funcId = String(variable.defaultValue);
      const funcDef = functionRegistry[funcId];
      return funcDef ? funcDef.name : funcId;
    }
    return String(variable.defaultValue);
  };
  const handleBindToVariable = (variableId) => {
    bindPropToVariable(selectedLayer.id, propName, variableId);
    incrementRevision();
  };
  const handleUnbind = () => {
    unbindPropFromVariable(selectedLayer.id, propName);
    incrementRevision();
  };
  const emptyMessage = isFunctionProp ? "No function variables defined" : "No variables defined";
  const bindLabel = isFunctionProp ? "Bind to Function Variable" : "Bind to Variable";
  const tooltipLabel = isFunctionProp ? "Bind Function" : "Bind Variable";
  return /* @__PURE__ */ jsx("div", { className: "flex w-full gap-2 items-end", children: isCurrentlyBound && boundVariable ? (
    // Bound state - show variable info and unbind button
    /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 w-full", children: [
      /* @__PURE__ */ jsx(Label, { children: propName.charAt(0).toUpperCase() + propName.slice(1) }),
      /* @__PURE__ */ jsxs("div", { className: "flex items-end gap-2 w-full", children: [
        /* @__PURE__ */ jsx(Card, { className: "w-full overflow-hidden min-w-0", children: /* @__PURE__ */ jsx(CardContent, { className: "py-1 px-4", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 w-full", children: [
          /* @__PURE__ */ jsx(Link, { className: "h-4 w-4 flex-shrink-0" }),
          /* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-0 flex-1", children: [
            /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 w-full", children: [
              /* @__PURE__ */ jsx("span", { className: "font-medium", children: boundVariable.name }),
              /* @__PURE__ */ jsx("span", { className: "px-1.5 py-0.5 bg-muted rounded text-xs font-mono", children: boundVariable.type }),
              isImmutable && /* @__PURE__ */ jsx(Badge, { "data-testid": "immutable-badge", className: "rounded", children: /* @__PURE__ */ jsx(LockKeyhole, { strokeWidth: 3, className: "w-3 h-3" }) })
            ] }),
            /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground truncate", children: getFunctionDisplayValue(boundVariable) })
          ] })
        ] }) }) }),
        !isImmutable && /* @__PURE__ */ jsxs(Tooltip, { children: [
          /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
            Button,
            {
              variant: "outline",
              onClick: handleUnbind,
              className: "px-3 h-10",
              "data-testid": "unbind-variable-button",
              children: /* @__PURE__ */ jsx(Unlink, { className: "h-4 w-4" })
            }
          ) }),
          /* @__PURE__ */ jsx(TooltipContent, { children: "Unbind Variable" })
        ] })
      ] })
    ] })
  ) : (
    // Unbound state - show normal field with bind button
    /* @__PURE__ */ jsxs(Fragment, { children: [
      /* @__PURE__ */ jsx("div", { className: "flex-1", children }),
      /* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [
        /* @__PURE__ */ jsxs(Tooltip, { children: [
          /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", className: "px-3 h-10", "data-testid": "bind-variable-button", children: /* @__PURE__ */ jsx(Link, { className: "h-4 w-4 my-1" }) }) }) }),
          /* @__PURE__ */ jsx(TooltipContent, { children: tooltipLabel })
        ] }),
        /* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", className: "w-56", children: [
          /* @__PURE__ */ jsx("div", { className: "px-2 py-1.5 text-xs font-medium text-muted-foreground border-b", children: bindLabel }),
          filteredVariables.length > 0 ? filteredVariables.map((variable) => /* @__PURE__ */ jsx(
            DropdownMenuItem,
            {
              onClick: () => handleBindToVariable(variable.id),
              className: "flex flex-col items-start p-3",
              children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 w-full", children: [
                /* @__PURE__ */ jsx(Link, { className: "h-4 w-4 flex-shrink-0" }),
                /* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-0 flex-1", children: [
                  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 ", children: [
                    /* @__PURE__ */ jsx("span", { className: "font-medium", children: variable.name }),
                    /* @__PURE__ */ jsx("span", { className: "px-1.5 py-0.5 bg-muted rounded text-xs font-mono", children: variable.type })
                  ] }),
                  /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground truncate", children: getFunctionDisplayValue(variable) })
                ] })
              ] })
            },
            variable.id
          )) : /* @__PURE__ */ jsx("div", { className: "px-3 py-2 text-xs text-muted-foreground", children: emptyMessage })
        ] })
      ] }) })
    ] })
  ) });
}
function FormFieldWrapper({
  label,
  isRequired,
  fieldConfigItem,
  children
}) {
  return /* @__PURE__ */ jsxs(FormItem, { className: "flex flex-col", children: [
    /* @__PURE__ */ jsxs(FormLabel, { children: [
      label,
      isRequired && /* @__PURE__ */ jsx("span", { className: "text-destructive", children: " *" })
    ] }),
    /* @__PURE__ */ jsx(FormControl, { children }),
    fieldConfigItem?.description && /* @__PURE__ */ jsx(FormDescription, { children: fieldConfigItem.description })
  ] });
}
function ChildrenVariableBindingWrapper({
  children
}) {
  const variables = useLayerStore((state) => state.variables);
  const selectedLayerId = useLayerStore((state) => state.selectedLayerId);
  const findLayerById = useLayerStore((state) => state.findLayerById);
  const isChildrenBindingImmutable = useLayerStore((state) => state.isChildrenBindingImmutable);
  const incrementRevision = useEditorStore((state) => state.incrementRevision);
  const unbindChildrenFromVariable = useLayerStore(
    (state) => state.unbindChildrenFromVariable
  );
  const bindChildrenToVariable = useLayerStore((state) => state.bindChildrenToVariable);
  const selectedLayer = findLayerById(selectedLayerId);
  if (!selectedLayer) {
    return /* @__PURE__ */ jsx(Fragment, { children });
  }
  const currentValue = selectedLayer.children;
  const isCurrentlyBound = isVariableReference(currentValue);
  const boundVariable = isCurrentlyBound ? variables.find((v) => v.id === currentValue.__variableRef) : null;
  const isImmutable = isChildrenBindingImmutable(selectedLayer.id);
  const handleBindToVariable = (variableId) => {
    bindChildrenToVariable(selectedLayer.id, variableId);
    incrementRevision();
  };
  const handleUnbind = () => {
    unbindChildrenFromVariable(selectedLayer.id);
    incrementRevision();
  };
  return /* @__PURE__ */ jsx("div", { className: "flex w-full gap-2 items-end", children: isCurrentlyBound && boundVariable ? (
    // Bound state - show variable info and unbind button
    /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 w-full", children: [
      /* @__PURE__ */ jsx(Label, { children: "Children" }),
      /* @__PURE__ */ jsxs("div", { className: "flex items-end gap-2 w-full", children: [
        /* @__PURE__ */ jsx(Card, { className: "w-full overflow-hidden min-w-0", children: /* @__PURE__ */ jsx(CardContent, { className: "py-1 px-4", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 w-full", children: [
          /* @__PURE__ */ jsx(Link, { className: "h-4 w-4 flex-shrink-0" }),
          /* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-0 flex-1", children: [
            /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 w-full", children: [
              /* @__PURE__ */ jsx("span", { className: "font-medium", children: boundVariable.name }),
              /* @__PURE__ */ jsx("span", { className: "px-1.5 py-0.5 bg-muted rounded text-xs font-mono", children: boundVariable.type }),
              isImmutable && /* @__PURE__ */ jsx(Badge, { "data-testid": "immutable-children-badge", className: "rounded", children: /* @__PURE__ */ jsx(LockKeyhole, { strokeWidth: 3, className: "w-3 h-3" }) })
            ] }),
            /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground truncate", children: String(boundVariable.defaultValue) })
          ] })
        ] }) }) }),
        !isImmutable && /* @__PURE__ */ jsxs(Tooltip, { children: [
          /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
            Button,
            {
              variant: "outline",
              onClick: handleUnbind,
              className: "px-3 h-10",
              "data-testid": "unbind-children-button",
              children: /* @__PURE__ */ jsx(Unlink, { className: "h-4 w-4" })
            }
          ) }),
          /* @__PURE__ */ jsx(TooltipContent, { children: "Unbind Variable" })
        ] })
      ] })
    ] })
  ) : (
    // Unbound state - show normal field with bind button
    /* @__PURE__ */ jsxs(Fragment, { children: [
      /* @__PURE__ */ jsx("div", { className: "flex-1", children }),
      /* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [
        /* @__PURE__ */ jsxs(Tooltip, { children: [
          /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", className: "px-3 h-10", "data-testid": "bind-children-button", children: /* @__PURE__ */ jsx(Link, { className: "h-4 w-4 my-1" }) }) }) }),
          /* @__PURE__ */ jsx(TooltipContent, { children: "Bind Children to Variable" })
        ] }),
        /* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", className: "w-56", children: [
          /* @__PURE__ */ jsx("div", { className: "px-2 py-1.5 text-xs font-medium text-muted-foreground border-b", children: "Bind Children to Variable" }),
          variables.filter((v) => v.type === "string").length > 0 ? variables.filter((v) => v.type === "string").map((variable) => /* @__PURE__ */ jsx(
            DropdownMenuItem,
            {
              onClick: () => handleBindToVariable(variable.id),
              className: "flex flex-col items-start p-3",
              children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 w-full", children: [
                /* @__PURE__ */ jsx(Link, { className: "h-4 w-4 flex-shrink-0" }),
                /* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-0 flex-1", children: [
                  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 ", children: [
                    /* @__PURE__ */ jsx("span", { className: "font-medium", children: variable.name }),
                    /* @__PURE__ */ jsx("span", { className: "px-1.5 py-0.5 bg-muted rounded text-xs font-mono", children: variable.type })
                  ] }),
                  /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground truncate", children: String(variable.defaultValue) })
                ] })
              ] })
            },
            variable.id
          )) : /* @__PURE__ */ jsx("div", { className: "px-3 py-2 text-xs text-muted-foreground", children: "No string variables defined" })
        ] })
      ] }) })
    ] })
  ) });
}

export { ChildrenVariableBindingWrapper, FormFieldWrapper, VariableBindingWrapper, childrenAsTextareaFieldOverrides, childrenAsTipTapFieldOverrides, childrenFieldOverrides, classNameFieldOverrides, commonFieldOverrides, functionPropFieldOverrides, iconNameFieldOverrides };
