"use client";
'use strict';

const jsxRuntime = require('react/jsx-runtime');
const React = require('react');
const index_esm = require('../../../../../../../node_modules/.pnpm/react-zoom-pan-pinch@3.7.0_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/react-zoom-pan-pinch/dist/index.esm.cjs');
const layerMenu = require('./layer-menu.cjs');
const dragHandle = require('../dnd/drag-handle.cjs');
const resizableWrapper = require('../canvas/resizable-wrapper.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');
require('../../../../lib/ui-builder/store/layer-store.cjs');
require('zod');
require('../../../../lib/ui-builder/store/editor-store.cjs');
const utils = require('../../../../lib/utils.cjs');
const floatingUi_react = require('../../../../../../../node_modules/.pnpm/@floating-ui_react@0.27.16_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/@floating-ui/react/dist/floating-ui.react.cjs');
const getScrollParent = require('../../../../lib/ui-builder/utils/get-scroll-parent.cjs');
const autoFrame = require('../canvas/auto-frame.cjs');
const floatingUi_reactDom = require('../../../../../../../node_modules/.pnpm/@floating-ui_react-dom@2.1.6_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/@floating-ui/react-dom/dist/floating-ui.react-dom.cjs');
const floatingUi_dom = require('../../../../../../../node_modules/.pnpm/@floating-ui_dom@1.7.4/node_modules/@floating-ui/dom/dist/floating-ui.dom.cjs');

const style = {
  display: "contents"
};
const ElementSelector = ({
  layer,
  isSelected,
  zIndex,
  onSelectElement,
  onDuplicateLayer,
  onDeleteLayer,
  children,
  isPageLayer = false
}) => {
  const [boundingRect, setBoundingRect] = React.useState(null);
  const dndContext = dndContexts.useDndContext();
  const { refs, floatingStyles } = floatingUi_react.useFloating({
    placement: "top-start",
    whileElementsMounted: floatingUi_dom.autoUpdate,
    middleware: [
      floatingUi_reactDom.offset(-2),
      // Negative offset to overlap like the sticky label
      floatingUi_reactDom.shift({
        crossAxis: true,
        // Allow sliding along the cross axis
        limiter: floatingUi_reactDom.limitShift()
      })
    ]
  });
  const isBeingDragged = dndContext.activeLayerId === layer.id;
  const handleClick = React.useCallback(
    (e) => {
      e.stopPropagation();
      e.preventDefault();
      onSelectElement(layer.id);
    },
    [layer.id, onSelectElement]
  );
  const handlePointerEvent = React.useCallback((e) => {
    e.stopPropagation();
    e.preventDefault();
  }, []);
  const overlayStyle = React.useMemo(() => {
    if (!boundingRect) return { display: "none" };
    return {
      position: "fixed",
      top: boundingRect.top,
      left: boundingRect.left,
      width: boundingRect.width,
      height: boundingRect.height,
      zIndex,
      boxSizing: "border-box",
      pointerEvents: "auto"
      // Ensure overlay captures all pointer events
    };
  }, [boundingRect, zIndex]);
  const handleBoundingRectChange = React.useCallback(
    (rect) => {
      setBoundingRect(rect);
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [layer.id]
  );
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
    /* @__PURE__ */ jsxRuntime.jsx(MeasureRange, { debug: false, onChange: handleBoundingRectChange, children }),
    boundingRect && /* @__PURE__ */ jsxRuntime.jsx(
      "div",
      {
        onClick: handleClick,
        onMouseDown: handlePointerEvent,
        onMouseUp: handlePointerEvent,
        onDoubleClick: handlePointerEvent,
        onContextMenu: handlePointerEvent,
        ref: refs.setReference,
        className: utils.cn(
          "fixed box-border hover:border-blue-300 hover:border-2 hover:bg-blue-300/20 hover:shadow-md hover:shadow-blue-500/20 cursor-default",
          isBeingDragged ? "border-2 border-green-500 border-dashed shadow-lg opacity-70 bg-orange-50/20" : isSelected ? "border-2 border-blue-500 hover:border-blue-500 hover:bg-transparent  hover:shadow-none" : ""
        ),
        style: overlayStyle
      }
    ),
    isSelected && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "z-[9999]", ref: refs.setFloating, style: floatingStyles, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center bg-blue-500", children: [
      !isPageLayer && isSelected && /* @__PURE__ */ jsxRuntime.jsx(dragHandle.DragHandle, { layerId: layer.id, layerType: layer.type }),
      !isBeingDragged && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
        /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-white  px-[1px] whitespace-nowrap cursor-default", children: layer.name?.toLowerCase().startsWith(layer.type.toLowerCase()) ? layer.type.replaceAll("_", "") : `${layer.name} (${layer.type.replaceAll("_", "")})` }),
        /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-px h-4 bg-white/20 ml-1" }),
        /* @__PURE__ */ jsxRuntime.jsx(
          layerMenu.LayerMenu,
          {
            layerId: layer.id,
            handleDuplicateComponent: onDuplicateLayer,
            handleDeleteComponent: onDeleteLayer
          }
        )
      ] })
    ] }) })
  ] });
};
const MIN_SIZE = 5;
const MIN_CHANGE_THRESHOLD = 0;
const MeasureRange = ({
  onChange,
  children,
  debug = false
}) => {
  const wrapperRef = React.useRef(null);
  const [rect, setRect] = React.useState(null);
  const rafIdRef = React.useRef(null);
  const lastMeasurementRef = React.useRef(null);
  const elementsRef = React.useRef([]);
  const transformUpdatePendingRef = React.useRef(false);
  const { dragging } = React.useContext(resizableWrapper.DragHandleContext);
  const frameContext = autoFrame.useFrame();
  const parentObserverRef = React.useRef(null);
  const measureElements = React.useCallback(() => {
    if (rafIdRef.current) {
      cancelAnimationFrame(rafIdRef.current);
    }
    rafIdRef.current = requestAnimationFrame(() => {
      const wrapper = wrapperRef.current;
      if (!wrapper) {
        console.warn(`[MeasureRange] No wrapper found`);
        return;
      }
      const elements = elementsRef.current;
      if (elements.length === 0) {
        return;
      }
      try {
        const elementRects = elements.map((el) => el.getBoundingClientRect());
        if (elementRects.length === 0) return;
        const minTop = Math.min(...elementRects.map((rect2) => rect2.top));
        const minLeft = Math.min(...elementRects.map((rect2) => rect2.left));
        const maxBottom = Math.max(...elementRects.map((rect2) => rect2.bottom));
        const maxRight = Math.max(...elementRects.map((rect2) => rect2.right));
        const newRect = {
          top: minTop,
          left: minLeft,
          width: maxRight - minLeft,
          height: maxBottom - minTop,
          bottom: maxBottom,
          right: maxRight
        };
        const hasChanged = !lastMeasurementRef.current || Math.abs(lastMeasurementRef.current.top - newRect.top) > MIN_CHANGE_THRESHOLD || Math.abs(lastMeasurementRef.current.left - newRect.left) > MIN_CHANGE_THRESHOLD || Math.abs(lastMeasurementRef.current.width - newRect.width) > MIN_CHANGE_THRESHOLD || Math.abs(lastMeasurementRef.current.height - newRect.height) > MIN_CHANGE_THRESHOLD;
        if (hasChanged) {
          lastMeasurementRef.current = newRect;
          setRect(newRect);
          if (onChange) {
            const adjustedWidth = Math.max(newRect.width, MIN_SIZE);
            const adjustedHeight = Math.max(newRect.height, MIN_SIZE);
            onChange({
              ...newRect,
              width: adjustedWidth,
              height: adjustedHeight,
              bottom: newRect.top + adjustedHeight,
              right: newRect.left + adjustedWidth
            });
          }
        }
        transformUpdatePendingRef.current = false;
      } catch (error) {
        console.warn("Error measuring elements:", error);
      }
    });
  }, [onChange]);
  index_esm.useTransformEffect(
    React.useCallback(() => {
      if (transformUpdatePendingRef.current) return;
      transformUpdatePendingRef.current = true;
      measureElements();
    }, [measureElements])
  );
  React.useEffect(() => {
    measureElements();
  }, [dragging, measureElements]);
  React.useLayoutEffect(() => {
    const wrapper = wrapperRef.current;
    if (!wrapper) return;
    const elements = Array.from(wrapper.childNodes).filter(
      (node) => {
        if (node.nodeType !== Node.ELEMENT_NODE) return false;
        const element = node;
        const rect2 = element.getBoundingClientRect();
        return rect2.width > 0 || rect2.height > 0;
      }
    );
    elementsRef.current = elements;
    if (elements.length === 0) return;
    const observers = elements.map((el) => {
      const ro = new ResizeObserver(measureElements);
      ro.observe(el);
      return ro;
    });
    const parentContainer = wrapper.closest("#editor-panel-container") || wrapper.closest('[data-testid="transform-component"]') || wrapper.closest(".relative");
    if (parentContainer && parentContainer instanceof HTMLElement) {
      parentObserverRef.current = new ResizeObserver(measureElements);
      parentObserverRef.current.observe(parentContainer);
    }
    const scrollListeners = [];
    const targetDocument = frameContext.document || document;
    const targetWindow = frameContext.window || window;
    const potentialScrollContainers = [
      // Editor panel container (in parent document)
      document.getElementById("editor-panel-container"),
      // Transform component (zoom/pan container)
      wrapper.closest('[data-testid="transform-component"]'),
      // Any iframe that might contain our content
      document.querySelector("iframe"),
      // Canvas containers
      wrapper.closest(".relative"),
      wrapper.closest("[data-zoom-pan-pinch]"),
      // Traditional scroll parent
      elements.length > 0 ? getScrollParent.getScrollParent(elements[0]) : null,
      // Iframe-specific containers if we're in an iframe
      ...frameContext.document ? [
        frameContext.document.getElementById("frame-root"),
        frameContext.document.body
      ] : []
    ].filter(Boolean);
    potentialScrollContainers.forEach((container) => {
      if (container && container !== document.body && container !== targetDocument.body) {
        const scrollHandler = () => {
          measureElements();
        };
        container.addEventListener("scroll", scrollHandler, { passive: true });
        scrollListeners.push(
          () => container.removeEventListener("scroll", scrollHandler)
        );
      }
    });
    const setupWindowListeners = (win, _) => {
      const windowScrollHandler = () => {
        measureElements();
      };
      const windowResizeHandler = () => {
        measureElements();
      };
      win.addEventListener("scroll", windowScrollHandler, { passive: true });
      win.addEventListener("resize", windowResizeHandler, { passive: true });
      scrollListeners.push(
        () => win.removeEventListener("scroll", windowScrollHandler)
      );
      scrollListeners.push(
        () => win.removeEventListener("resize", windowResizeHandler)
      );
    };
    setupWindowListeners(window);
    if (frameContext.window && frameContext.window !== window) {
      setupWindowListeners(frameContext.window);
    }
    let mutationObserver = null;
    if ("MutationObserver" in targetWindow) {
      mutationObserver = new MutationObserver(measureElements);
      const transformContainer = wrapper.closest('[data-testid="transform-component"]') || wrapper.closest("[data-zoom-pan-pinch]") || targetDocument.body;
      mutationObserver.observe(transformContainer, {
        attributeFilter: ["style", "class", "transform"],
        attributes: true,
        subtree: true
      });
    }
    measureElements();
    return () => {
      observers.forEach((ro) => ro.disconnect());
      if (parentObserverRef.current) {
        parentObserverRef.current.disconnect();
        parentObserverRef.current = null;
      }
      scrollListeners.forEach((cleanup) => cleanup());
      if (mutationObserver) {
        mutationObserver.disconnect();
      }
      if (rafIdRef.current) {
        cancelAnimationFrame(rafIdRef.current);
        rafIdRef.current = null;
      }
    };
  }, [children, measureElements, frameContext.document, frameContext.window]);
  React.useEffect(() => {
    return () => {
      if (rafIdRef.current) {
        cancelAnimationFrame(rafIdRef.current);
      }
    };
  }, []);
  const memoizedStyle = React.useMemo(() => {
    if (!rect) return {};
    return {
      position: "fixed",
      top: rect.top,
      left: rect.left,
      width: Math.max(rect.width, MIN_SIZE),
      height: Math.max(rect.height, MIN_SIZE),
      border: "1px solid #5be312",
      zIndex: 9999,
      boxSizing: "border-box",
      pointerEvents: "none",
      cursor: "default"
    };
  }, [rect]);
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
    /* @__PURE__ */ jsxRuntime.jsx("span", { ref: wrapperRef, style, children }),
    rect && debug && /* @__PURE__ */ jsxRuntime.jsx("div", { style: memoizedStyle })
  ] });
};

exports.ElementSelector = ElementSelector;
exports.MeasureRange = MeasureRange;
