"use client";
'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

const jsxRuntime = require('react/jsx-runtime');
const React = require('react');
const core_esm = require('../../../../../node_modules/.pnpm/@dnd-kit_core@6.3.1_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/@dnd-kit/core/dist/core.esm.cjs');
const sortable_esm = require('../../../../../node_modules/.pnpm/@dnd-kit_sortable@10.0.0_@dnd-kit_core@6.3.1_react-dom@19.2.0_react@19.2.0__react@19.2.0__react@19.2.0/node_modules/@dnd-kit/sortable/dist/sortable.esm.cjs');
const utils = require('../../lib/utils.cjs');
const tabs = require('../tabs.cjs');
const palette = require('./palette.cjs');
const canvas = require('./canvas.cjs');
const editFieldDialog = require('./edit-field-dialog.cjs');
const nestedFieldEditorDialog = require('./nested-field-editor-dialog.cjs');
const formPreview = require('./form-preview.cjs');
const sortableField = require('./sortable-field.cjs');
const index = require('./components/index.cjs');
const schemaUtils = require('./schema-utils.cjs');
const validationSchemas = require('./validation-schemas.cjs');

function FormBuilder({
  components = index.defaultComponents,
  value,
  onChange,
  className,
  fieldComponents,
  defaultValues
}) {
  const dndContextId = React.useId();
  const [fields, setFields] = React.useState(() => {
    if (!value) return [];
    const { fields: parsedFields } = schemaUtils.jsonSchemaToFieldsAndSteps(value, components);
    return parsedFields;
  });
  const [steps, setSteps] = React.useState(() => {
    if (!value) return [];
    const { steps: parsedSteps } = schemaUtils.jsonSchemaToFieldsAndSteps(value, components);
    return parsedSteps;
  });
  const [activeStepIndex, setActiveStepIndex] = React.useState(0);
  const [editDialogFieldId, setEditDialogFieldId] = React.useState(null);
  const [nestedEditorFieldId, setNestedEditorFieldId] = React.useState(null);
  const [activeId, setActiveId] = React.useState(null);
  const notifyChange = React.useCallback(
    (newFields, newSteps) => {
      if (onChange) {
        const schema = schemaUtils.fieldsToJSONSchema(newFields, components, newSteps ?? steps);
        onChange(schema);
      }
    },
    [onChange, components, steps]
  );
  const currentSchema = React.useMemo(
    () => schemaUtils.fieldsToJSONSchema(fields, components, steps),
    [fields, components, steps]
  );
  const sensors = core_esm.useSensors(
    core_esm.useSensor(core_esm.PointerSensor, {
      activationConstraint: {
        distance: 8
      }
    }),
    core_esm.useSensor(core_esm.TouchSensor, {
      activationConstraint: {
        // Use distance instead of delay for better compatibility with
        // automated testing tools and faster touch interactions
        distance: 8
      }
    }),
    core_esm.useSensor(core_esm.KeyboardSensor, {
      coordinateGetter: sortable_esm.sortableKeyboardCoordinates
    })
  );
  const activeDragData = React.useMemo(() => {
    if (!activeId) return null;
    const idStr = String(activeId);
    if (idStr.startsWith("palette-")) {
      const componentType = idStr.replace("palette-", "");
      return {
        type: "palette",
        componentType,
        component: index.getComponentByType(componentType, components)
      };
    }
    const field = fields.find((f) => f.id === idStr);
    if (field) {
      return {
        type: "field",
        field,
        component: index.getComponentByType(field.type, components)
      };
    }
    return null;
  }, [activeId, fields, components]);
  const handleDragStart = (event) => {
    setActiveId(event.active.id);
  };
  const handleDragEnd = (event) => {
    const { active, over } = event;
    setActiveId(null);
    if (!over) return;
    const activeData = active.data.current;
    if (activeData?.type === "palette") {
      const { componentType } = activeData;
      const component = index.getComponentByType(componentType, components);
      if (component) {
        const newField = {
          id: schemaUtils.generateFieldId(componentType),
          type: componentType,
          props: {
            label: component.defaultProps.label || component.label,
            ...component.defaultProps
          },
          // Assign to active step when in multi-step mode
          ...steps.length > 1 ? { stepGroup: activeStepIndex } : {}
        };
        let insertIndex = fields.length;
        const overId = String(over.id);
        if (overId === "drop-zone-start") {
          insertIndex = 0;
        } else if (overId.startsWith("drop-zone-")) {
          const fieldId = overId.replace("drop-zone-", "");
          const overIndex = fields.findIndex((f) => f.id === fieldId);
          if (overIndex !== -1) {
            insertIndex = overIndex + 1;
          }
        } else if (overId !== "canvas") {
          const overIndex = fields.findIndex((f) => f.id === overId);
          if (overIndex !== -1) {
            insertIndex = overIndex + 1;
          }
        }
        const newFields = [...fields];
        newFields.splice(insertIndex, 0, newField);
        setFields(newFields);
        notifyChange(newFields);
      }
      return;
    }
    if (activeData?.type === "field" && active.id !== over.id) {
      const oldIndex = fields.findIndex((f) => f.id === active.id);
      const newIndex = fields.findIndex((f) => f.id === over.id);
      if (oldIndex !== -1 && newIndex !== -1) {
        const newFields = sortable_esm.arrayMove(fields, oldIndex, newIndex);
        setFields(newFields);
        notifyChange(newFields);
      }
    }
  };
  const handleUpdateField = React.useCallback(
    (id, props, newId, stepGroup) => {
      if (newId && newId !== id) {
        const idExists = fields.some((f) => f.id === newId && f.id !== id);
        if (idExists) {
          console.warn(`Cannot rename field "${id}" to "${newId}": a field with that ID already exists`);
          return;
        }
      }
      const newFields = fields.map((f) => {
        if (f.id !== id) return f;
        const updated = {
          ...f,
          id: newId || f.id,
          props: { ...f.props, ...props }
        };
        if (stepGroup !== void 0) {
          updated.stepGroup = stepGroup;
        }
        return updated;
      });
      setFields(newFields);
      notifyChange(newFields);
    },
    [fields, notifyChange]
  );
  const handleEditField = React.useCallback((id) => {
    setEditDialogFieldId(id);
  }, []);
  const handleDeleteField = React.useCallback(
    (id) => {
      const newFields = fields.filter((f) => f.id !== id);
      setFields(newFields);
      notifyChange(newFields);
    },
    [fields, notifyChange]
  );
  const handleConfigureNested = React.useCallback((id) => {
    setNestedEditorFieldId(id);
  }, []);
  const handleSaveNestedFields = React.useCallback(
    (fieldId, nestedFields) => {
      const newFields = fields.map((f) => {
        if (f.id !== fieldId) return f;
        if (f.type === "object") {
          return { ...f, children: nestedFields };
        } else if (f.type === "array") {
          return { ...f, itemTemplate: nestedFields };
        }
        return f;
      });
      setFields(newFields);
      notifyChange(newFields);
    },
    [fields, notifyChange]
  );
  const handleAddStep = React.useCallback(() => {
    const newStep = schemaUtils.createStep(steps.length);
    const newSteps = [...steps, newStep];
    if (steps.length === 1) {
      const updatedFields = fields.map((f) => ({ ...f, stepGroup: 0 }));
      setFields(updatedFields);
      setSteps(newSteps);
      notifyChange(updatedFields, newSteps);
    } else if (steps.length === 0) {
      const firstStep = schemaUtils.createStep(0);
      const secondStep = schemaUtils.createStep(1);
      const bothSteps = [firstStep, secondStep];
      const updatedFields = fields.map((f) => ({ ...f, stepGroup: 0 }));
      setFields(updatedFields);
      setSteps(bothSteps);
      notifyChange(updatedFields, bothSteps);
    } else {
      setSteps(newSteps);
      notifyChange(fields, newSteps);
    }
  }, [steps, fields, notifyChange]);
  const handleDeleteStep = React.useCallback(
    (index) => {
      const fieldsWithoutDeleted = fields.filter((f) => f.stepGroup !== index);
      if (steps.length <= 2) {
        const updatedFields = fieldsWithoutDeleted.map((f) => {
          const { stepGroup: _, ...rest } = f;
          return rest;
        });
        setFields(updatedFields);
        setSteps([]);
        setActiveStepIndex(0);
        notifyChange(updatedFields, []);
      } else {
        const newSteps = steps.filter((_, i) => i !== index);
        const updatedFields = fieldsWithoutDeleted.map((f) => {
          if (f.stepGroup !== void 0 && f.stepGroup > index) {
            return { ...f, stepGroup: f.stepGroup - 1 };
          }
          return f;
        });
        setFields(updatedFields);
        setSteps(newSteps);
        if (activeStepIndex >= newSteps.length) {
          setActiveStepIndex(newSteps.length - 1);
        }
        notifyChange(updatedFields, newSteps);
      }
    },
    [steps, fields, activeStepIndex, notifyChange]
  );
  const handleRenameStep = React.useCallback(
    (index, newTitle) => {
      const newSteps = steps.map(
        (step, i) => i === index ? { ...step, title: newTitle } : step
      );
      setSteps(newSteps);
      notifyChange(fields, newSteps);
    },
    [steps, fields, notifyChange]
  );
  const editDialogField = fields.find((f) => f.id === editDialogFieldId) || null;
  const editDialogComponent = editDialogField ? index.getComponentByType(editDialogField.type, components) || null : null;
  const nestedEditorField = fields.find((f) => f.id === nestedEditorFieldId) || null;
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: utils.cn("flex flex-col lg:h-full", className), children: [
    /* @__PURE__ */ jsxRuntime.jsxs(
      core_esm.DndContext,
      {
        id: dndContextId,
        sensors,
        collisionDetection: core_esm.closestCenter,
        onDragStart: handleDragStart,
        onDragEnd: handleDragEnd,
        children: [
          /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 flex flex-col lg:flex-row lg:overflow-hidden", children: [
            /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full lg:w-64 p-4 border-b lg:border-b-0 lg:border-r lg:overflow-auto shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(palette.Palette, { components }) }),
            /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 p-4 lg:overflow-auto min-h-[300px]", children: /* @__PURE__ */ jsxRuntime.jsx(
              canvas.Canvas,
              {
                fields,
                components,
                onEditField: handleEditField,
                onDeleteField: handleDeleteField,
                onConfigureNested: handleConfigureNested,
                isDraggingFromPalette: activeDragData?.type === "palette",
                steps,
                activeStepIndex,
                onActiveStepChange: setActiveStepIndex,
                onAddStep: handleAddStep,
                onDeleteStep: handleDeleteStep,
                onRenameStep: handleRenameStep
              }
            ) }),
            /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1 lg:w-96 border-t lg:border-t-0 lg:border-l lg:overflow-auto min-h-[300px]", children: /* @__PURE__ */ jsxRuntime.jsxs(tabs.Tabs, { defaultValue: "preview", className: "h-full flex flex-col", children: [
              /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 border-b", children: /* @__PURE__ */ jsxRuntime.jsxs(tabs.TabsList, { className: "w-full", children: [
                /* @__PURE__ */ jsxRuntime.jsx(tabs.TabsTrigger, { value: "preview", className: "flex-1", children: "Preview" }),
                /* @__PURE__ */ jsxRuntime.jsx(tabs.TabsTrigger, { value: "schema", className: "flex-1", children: "JSON Schema" })
              ] }) }),
              /* @__PURE__ */ jsxRuntime.jsx(tabs.TabsContent, { value: "preview", className: "flex-1 m-0 lg:overflow-auto", children: /* @__PURE__ */ jsxRuntime.jsx(formPreview.FormPreview, { schema: currentSchema, fieldComponents, defaultValues }) }),
              /* @__PURE__ */ jsxRuntime.jsx(tabs.TabsContent, { value: "schema", className: "flex-1 m-0 p-4 lg:overflow-auto", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border bg-muted/50 p-4", children: /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "text-sm overflow-auto whitespace-pre-wrap", children: JSON.stringify(currentSchema, null, 2) }) }) })
            ] }) })
          ] }),
          /* @__PURE__ */ jsxRuntime.jsxs(core_esm.DragOverlay, { dropAnimation: null, children: [
            activeDragData?.type === "palette" && activeDragData.component && /* @__PURE__ */ jsxRuntime.jsx(palette.PaletteDragOverlay, { component: activeDragData.component }),
            activeDragData?.type === "field" && activeDragData.field && /* @__PURE__ */ jsxRuntime.jsx(
              sortableField.FieldDragOverlay,
              {
                field: activeDragData.field,
                component: activeDragData.component
              }
            )
          ] })
        ]
      }
    ),
    /* @__PURE__ */ jsxRuntime.jsx(
      editFieldDialog.EditFieldDialog,
      {
        open: editDialogFieldId !== null,
        onOpenChange: (open) => !open && setEditDialogFieldId(null),
        field: editDialogField,
        component: editDialogComponent,
        onUpdate: handleUpdateField,
        steps,
        allFieldIds: fields.map((f) => f.id)
      }
    ),
    /* @__PURE__ */ jsxRuntime.jsx(
      nestedFieldEditorDialog.NestedFieldEditorDialog,
      {
        open: nestedEditorFieldId !== null,
        onOpenChange: (open) => !open && setNestedEditorFieldId(null),
        field: nestedEditorField,
        components,
        onSave: handleSaveNestedFields
      }
    )
  ] });
}

exports.arrayFieldDefinition = index.arrayFieldDefinition;
exports.defaultComponents = index.defaultComponents;
exports.objectFieldDefinition = index.objectFieldDefinition;
exports.baseMetaSchema = validationSchemas.baseMetaSchema;
exports.baseMetaSchemaWithPlaceholder = validationSchemas.baseMetaSchemaWithPlaceholder;
exports.FormBuilder = FormBuilder;
exports.default = FormBuilder;
