'use strict';

const jsxRuntime = require('react/jsx-runtime');
const React = require('react');
const index = require('../../../../../../../_virtual/index.cjs');
const elementSelector = require('../components/element-selector.cjs');
const dropZone = require('../dnd/drop-zone.cjs');
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');
require('../../../../lib/ui-builder/context/dnd-context-colission-utils.cjs');
const dndContexts = require('../../../../lib/ui-builder/context/dnd-contexts.cjs');
require('react-dom');
const layerStore = require('../../../../lib/ui-builder/store/layer-store.cjs');
const layerUtils = require('../../../../lib/ui-builder/store/layer-utils.cjs');
const editorStore = require('../../../../lib/ui-builder/store/editor-store.cjs');
const reactErrorBoundary = require('react-error-boundary');
const errorFallback = require('../components/error-fallback.cjs');
const editorUtils = require('../../../../lib/ui-builder/store/editor-utils.cjs');
const devProfiler = require('../components/dev-profiler.cjs');
const types = require('../../types.cjs');
const variableResolver = require('../../../../lib/ui-builder/utils/variable-resolver.cjs');

const POSITION_CLASSES = ["static", "fixed", "absolute", "relative", "sticky"];
function hasPositionClass(className) {
  const classes = className.split(/\s+/);
  return POSITION_CLASSES.some((posClass) => classes.includes(posClass));
}
function isLayerBeingDraggedOrDescendant(layerId, activeLayerId, pages) {
  if (!activeLayerId) return false;
  if (layerId === activeLayerId) return true;
  if (!pages || !Array.isArray(pages) || pages.length === 0) return false;
  const draggedLayer = layerUtils.findLayerRecursive(pages, activeLayerId);
  if (!draggedLayer) return false;
  if (layerUtils.hasLayerChildren(draggedLayer)) {
    const foundInDragged = layerUtils.findLayerRecursive([draggedLayer], layerId);
    return !!foundInDragged;
  }
  return false;
}
const RenderLayer = React.memo(
  ({ layer, componentRegistry, editorConfig, variables, variableValues, functionRegistry }) => {
    const storeVariables = layerStore.useLayerStore((state) => state.variables);
    const pages = layerStore.useLayerStore((state) => state.pages);
    const isLayerAPage = layerStore.useLayerStore((state) => state.isLayerAPage(layer.id));
    const registry = editorStore.useEditorStore((state) => state.registry);
    const storeFunctionRegistry = editorStore.useEditorStore((state) => state.functionRegistry);
    const dndContext = dndContexts.useDndContext();
    const effectiveFunctionRegistry = functionRegistry ?? storeFunctionRegistry;
    const effectiveVariables = variables || storeVariables;
    const componentDefinition = componentRegistry[layer.type];
    const prevLayer = React.useRef(layer);
    const infoData = React.useMemo(() => ({
      layerType: layer.type,
      layerId: layer.id,
      layerName: layer.name,
      availableComponents: Object.keys(componentRegistry),
      layer
    }), [layer, componentRegistry]);
    const resolvedProps = React.useMemo(
      () => variableResolver.resolveVariableReferences(layer.props, effectiveVariables, variableValues, effectiveFunctionRegistry),
      [layer.props, effectiveVariables, variableValues, effectiveFunctionRegistry]
    );
    const childEditorConfig = React.useMemo(() => {
      return editorConfig ? { ...editorConfig, zIndex: editorConfig.zIndex + 1, parentUpdated: editorConfig.parentUpdated || !index(prevLayer.current, layer) } : void 0;
    }, [editorConfig, layer]);
    const isBeingDragged = React.useMemo(
      () => isLayerBeingDraggedOrDescendant(layer.id, dndContext.activeLayerId, pages),
      [layer.id, dndContext.activeLayerId, pages]
    );
    const isRootDraggedLayer = layer.id === dndContext.activeLayerId;
    const canAcceptChildren = React.useMemo(() => layerUtils.canLayerAcceptChildren(layer, registry), [layer, registry]);
    const showDropZones = React.useMemo(
      () => editorConfig && dndContext.isDragging && canAcceptChildren && !isBeingDragged,
      [editorConfig, dndContext.isDragging, canAcceptChildren, isBeingDragged]
    );
    const childProps = React.useMemo(() => {
      const props = {};
      for (const [key, value] of Object.entries(resolvedProps)) {
        if (!key.startsWith("__function_")) {
          props[key] = value;
        }
      }
      if (showDropZones && layerUtils.hasLayerChildren(layer)) {
        const existingClassName = props.className || "";
        if (!hasPositionClass(existingClassName)) {
          props.className = existingClassName ? `${existingClassName} relative` : "relative";
        }
      }
      return props;
    }, [resolvedProps, showDropZones, layer]);
    if (!componentDefinition) {
      console.error(
        `[UIBuilder] Component definition not found in registry:`,
        infoData
      );
      return null;
    }
    let Component = componentDefinition.component;
    let isPrimitive = false;
    if (editorUtils.isPrimitiveComponent(componentDefinition)) {
      Component = layer.type;
      isPrimitive = true;
    }
    if (!Component) return null;
    if (layerUtils.hasLayerChildren(layer) && layer.children.length > 0) {
      const childElements = layer.children.map((child, index) => {
        const childElement = /* @__PURE__ */ jsxRuntime.jsx(
          RenderLayer,
          {
            componentRegistry,
            layer: child,
            variables,
            variableValues,
            editorConfig: childEditorConfig,
            functionRegistry
          },
          child.id
        );
        if (showDropZones) {
          return /* @__PURE__ */ jsxRuntime.jsxs(React.Fragment, { children: [
            /* @__PURE__ */ jsxRuntime.jsx(
              dropZone.DropPlaceholder,
              {
                parentId: layer.id,
                position: index,
                isActive: true
              }
            ),
            childElement
          ] }, child.id);
        }
        return childElement;
      });
      if (showDropZones) {
        childElements.push(
          /* @__PURE__ */ jsxRuntime.jsx(
            dropZone.DropPlaceholder,
            {
              parentId: layer.id,
              position: layer.children.length,
              isActive: true
            },
            `drop-${layer.id}-${layer.children.length}`
          )
        );
      }
      childProps.children = childElements;
    } else if (types.isVariableReference(layer.children)) {
      const resolvedChildren = variableResolver.resolveChildrenVariableReference(
        layer.children,
        effectiveVariables,
        variableValues
      );
      childProps.children = resolvedChildren;
    } else if (typeof layer.children === "string") {
      childProps.children = layer.children;
    } else if (showDropZones && layerUtils.hasLayerChildren(layer)) {
      childProps.children = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-[2rem] w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
        dropZone.DropPlaceholder,
        {
          parentId: layer.id,
          position: 0,
          isActive: true
        }
      ) });
    }
    const WrappedComponent = isPrimitive ? /* @__PURE__ */ jsxRuntime.jsx(Component, { id: layer.id, "data-testid": layer.id, "data-layer-id": layer.id, ...childProps }) : /* @__PURE__ */ jsxRuntime.jsx(ErrorSuspenseWrapper, { id: layer.id, children: /* @__PURE__ */ jsxRuntime.jsx(Component, { "data-testid": layer.id, "data-layer-id": layer.id, ...childProps }) }, layer.id);
    const DragFeedbackWrapper = isRootDraggedLayer ? /* @__PURE__ */ jsxRuntime.jsxs(
      "div",
      {
        className: "relative opacity-50 pointer-events-none",
        "data-dragging": "true",
        children: [
          /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-primary/20 rounded pointer-events-none z-10" }),
          WrappedComponent
        ]
      }
    ) : WrappedComponent;
    if (!editorConfig) {
      return DragFeedbackWrapper;
    } else {
      const {
        zIndex,
        totalLayers,
        selectedLayer,
        onSelectElement
      } = editorConfig;
      return /* @__PURE__ */ jsxRuntime.jsx(
        devProfiler.DevProfiler,
        {
          id: layer.type,
          threshold: 20,
          children: /* @__PURE__ */ jsxRuntime.jsx(
            elementSelector.ElementSelector,
            {
              layer,
              zIndex,
              isSelected: layer.id === selectedLayer?.id,
              onSelectElement,
              isPageLayer: isLayerAPage,
              totalLayers,
              children: DragFeedbackWrapper
            },
            layer.id
          )
        }
      );
    }
  },
  (prevProps, nextProps) => {
    if (nextProps.editorConfig?.parentUpdated) {
      return false;
    }
    const editorConfigEqual = index(
      prevProps.editorConfig?.selectedLayer?.id,
      nextProps.editorConfig?.selectedLayer?.id
    );
    const layerEqual = index(prevProps.layer, nextProps.layer);
    const variablesEqual = index(prevProps.variables, nextProps.variables);
    const variableValuesEqual = index(prevProps.variableValues, nextProps.variableValues);
    const functionRegistryEqual = prevProps.functionRegistry === nextProps.functionRegistry;
    return editorConfigEqual && layerEqual && variablesEqual && variableValuesEqual && functionRegistryEqual;
  }
);
RenderLayer.displayName = "RenderLayer";
const ErrorSuspenseWrapper = ({ children }) => {
  const loadingFallback = React.useMemo(() => /* @__PURE__ */ jsxRuntime.jsx(LoadingComponent, {}), []);
  return /* @__PURE__ */ jsxRuntime.jsx(reactErrorBoundary.ErrorBoundary, { fallbackRender: errorFallback.ErrorFallback, children: /* @__PURE__ */ jsxRuntime.jsx(React.Suspense, { fallback: loadingFallback, children }) });
};
const LoadingComponent = () => /* @__PURE__ */ jsxRuntime.jsx("div", { children: "Loading..." });

exports.RenderLayer = RenderLayer;
exports.hasPositionClass = hasPositionClass;
