"use client";
import { jsxs, jsx } from 'react/jsx-runtime';
import { useId, useMemo, useState, useCallback } from 'react';
import { createPortal } from 'react-dom';
import { useSensors, useSensor, KeyboardSensor, TouchSensor, PointerSensor, DndContext, closestCenter, DragOverlay } from '../../../../../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.mjs';
import { snapCenterToCursor } from '../../../../../node_modules/.pnpm/@dnd-kit_modifiers@9.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/modifiers/dist/modifiers.esm.mjs';
import { sortableKeyboardCoordinates, arrayMove } from '../../../../../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.mjs';
import { FolderOpen, List } from 'lucide-react';
import { Button } from '../button.mjs';
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from '../dialog.mjs';
import { Palette, PaletteDragOverlay } from './palette.mjs';
import { Canvas } from './canvas.mjs';
import { EditFieldDialog } from './edit-field-dialog.mjs';
import { FieldDragOverlay } from './sortable-field.mjs';
import { getComponentByType } from './components/index.mjs';
import { generateFieldId } from './schema-utils.mjs';

function NestedFieldEditorDialog({
  open,
  onOpenChange,
  field,
  components,
  onSave
}) {
  const dndContextId = useId();
  const initialFields = useMemo(() => {
    if (!field) return [];
    if (field.type === "object") return field.children || [];
    if (field.type === "array") return field.itemTemplate || [];
    return [];
  }, [field]);
  const [nestedFields, setNestedFields] = useState(initialFields);
  const [activeId, setActiveId] = useState(null);
  const [editDialogFieldId, setEditDialogFieldId] = useState(null);
  const [prevField, setPrevField] = useState(field);
  const [prevOpen, setPrevOpen] = useState(open);
  if (prevField !== field || open && !prevOpen) {
    setPrevField(field);
    setPrevOpen(open);
    setNestedFields(initialFields);
    setEditDialogFieldId(null);
  }
  if (prevOpen !== open) {
    setPrevOpen(open);
  }
  const sensors = useSensors(
    useSensor(PointerSensor, {
      activationConstraint: { distance: 8 }
    }),
    useSensor(TouchSensor, {
      activationConstraint: { distance: 8 }
    }),
    useSensor(KeyboardSensor, {
      coordinateGetter: sortableKeyboardCoordinates
    })
  );
  const activeDragData = useMemo(() => {
    if (!activeId) return null;
    const idStr = String(activeId);
    if (idStr.startsWith("palette-")) {
      const componentType = idStr.replace("palette-", "");
      return {
        type: "palette",
        componentType,
        component: getComponentByType(componentType, components)
      };
    }
    const nestedField = nestedFields.find((f) => f.id === idStr);
    if (nestedField) {
      return {
        type: "field",
        field: nestedField,
        component: getComponentByType(nestedField.type, components)
      };
    }
    return null;
  }, [activeId, nestedFields, 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 = getComponentByType(componentType, components);
      if (component) {
        const newField = {
          id: generateFieldId(componentType),
          type: componentType,
          props: {
            label: component.defaultProps.label || component.label,
            ...component.defaultProps
          }
        };
        let insertIndex = nestedFields.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 = nestedFields.findIndex((f) => f.id === fieldId);
          if (overIndex !== -1) {
            insertIndex = overIndex + 1;
          }
        } else if (overId !== "canvas") {
          const overIndex = nestedFields.findIndex((f) => f.id === overId);
          if (overIndex !== -1) {
            insertIndex = overIndex + 1;
          }
        }
        const newFields = [...nestedFields];
        newFields.splice(insertIndex, 0, newField);
        setNestedFields(newFields);
      }
      return;
    }
    if (activeData?.type === "field" && active.id !== over.id) {
      const oldIndex = nestedFields.findIndex((f) => f.id === active.id);
      const newIndex = nestedFields.findIndex((f) => f.id === over.id);
      if (oldIndex !== -1 && newIndex !== -1) {
        setNestedFields(arrayMove(nestedFields, oldIndex, newIndex));
      }
    }
  };
  const handleDeleteField = useCallback((id) => {
    setNestedFields((fields) => fields.filter((f) => f.id !== id));
  }, []);
  const handleEditField = useCallback((id) => {
    setEditDialogFieldId(id);
  }, []);
  const handleUpdateField = useCallback(
    (id, props, newId) => {
      if (newId && newId !== id) {
        const idExists = nestedFields.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;
        }
      }
      setNestedFields(
        (fields) => fields.map((f) => {
          if (f.id !== id) return f;
          return {
            ...f,
            id: newId || f.id,
            props: { ...f.props, ...props }
          };
        })
      );
    },
    [nestedFields]
  );
  const handleSave = useCallback(() => {
    if (!field) return;
    onSave(field.id, nestedFields);
    onOpenChange(false);
  }, [field, nestedFields, onSave, onOpenChange]);
  if (!field) return null;
  const isObjectField = field.type === "object";
  const Icon = isObjectField ? FolderOpen : List;
  const fieldTypeLabel = isObjectField ? "Field Group" : "Repeating Group";
  const nestedLabel = isObjectField ? "nested fields" : "item fields";
  const editDialogField = nestedFields.find((f) => f.id === editDialogFieldId) || null;
  const editDialogComponent = editDialogField ? getComponentByType(editDialogField.type, components) || null : null;
  return /* @__PURE__ */ jsxs(Dialog, { open, onOpenChange, children: [
    /* @__PURE__ */ jsxs(DialogContent, { className: "max-w-6xl! max-h-[90vh] overflow-hidden flex flex-col", children: [
      /* @__PURE__ */ jsxs(DialogHeader, { children: [
        /* @__PURE__ */ jsxs(DialogTitle, { className: "flex items-center gap-2", children: [
          /* @__PURE__ */ jsx(Icon, { className: "h-5 w-5 text-muted-foreground" }),
          "Configure ",
          fieldTypeLabel,
          ": ",
          field.props.label
        ] }),
        /* @__PURE__ */ jsxs(DialogDescription, { children: [
          "Add and arrange the ",
          nestedLabel,
          " for this ",
          fieldTypeLabel.toLowerCase(),
          ".",
          isObjectField ? " These fields will be grouped together." : " Each item in the array will have these fields."
        ] })
      ] }),
      /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxs(
        DndContext,
        {
          id: dndContextId,
          sensors,
          collisionDetection: closestCenter,
          onDragStart: handleDragStart,
          onDragEnd: handleDragEnd,
          children: [
            /* @__PURE__ */ jsxs("div", { className: "flex h-[50vh] gap-4", children: [
              /* @__PURE__ */ jsx("div", { className: "w-48 overflow-auto shrink-0 border-r pr-4", children: /* @__PURE__ */ jsx(Palette, { components }) }),
              /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-auto", children: /* @__PURE__ */ jsx(
                Canvas,
                {
                  fields: nestedFields,
                  components,
                  onEditField: handleEditField,
                  onDeleteField: handleDeleteField,
                  isDraggingFromPalette: activeDragData?.type === "palette",
                  steps: [],
                  activeStepIndex: 0,
                  onActiveStepChange: () => {
                  },
                  onAddStep: () => {
                  },
                  onDeleteStep: () => {
                  },
                  onRenameStep: () => {
                  },
                  hideStepControls: true
                }
              ) })
            ] }),
            typeof document !== "undefined" && createPortal(
              /* @__PURE__ */ jsxs(DragOverlay, { dropAnimation: null, modifiers: [snapCenterToCursor], children: [
                activeDragData?.type === "palette" && activeDragData.component && /* @__PURE__ */ jsx(PaletteDragOverlay, { component: activeDragData.component }),
                activeDragData?.type === "field" && activeDragData.field && /* @__PURE__ */ jsx(
                  FieldDragOverlay,
                  {
                    field: activeDragData.field,
                    component: activeDragData.component
                  }
                )
              ] }),
              document.body
            )
          ]
        }
      ) }),
      /* @__PURE__ */ jsxs(DialogFooter, { className: "border-t pt-4", children: [
        /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground mr-auto", children: [
          nestedFields.length,
          " ",
          nestedFields.length === 1 ? "field" : "fields"
        ] }),
        /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: () => onOpenChange(false), children: "Cancel" }),
        /* @__PURE__ */ jsx(Button, { onClick: handleSave, children: "Save Fields" })
      ] })
    ] }),
    /* @__PURE__ */ jsx(
      EditFieldDialog,
      {
        open: editDialogFieldId !== null,
        onOpenChange: (open2) => !open2 && setEditDialogFieldId(null),
        field: editDialogField,
        component: editDialogComponent,
        onUpdate: handleUpdateField,
        steps: [],
        allFieldIds: nestedFields.map((f) => f.id)
      }
    )
  ] });
}

export { NestedFieldEditorDialog };
