import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
import React__default, { useCallback, useMemo } from 'react';
import { z } from 'zod';
import { useLayerStore } from '../../../lib/ui-builder/store/layer-store.mjs';
import { useEditorStore } from '../../../lib/ui-builder/store/editor-store.mjs';
import { Button } from '../../button.mjs';
import AutoForm from '../../auto-form/index.mjs';
import { generateFieldOverrides } from '../../../lib/ui-builder/store/editor-utils.mjs';
import { addDefaultValues } from '../../../lib/ui-builder/store/schema-utils.mjs';
import { getBaseType } from '../../auto-form/helpers.mjs';
import { resolveVariableReferences } from '../../../lib/ui-builder/utils/variable-resolver.mjs';
import { isVariableReference } from '../types.mjs';

const PropsPanel = React__default.memo(({ className }) => {
  const selectedLayerId = useLayerStore((state) => state.selectedLayerId);
  const findLayerById = useLayerStore((state) => state.findLayerById);
  const removeLayer = useLayerStore((state) => state.removeLayer);
  const duplicateLayer = useLayerStore((state) => state.duplicateLayer);
  const updateLayer = useLayerStore((state) => state.updateLayer);
  const addComponentLayer = useLayerStore((state) => state.addComponentLayer);
  const componentRegistry = useEditorStore((state) => state.registry);
  const selectedLayer = findLayerById(selectedLayerId);
  const handleAddComponentLayer = useCallback(
    (layerType, parentLayerId, addPosition) => {
      addComponentLayer(layerType, parentLayerId, addPosition);
    },
    [addComponentLayer]
  );
  const handleDeleteLayer = useCallback(
    (layerId) => {
      removeLayer(layerId);
    },
    [removeLayer]
  );
  const handleDuplicateLayer = useCallback(() => {
    if (selectedLayer) {
      duplicateLayer(selectedLayer.id);
    }
  }, [selectedLayer, duplicateLayer]);
  const handleUpdateLayer = useCallback(
    (id, props, rest) => {
      updateLayer(id, props, rest);
    },
    [updateLayer]
  );
  if (selectedLayer && !componentRegistry[selectedLayer.type]) {
    return null;
  }
  return /* @__PURE__ */ jsxs("div", { className, children: [
    selectedLayer && /* @__PURE__ */ jsxs(Fragment, { children: [
      /* @__PURE__ */ jsx(Title, {}),
      /* @__PURE__ */ jsxs("h3", { className: "text-base font-medium mb-4", children: [
        "Type: ",
        selectedLayer.type.replaceAll("_", "")
      ] })
    ] }),
    !selectedLayer && /* @__PURE__ */ jsxs(Fragment, { children: [
      /* @__PURE__ */ jsx("h2", { className: "text-xl font-semibold mb-2", children: "Component Properties" }),
      /* @__PURE__ */ jsx("p", { children: "No component selected" })
    ] }),
    selectedLayer && /* @__PURE__ */ jsx(
      ComponentPropsAutoForm,
      {
        componentRegistry,
        selectedLayerId: selectedLayer.id,
        removeLayer: handleDeleteLayer,
        duplicateLayer: handleDuplicateLayer,
        updateLayer: handleUpdateLayer,
        addComponentLayer: handleAddComponentLayer
      },
      selectedLayer.id
    )
  ] });
});
PropsPanel.displayName = "PropsPanel";
const EMPTY_ZOD_SCHEMA = z.object({});
const EMPTY_FORM_VALUES = {};
const ComponentPropsAutoForm = ({
  selectedLayerId,
  componentRegistry,
  removeLayer,
  duplicateLayer,
  updateLayer,
  addComponentLayer
}) => {
  const findLayerById = useLayerStore((state) => state.findLayerById);
  const revisionCounter = useEditorStore((state) => state.revisionCounter);
  const selectedLayer = findLayerById(selectedLayerId);
  const isPage = useLayerStore((state) => state.isLayerAPage(selectedLayerId));
  const allowPagesCreation = useEditorStore(
    (state) => state.allowPagesCreation
  );
  const allowPagesDeletion = useEditorStore(
    (state) => state.allowPagesDeletion
  );
  const { schema } = useMemo(() => {
    if (selectedLayer && componentRegistry[selectedLayer.type]) {
      const registryEntry = componentRegistry[selectedLayer.type];
      if (registryEntry) {
        return registryEntry;
      }
    }
    return { schema: EMPTY_ZOD_SCHEMA };
  }, [selectedLayer, componentRegistry]);
  const handleDeleteLayer = useCallback(() => {
    removeLayer(selectedLayerId);
  }, [removeLayer, selectedLayerId]);
  const handleDuplicateLayer = useCallback(() => {
    duplicateLayer(selectedLayerId);
  }, [duplicateLayer, selectedLayerId]);
  const variables = useLayerStore((state) => state.variables);
  const onParsedValuesChange = useCallback(
    (parsedValues) => {
      const { children, ...dataProps } = parsedValues;
      const preservedProps = {};
      if (selectedLayer) {
        Object.assign(preservedProps, selectedLayer.props);
        Object.keys(dataProps).forEach((key) => {
          const originalValue = selectedLayer.props[key];
          const newValue = dataProps[key];
          const fieldDef = "shape" in schema && schema.shape ? schema.shape[key] : void 0;
          const baseType = fieldDef ? getBaseType(fieldDef) : void 0;
          if (isVariableReference(originalValue)) {
            const variableExists = variables.some((v) => v.id === originalValue.__variableRef);
            if (variableExists) {
              preservedProps[key] = originalValue;
            } else {
              preservedProps[key] = newValue;
            }
          } else {
            if (baseType === "ZodDate" && newValue instanceof Date) {
              preservedProps[key] = newValue.toISOString();
            } else {
              preservedProps[key] = newValue;
            }
          }
        });
      }
      const originalChildren = selectedLayer?.children;
      const shouldPreserveChildrenBinding = isVariableReference(originalChildren) && variables.some((v) => v.id === originalChildren.__variableRef);
      if (shouldPreserveChildrenBinding) {
        updateLayer(selectedLayerId, preservedProps);
      } else if (typeof children === "string") {
        updateLayer(selectedLayerId, preservedProps, { children });
      } else if (children && children.layerType) {
        updateLayer(selectedLayerId, preservedProps, {
          children: selectedLayer?.children
        });
        addComponentLayer(
          children.layerType,
          selectedLayerId,
          children.addPosition
        );
      } else {
        updateLayer(selectedLayerId, preservedProps);
      }
    },
    [updateLayer, selectedLayerId, selectedLayer, addComponentLayer, schema, variables]
  );
  const formValues = useMemo(() => {
    if (!selectedLayer) return EMPTY_FORM_VALUES;
    const resolvedProps = resolveVariableReferences(
      selectedLayer.props,
      variables
    );
    const transformedProps = {};
    const schemaShape = "shape" in schema && schema.shape ? schema.shape : void 0;
    if (schemaShape) {
      for (const [key, value] of Object.entries(resolvedProps)) {
        const fieldDef = schemaShape[key];
        if (fieldDef) {
          const baseType = getBaseType(fieldDef);
          if (baseType === "ZodEnum") {
            transformedProps[key] = typeof value === "string" ? value : String(value);
          } else if (baseType === "ZodDate") {
            if (value instanceof Date) {
              transformedProps[key] = value;
            } else if (typeof value === "string" || typeof value === "number") {
              const date = new Date(value);
              transformedProps[key] = isNaN(date.getTime()) ? void 0 : date;
            } else {
              transformedProps[key] = void 0;
            }
          } else {
            transformedProps[key] = value;
          }
        } else {
          transformedProps[key] = value;
        }
      }
    } else {
      Object.assign(transformedProps, resolvedProps);
    }
    return { ...transformedProps, children: selectedLayer.children };
  }, [selectedLayer, schema, revisionCounter]);
  const autoFormSchema = useMemo(() => {
    if ("shape" in schema && typeof schema.shape === "object") {
      try {
        return addDefaultValues(schema, formValues);
      } catch (error) {
        console.warn("Failed to add default values to schema:", error);
        return schema;
      }
    }
    return schema;
  }, [schema, formValues]);
  const autoFormFieldConfig = useMemo(() => {
    if (!selectedLayer) return void 0;
    return generateFieldOverrides(componentRegistry, selectedLayer);
  }, [componentRegistry, selectedLayer, selectedLayer?.props]);
  const formKey = useMemo(() => {
    return `${selectedLayerId}-${revisionCounter}`;
  }, [selectedLayerId, revisionCounter]);
  if (!selectedLayer || !componentRegistry[selectedLayer.type]) {
    return null;
  }
  return /* @__PURE__ */ jsxs(
    AutoForm,
    {
      formSchema: autoFormSchema,
      values: formValues,
      onParsedValuesChange,
      fieldConfig: autoFormFieldConfig,
      className: "space-y-4 mt-4",
      children: [
        (!isPage || allowPagesCreation) && /* @__PURE__ */ jsxs(
          Button,
          {
            type: "button",
            variant: "secondary",
            className: "mt-4 w-full",
            onClick: handleDuplicateLayer,
            "data-testid": `button-Duplicate ,${isPage ? "Page" : "Component"}`,
            children: [
              "Duplicate ",
              isPage ? "Page" : "Component"
            ]
          }
        ),
        (!isPage || allowPagesDeletion) && /* @__PURE__ */ jsxs(
          Button,
          {
            type: "button",
            variant: "destructive",
            className: "mt-4 w-full",
            onClick: handleDeleteLayer,
            "data-testid": `button-Delete ,${isPage ? "Page" : "Component"}`,
            children: [
              "Delete ",
              isPage ? "Page" : "Component"
            ]
          }
        )
      ]
    },
    formKey
  );
};
ComponentPropsAutoForm.displayName = "ComponentPropsAutoForm";
const nameForLayer = (layer) => {
  return layer.name || layer.type.replaceAll("_", "");
};
const Title = React__default.memo(() => {
  const selectedLayer = useLayerStore((state) => {
    const selectedLayerId = state.selectedLayerId;
    return selectedLayerId ? state.findLayerById(selectedLayerId) : null;
  });
  return /* @__PURE__ */ jsxs("h2", { className: "text-xl font-semibold mb-2", children: [
    selectedLayer ? nameForLayer(selectedLayer) : "",
    " Properties"
  ] });
});
Title.displayName = "Title";

export { PropsPanel as default };
