import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
import React__default, { useMemo, useState, useRef, useCallback, useLayoutEffect } from 'react';
import isDeepEqual from '../../../../../../_virtual/index.mjs';
import { useLayerStore } from '../../../lib/ui-builder/store/layer-store.mjs';
import { isVariableReference } from '../types.mjs';
import { cn } from '../../../lib/utils.mjs';
import { hasLayerChildren, findAllParentLayersRecursive } from '../../../lib/ui-builder/store/layer-utils.mjs';
import { Plus } from 'lucide-react';
import { useHeTree as He } from '../../../../../../node_modules/.pnpm/he-tree-react@1.2.0_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/he-tree-react/dist/index.mjs';
import { TreeRowPlaceholder, TreeRowNode } from './components/tree-row-node.mjs';
import { DevProfiler } from './components/dev-profiler.mjs';
import { AddComponentsPopover } from './components/add-component-popover.mjs';
import { buttonVariants } from '../../button.mjs';
import { DividerControl } from './components/divider-control.mjs';

const LayersPanel = ({ className }) => {
  const {
    selectedPageId,
    selectedLayerId,
    findLayerById,
    updateLayer,
    selectLayer
  } = useLayerStore();
  const pageLayer = findLayerById(selectedPageId);
  const layers = useMemo(() => [pageLayer], [pageLayer]);
  if (!pageLayer) {
    return null;
  }
  return /* @__PURE__ */ jsx(
    LayersTree,
    {
      className,
      layers,
      selectedPageId,
      selectedLayerId,
      updateLayer,
      selectLayer
    }
  );
};
const LayersTree = React__default.memo(
  ({
    className,
    layers,
    selectedPageId,
    selectedLayerId,
    updateLayer,
    selectLayer
  }) => {
    const [openIdsArray, setOpenIdsArray] = useState([]);
    const prevSelectedLayerId = useRef(selectedLayerId);
    const handleNodeToggle = useCallback((id, open) => {
      setOpenIdsArray((prev) => {
        if (open) {
          return prev.includes(id) ? prev : [...prev, id];
        } else {
          return prev.filter((existingId) => existingId !== id);
        }
      });
    }, []);
    const handleChange = useCallback(
      (newLayers) => {
        if (Array.isArray(newLayers) && newLayers.length > 0) {
          const updatedPageLayer = newLayers[0];
          if (!updatedPageLayer || !updatedPageLayer.id || updatedPageLayer.id !== selectedPageId) {
            console.error(
              "LayersTree onChange: Invalid layer structure - ID mismatch",
              { updatedPageLayer, selectedPageId }
            );
            return;
          }
          const updatedChildren = hasLayerChildren(updatedPageLayer) ? updatedPageLayer.children || [] : [];
          const currentLayer = layers[0];
          const currentChildren = currentLayer && hasLayerChildren(currentLayer) ? currentLayer.children || [] : [];
          if (!isDeepEqual(currentChildren, updatedChildren)) {
            updateLayer(selectedPageId, {}, { children: updatedChildren });
          }
        } else {
          console.error(
            "LayersTree onChange: Invalid newLayers structure received",
            newLayers
          );
        }
      },
      [updateLayer, selectedPageId, layers]
    );
    const handleDragOpen = useCallback(
      (stat) => {
        if (hasLayerChildren(stat.node)) {
          handleNodeToggle(stat.id, true);
        }
      },
      [handleNodeToggle]
    );
    const canNodeDrop = useCallback((layer) => {
      const isDroppable = hasLayerChildren(layer.node);
      return isDroppable;
    }, []);
    const renderNode = useCallback(
      ({ stat, attrs, isPlaceholder }) => {
        const stableKey = isPlaceholder ? `placeholder-${attrs.key}` : stat.node.id;
        if (isPlaceholder) {
          return /* @__PURE__ */ jsx(
            TreeRowPlaceholder,
            {
              nodeAttributes: attrs
            },
            stableKey
          );
        }
        const findOriginalLayer = (layers2, id) => {
          for (const layer of layers2) {
            if (layer.id === id) return layer;
            if (hasLayerChildren(layer)) {
              const found = findOriginalLayer(layer.children, id);
              if (found) return found;
            }
          }
          return null;
        };
        const originalNode = findOriginalLayer(layers, stat.node.id) || stat.node;
        return /* @__PURE__ */ jsx(
          TreeRowNode,
          {
            nodeAttributes: attrs,
            node: originalNode,
            id: stat.id,
            open: stat.open,
            draggable: stat.draggable,
            onToggle: handleNodeToggle,
            level: stat.level,
            selectedLayerId,
            selectLayer
          },
          stableKey
        );
      },
      [
        handleNodeToggle,
        selectedLayerId,
        selectLayer,
        layers
      ]
    );
    const processedLayers = useMemo(() => {
      const processLayer = (layer) => {
        const processed = { ...layer };
        if (hasLayerChildren(layer)) {
          processed.children = layer.children.map(processLayer);
        } else if (typeof layer.children === "string") {
          processed.children = [];
        } else if (isVariableReference(layer.children)) {
          processed.children = [];
        } else if (!layer.children) {
          processed.children = [];
        }
        return processed;
      };
      return layers.map(processLayer);
    }, [layers]);
    const data = useMemo(() => {
      return {
        data: processedLayers,
        dataType: "tree",
        childrenKey: "children",
        openIds: openIdsArray,
        dragOpen: true,
        onChange: handleChange,
        renderNodeBox: renderNode,
        onDragOpen: handleDragOpen,
        canDrop: canNodeDrop
      };
    }, [
      processedLayers,
      openIdsArray,
      handleChange,
      renderNode,
      handleDragOpen,
      canNodeDrop
    ]);
    const { renderTree, scrollToNode } = He(data);
    useLayoutEffect(() => {
      if (selectedLayerId) {
        const parentLayers = findAllParentLayersRecursive(
          layers,
          selectedLayerId
        );
        const parentIds = parentLayers.map((layer) => layer.id);
        setOpenIdsArray((prevOpenIds) => {
          const newIds = [...prevOpenIds];
          let hasChanges = false;
          parentIds.forEach((id) => {
            if (!newIds.includes(id)) {
              newIds.push(id);
              hasChanges = true;
            }
          });
          return hasChanges ? newIds : prevOpenIds;
        });
      }
    }, [selectedLayerId, layers]);
    useLayoutEffect(() => {
      if (prevSelectedLayerId.current !== selectedLayerId) {
        prevSelectedLayerId.current = selectedLayerId;
        if (selectedLayerId) {
          scrollToNode(selectedLayerId);
        }
      }
    }, [scrollToNode, selectedLayerId]);
    const buttonClass = useMemo(() => {
      return cn(
        buttonVariants({ variant: "default", size: "sm" }),
        "cursor-pointer w-full"
      );
    }, []);
    return /* @__PURE__ */ jsx(DevProfiler, { id: "LayersPanel", threshold: 40, children: /* @__PURE__ */ jsx(
      "div",
      {
        "data-testid": "layers-tree",
        className: cn(
          className,
          "flex flex-col size-full overflow-x-auto pl-4"
        ),
        children: layers.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
          /* @__PURE__ */ jsx(
            DividerControl,
            {
              className: "border-l border-dashed border-primary",
              addPosition: 0,
              parentLayerId: selectedPageId
            }
          ),
          renderTree(),
          /* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsx("div", { className: "w-[1px] h-4 absolute left-0 bottom-0 border-l border-dashed border-primary bg-background" }) }),
          /* @__PURE__ */ jsx(
            DividerControl,
            {
              className: "border-l border-dashed border-primary",
              parentLayerId: selectedPageId
            }
          )
        ] }) : /* @__PURE__ */ jsx(
          AddComponentsPopover,
          {
            parentLayerId: selectedPageId,
            className: "w-full mt-4",
            children: /* @__PURE__ */ jsxs(
              "div",
              {
                className: buttonClass,
                children: [
                  /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Add Component" }),
                  /* @__PURE__ */ jsx(Plus, { className: "h-5 w-5" }),
                  /* @__PURE__ */ jsx("span", { children: "Add Component" })
                ]
              }
            )
          }
        )
      }
    ) });
  },
  (prevProps, nextProps) => {
    return isDeepEqual(prevProps.layers, nextProps.layers) && prevProps.selectedPageId === nextProps.selectedPageId && prevProps.selectedLayerId === nextProps.selectedLayerId && prevProps.className === nextProps.className;
  }
);
LayersTree.displayName = "LayersTree";

export { LayersTree, LayersPanel as default };
