'use strict';

const jsxRuntime = require('react/jsx-runtime');
const React = require('react');
const command = require('../../../command.cjs');
const popover = require('../../../popover.cjs');
const tabs = require('../../../tabs.cjs');
const layerStore = require('../../../../lib/ui-builder/store/layer-store.cjs');
const editorStore = require('../../../../lib/ui-builder/store/editor-store.cjs');
const utils = require('../../../../lib/utils.cjs');
const layerRenderer = require('../../layer-renderer.cjs');
const layerUtils = require('../../../../lib/ui-builder/store/layer-utils.cjs');
const draggableNewComponent = require('../dnd/draggable-new-component.cjs');

function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }

const React__default = /*#__PURE__*/_interopDefaultCompat(React);

const fallback = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full bg-muted rounded border animate-pulse" });
const previewLayerCache = /* @__PURE__ */ new Map();
function isValidChildOfParent(componentRegistry, componentType, parentType) {
  const def = componentRegistry[componentType];
  if (!def?.childOf) {
    return true;
  }
  if (!parentType) {
    return false;
  }
  return def.childOf.includes(parentType);
}
function isChildOnlyComponent(componentRegistry, componentType) {
  const def = componentRegistry[componentType];
  return Boolean(def?.childOf);
}
function AddComponentsPopover({
  className,
  children,
  addPosition,
  parentLayerId,
  onOpenChange,
  enableDragToCanvas = false,
  onChange
}) {
  const [open, setOpen] = React__default.useState(false);
  const [activeView, setActiveView] = React__default.useState("components");
  const componentRegistry = editorStore.useEditorStore((state) => state.registry);
  const blocks = editorStore.useEditorStore((state) => state.blocks);
  const findLayerById = layerStore.useLayerStore((state) => state.findLayerById);
  const parentLayerType = React.useMemo(() => {
    const parentLayer = findLayerById(parentLayerId);
    return parentLayer?.type;
  }, [findLayerById, parentLayerId]);
  const groupedOptions = React.useMemo(() => {
    const componentOptions = Object.keys(componentRegistry).filter((name) => isValidChildOfParent(componentRegistry, name, parentLayerType)).map((name) => ({
      value: name,
      label: name,
      type: "component",
      from: componentRegistry[name]?.from
    }));
    return componentOptions.reduce(
      (acc, option) => {
        const fromRoot = option.from?.split("/").slice(0, -1).join("/");
        const group = fromRoot || "other";
        if (!acc[group]) {
          acc[group] = [];
        }
        acc[group]?.push(option);
        return acc;
      },
      {}
    );
  }, [componentRegistry, parentLayerType]);
  const categories = React.useMemo(() => {
    return Object.keys(groupedOptions);
  }, [groupedOptions]);
  const groupedBlocks = React.useMemo(() => {
    if (!blocks) return {};
    return Object.values(blocks).reduce(
      (acc, block) => {
        if (!acc[block.category]) {
          acc[block.category] = [];
        }
        acc[block.category]?.push(block);
        return acc;
      },
      {}
    );
  }, [blocks]);
  const blockCategories = React.useMemo(() => {
    return Object.keys(groupedBlocks);
  }, [groupedBlocks]);
  const hasBlocks = blocks && Object.keys(blocks).length > 0;
  const addComponentLayer = layerStore.useLayerStore((state) => state.addComponentLayer);
  const addLayerDirect = layerStore.useLayerStore((state) => state.addLayerDirect);
  const handleSelect = React__default.useCallback(
    (currentValue) => {
      if (onChange) {
        onChange({ layerType: currentValue, parentLayerId, addPosition });
      } else if (componentRegistry[currentValue]) {
        addComponentLayer(
          currentValue,
          parentLayerId,
          addPosition
        );
      }
      setOpen(false);
      onOpenChange?.(false);
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [
      addComponentLayer,
      parentLayerId,
      addPosition,
      setOpen,
      onOpenChange,
      onChange
    ]
  );
  const handleBlockSelect = React__default.useCallback(
    (block) => {
      const clonedTemplate = cloneLayerWithNewIds(block.template);
      addLayerDirect(clonedTemplate, parentLayerId, addPosition);
      setOpen(false);
      onOpenChange?.(false);
    },
    [addLayerDirect, parentLayerId, addPosition, onOpenChange]
  );
  const handleOpenChange = React.useCallback(
    (open2) => {
      setOpen(open2);
      onOpenChange?.(open2);
    },
    [onOpenChange]
  );
  const handleDragStart = React.useCallback(() => {
    setOpen(false);
    onOpenChange?.(false);
  }, [onOpenChange]);
  const defaultTab = categories[0] || "";
  const defaultBlockCategory = blockCategories[0] || "";
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: utils.cn("relative flex justify-center", className), children: /* @__PURE__ */ jsxRuntime.jsxs(popover.Popover, { open, onOpenChange: handleOpenChange, children: [
    /* @__PURE__ */ jsxRuntime.jsx(popover.PopoverTrigger, { asChild: true, children }),
    /* @__PURE__ */ jsxRuntime.jsxs(popover.PopoverContent, { className: "w-[320px] p-0", align: "start", children: [
      hasBlocks && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex border-b", children: [
        /* @__PURE__ */ jsxRuntime.jsx(
          "button",
          {
            className: utils.cn(
              "flex-1 px-4 py-2 text-sm font-medium transition-colors",
              activeView === "components" ? "bg-background border-b-2 border-primary" : "bg-muted/50 text-muted-foreground hover:text-foreground"
            ),
            onClick: () => setActiveView("components"),
            children: "Components"
          }
        ),
        /* @__PURE__ */ jsxRuntime.jsx(
          "button",
          {
            className: utils.cn(
              "flex-1 px-4 py-2 text-sm font-medium transition-colors",
              activeView === "blocks" ? "bg-background border-b-2 border-primary" : "bg-muted/50 text-muted-foreground hover:text-foreground"
            ),
            onClick: () => setActiveView("blocks"),
            children: "Blocks"
          }
        )
      ] }),
      activeView === "components" && categories.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(tabs.Tabs, { defaultValue: defaultTab, className: "w-full", children: [
        /* @__PURE__ */ jsxRuntime.jsx(tabs.TabsList, { className: utils.cn(categories.length > 1 ? "h-14 w-full rounded-none border-b flex flex-row overflow-x-scroll justify-start" : "hidden"), children: categories.map((category) => /* @__PURE__ */ jsxRuntime.jsxs(tabs.TabsTrigger, { value: category, className: "flex flex-col justify-start items-start overflow-hidden px-2 py-1 min-w-24 min-h-11 shrink-0", children: [
          /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm", children: formatCategoryName(category) }),
          /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full min-h-[12px] text-[8px] leading-[9px] text-left text-muted-foreground text-wrap", children: category })
        ] }, category)) }),
        categories.map((category) => /* @__PURE__ */ jsxRuntime.jsx(tabs.TabsContent, { value: category, className: "m-0", children: /* @__PURE__ */ jsxRuntime.jsxs(command.Command, { className: "border-0", children: [
          /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center px-3 w-full [&>div:first-child]:w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
            command.CommandInput,
            {
              placeholder: "Find components",
              className: "border-0 focus:ring-0 w-full"
            }
          ) }),
          /* @__PURE__ */ jsxRuntime.jsxs(command.CommandList, { className: "max-h-[250px]", children: [
            /* @__PURE__ */ jsxRuntime.jsx(command.CommandEmpty, { children: "No components found" }),
            /* @__PURE__ */ jsxRuntime.jsx(command.CommandGroup, { children: groupedOptions[category]?.map((component) => /* @__PURE__ */ jsxRuntime.jsx(
              GroupedComponentItem,
              {
                component,
                onClick: handleSelect,
                onDragStart: handleDragStart,
                enableDrag: enableDragToCanvas
              },
              component.value
            )) })
          ] })
        ] }) }, category))
      ] }) : activeView === "components" ? /* @__PURE__ */ jsxRuntime.jsxs(command.Command, { children: [
        /* @__PURE__ */ jsxRuntime.jsx(command.CommandInput, { placeholder: "Add component" }),
        /* @__PURE__ */ jsxRuntime.jsx(command.CommandList, { children: /* @__PURE__ */ jsxRuntime.jsx(command.CommandEmpty, { children: "No components found" }) })
      ] }) : null,
      activeView === "blocks" && hasBlocks && /* @__PURE__ */ jsxRuntime.jsxs(tabs.Tabs, { defaultValue: defaultBlockCategory, className: "w-full", children: [
        /* @__PURE__ */ jsxRuntime.jsx(tabs.TabsList, { className: "h-14 w-full rounded-none border-b flex flex-row overflow-x-scroll justify-start", children: blockCategories.map((category) => /* @__PURE__ */ jsxRuntime.jsxs(tabs.TabsTrigger, { value: category, className: "flex flex-col justify-start items-start overflow-hidden px-2 py-1 min-w-24 min-h-11 shrink-0", children: [
          /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm", children: formatCategoryName(category) }),
          /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full min-h-[12px] text-[8px] leading-[9px] text-left text-muted-foreground", children: [
            groupedBlocks[category]?.length,
            " blocks"
          ] })
        ] }, category)) }),
        blockCategories.map((category) => /* @__PURE__ */ jsxRuntime.jsx(tabs.TabsContent, { value: category, className: "m-0", children: /* @__PURE__ */ jsxRuntime.jsxs(command.Command, { className: "border-0", children: [
          /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center px-3 w-full [&>div:first-child]:w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
            command.CommandInput,
            {
              placeholder: "Find blocks",
              className: "border-0 focus:ring-0 w-full"
            }
          ) }),
          /* @__PURE__ */ jsxRuntime.jsxs(command.CommandList, { className: "max-h-[250px]", children: [
            /* @__PURE__ */ jsxRuntime.jsx(command.CommandEmpty, { children: "No blocks found" }),
            /* @__PURE__ */ jsxRuntime.jsx(command.CommandGroup, { children: groupedBlocks[category]?.map((block) => /* @__PURE__ */ jsxRuntime.jsx(
              BlockItem,
              {
                block,
                onClick: handleBlockSelect
              },
              block.name
            )) })
          ] })
        ] }) }, category))
      ] })
    ] })
  ] }) });
}
function cloneLayerWithNewIds(layer) {
  const newId = generateUniqueId();
  let newChildren;
  if (Array.isArray(layer.children)) {
    newChildren = layer.children.map((child) => cloneLayerWithNewIds(child));
  } else if (typeof layer.children === "string") {
    newChildren = layer.children;
  } else if (layer.children && typeof layer.children === "object" && "__variableRef" in layer.children) {
    newChildren = layer.children;
  } else {
    newChildren = layer.children;
  }
  return {
    ...layer,
    id: newId,
    children: newChildren
  };
}
function generateUniqueId() {
  return Math.random().toString(36).substring(2, 9);
}
const BlockItem = React.memo(({
  block,
  onClick
}) => {
  const handleSelect = React.useCallback(() => {
    onClick(block);
  }, [onClick, block]);
  return /* @__PURE__ */ jsxRuntime.jsxs(
    command.CommandItem,
    {
      onSelect: handleSelect,
      className: "cursor-pointer flex flex-col items-start gap-1 py-3",
      children: [
        /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium", children: formatBlockName(block.name) }),
        block.description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground line-clamp-2", children: block.description })
      ]
    }
  );
});
BlockItem.displayName = "BlockItem";
function formatBlockName(name) {
  return name.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
}
const GroupedComponentItem = React.memo(({
  component,
  onClick,
  onDragStart,
  enableDrag = false
}) => {
  const handleSelect = React.useCallback(() => {
    onClick(component.value);
  }, [onClick, component.value]);
  const componentRegistry = editorStore.useEditorStore((state) => state.registry);
  const content = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
    /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 w-10 h-6 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
      LazyComponentPreview,
      {
        componentType: component.value,
        componentRegistry
      }
    ) }),
    /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center flex-1 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: component.label }) })
  ] });
  return /* @__PURE__ */ jsxRuntime.jsx(
    command.CommandItem,
    {
      onSelect: handleSelect,
      className: "cursor-pointer flex items-center gap-2 py-2",
      children: enableDrag ? /* @__PURE__ */ jsxRuntime.jsx(
        draggableNewComponent.DraggableNewComponent,
        {
          componentType: component.value,
          onDragStart,
          className: "flex-1",
          children: content
        }
      ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: content })
    },
    component.value
  );
});
GroupedComponentItem.displayName = "GroupedComponentItem";
const LazyComponentPreview = React.memo(({
  componentType,
  componentRegistry
}) => {
  const [shouldLoad, setShouldLoad] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    const element = ref.current;
    if (!element) return;
    let timeoutId = null;
    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry?.isIntersecting) {
          timeoutId = setTimeout(() => setShouldLoad(true), 50);
        }
      },
      { threshold: 0.1 }
    );
    observer.observe(element);
    return () => {
      observer.disconnect();
      if (timeoutId !== null) {
        clearTimeout(timeoutId);
      }
    };
  }, []);
  return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: "w-full h-full", children: shouldLoad ? /* @__PURE__ */ jsxRuntime.jsx(React.Suspense, { fallback, children: /* @__PURE__ */ jsxRuntime.jsx(
    ComponentPreview,
    {
      componentType,
      componentRegistry
    }
  ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full bg-muted rounded border" }) });
});
LazyComponentPreview.displayName = "LazyComponentPreview";
const ChildOnlyPlaceholder = React.memo(({ componentType }) => {
  const initials = componentType.replace(/([A-Z])/g, " $1").trim().split(" ").map((word) => word[0]).slice(0, 2).join("");
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full bg-muted/50 rounded border border-dashed flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[8px] font-medium text-muted-foreground", children: initials }) });
});
ChildOnlyPlaceholder.displayName = "ChildOnlyPlaceholder";
const ComponentPreview = React.memo(({
  componentType,
  componentRegistry
}) => {
  const isChildOnly = isChildOnlyComponent(componentRegistry, componentType);
  const previewLayer = React.useMemo(() => {
    if (isChildOnly) {
      return null;
    }
    const cacheKey = `${componentType}-${JSON.stringify(componentRegistry[componentType]?.schema)}`;
    if (previewLayerCache.has(cacheKey)) {
      return previewLayerCache.get(cacheKey);
    }
    try {
      const layer = layerUtils.createComponentLayer(componentType, componentRegistry, {
        id: `preview-${componentType}`
        // Use stable ID for previews
      });
      previewLayerCache.set(cacheKey, layer);
      return layer;
    } catch (error) {
      console.warn(`Failed to create preview for component ${componentType}:`, error);
      return null;
    }
  }, [componentType, componentRegistry, isChildOnly]);
  if (isChildOnly) {
    return /* @__PURE__ */ jsxRuntime.jsx(ChildOnlyPlaceholder, { componentType });
  }
  if (!previewLayer) {
    return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full bg-muted rounded border" });
  }
  const style = { width: "200%", height: "200%" };
  return /* @__PURE__ */ jsxRuntime.jsx(
    "div",
    {
      className: "w-full h-full bg-background rounded border overflow-hidden transform scale-50 origin-top-left pointer-events-none",
      style,
      inert: true,
      children: /* @__PURE__ */ jsxRuntime.jsx(
        layerRenderer,
        {
          page: previewLayer,
          componentRegistry,
          className: "pointer-events-none"
        }
      )
    }
  );
});
ComponentPreview.displayName = "ComponentPreview";
function formatCategoryName(name) {
  const words = name.split("/");
  const lastWord = words[words.length - 1];
  return lastWord?.replace(/-/g, " ").replace(/\b\w/g, (char) => char.toUpperCase()) ?? "";
}

exports.AddComponentsPopover = AddComponentsPopover;
