// packages/block-editor/src/components/block-edit/edit.js
import clsx from "clsx";
import {
  getBlockDefaultClassName,
  getBlockType,
  hasBlockSupport,
  store as blocksStore
} from "@wordpress/blocks";
import { withFilters } from "@wordpress/components";
import { useRegistry, useSelect } from "@wordpress/data";
import { useCallback, useContext, useMemo } from "@wordpress/element";
import BlockContext from "../block-context";
import isURLLike from "../link-control/is-url-like";
import {
  hasPatternOverridesDefaultBinding,
  replacePatternOverridesDefaultBinding
} from "../../utils/block-bindings";
import { unlock } from "../../lock-unlock";
import { PrivateBlockContext } from "../block-list/private-block-context";
import { jsx } from "react/jsx-runtime";
var DEFAULT_BLOCK_CONTEXT = {};
var Edit = (props) => {
  const { name } = props;
  const blockType = getBlockType(name);
  if (!blockType) {
    return null;
  }
  const Component = blockType.edit || blockType.save;
  return /* @__PURE__ */ jsx(Component, { ...props });
};
var EditWithFilters = withFilters("editor.BlockEdit")(Edit);
var EditWithGeneratedProps = (props) => {
  const { name, clientId, attributes, setAttributes } = props;
  const registry = useRegistry();
  const blockType = getBlockType(name);
  const blockContext = useContext(BlockContext);
  const registeredSources = useSelect(
    (select) => unlock(select(blocksStore)).getAllBlockBindingsSources(),
    []
  );
  const { bindableAttributes } = useContext(PrivateBlockContext);
  const { blockBindings, context, hasPatternOverrides } = useMemo(() => {
    const computedContext = blockType?.usesContext ? Object.fromEntries(
      Object.entries(blockContext).filter(
        ([key]) => blockType.usesContext.includes(key)
      )
    ) : DEFAULT_BLOCK_CONTEXT;
    if (attributes?.metadata?.bindings) {
      Object.values(attributes?.metadata?.bindings || {}).forEach(
        (binding) => {
          registeredSources[binding?.source]?.usesContext?.forEach(
            (key) => {
              computedContext[key] = blockContext[key];
            }
          );
        }
      );
    }
    return {
      blockBindings: replacePatternOverridesDefaultBinding(
        attributes?.metadata?.bindings,
        bindableAttributes
      ),
      context: computedContext,
      hasPatternOverrides: hasPatternOverridesDefaultBinding(
        attributes?.metadata?.bindings
      )
    };
  }, [
    name,
    blockType?.usesContext,
    blockContext,
    attributes?.metadata?.bindings,
    registeredSources
  ]);
  const computedAttributes = useSelect(
    (select) => {
      if (!blockBindings) {
        return attributes;
      }
      const attributesFromSources = {};
      const blockBindingsBySource = /* @__PURE__ */ new Map();
      for (const [attributeName, binding] of Object.entries(
        blockBindings
      )) {
        const { source: sourceName, args: sourceArgs } = binding;
        const source = registeredSources[sourceName];
        if (!source || !bindableAttributes?.includes(attributeName)) {
          continue;
        }
        blockBindingsBySource.set(source, {
          ...blockBindingsBySource.get(source),
          [attributeName]: {
            args: sourceArgs
          }
        });
      }
      if (blockBindingsBySource.size) {
        for (const [source, bindings] of blockBindingsBySource) {
          let values = {};
          if (!source.getValues) {
            Object.keys(bindings).forEach((attr) => {
              values[attr] = source.label;
            });
          } else {
            values = source.getValues({
              select,
              context,
              clientId,
              bindings
            });
          }
          for (const [attributeName, value] of Object.entries(
            values
          )) {
            if (attributeName === "url" && (!value || !isURLLike(value))) {
              attributesFromSources[attributeName] = null;
            } else {
              attributesFromSources[attributeName] = value;
            }
          }
        }
      }
      return {
        ...attributes,
        ...attributesFromSources
      };
    },
    [
      attributes,
      bindableAttributes,
      blockBindings,
      clientId,
      context,
      name,
      registeredSources
    ]
  );
  const setBoundAttributes = useCallback(
    (nextAttributes) => {
      if (!blockBindings) {
        setAttributes(nextAttributes);
        return;
      }
      registry.batch(() => {
        const keptAttributes = { ...nextAttributes };
        const blockBindingsBySource = /* @__PURE__ */ new Map();
        for (const [attributeName, newValue] of Object.entries(
          keptAttributes
        )) {
          if (!blockBindings[attributeName] || !bindableAttributes?.includes(attributeName)) {
            continue;
          }
          const binding = blockBindings[attributeName];
          const source = registeredSources[binding?.source];
          if (!source?.setValues) {
            continue;
          }
          blockBindingsBySource.set(source, {
            ...blockBindingsBySource.get(source),
            [attributeName]: {
              args: binding.args,
              newValue
            }
          });
          delete keptAttributes[attributeName];
        }
        if (blockBindingsBySource.size) {
          for (const [
            source,
            bindings
          ] of blockBindingsBySource) {
            source.setValues({
              select: registry.select,
              dispatch: registry.dispatch,
              context,
              clientId,
              bindings
            });
          }
        }
        const hasParentPattern = !!context["pattern/overrides"];
        if (
          // Don't update non-connected attributes if the block is using pattern overrides
          // and the editing is happening while overriding the pattern (not editing the original).
          !(hasPatternOverrides && hasParentPattern) && Object.keys(keptAttributes).length
        ) {
          if (hasPatternOverrides) {
            delete keptAttributes.caption;
            delete keptAttributes.href;
          }
          setAttributes(keptAttributes);
        }
      });
    },
    [
      bindableAttributes,
      blockBindings,
      clientId,
      context,
      hasPatternOverrides,
      setAttributes,
      registeredSources,
      name,
      registry
    ]
  );
  if (!blockType) {
    return null;
  }
  if (blockType.apiVersion > 1) {
    return /* @__PURE__ */ jsx(
      EditWithFilters,
      {
        ...props,
        attributes: computedAttributes,
        context,
        setAttributes: setBoundAttributes
      }
    );
  }
  const generatedClassName = hasBlockSupport(blockType, "className", true) ? getBlockDefaultClassName(name) : null;
  const className = clsx(
    generatedClassName,
    attributes?.className,
    props.className
  );
  return /* @__PURE__ */ jsx(
    EditWithFilters,
    {
      ...props,
      attributes: computedAttributes,
      className,
      context,
      setAttributes: setBoundAttributes
    }
  );
};
var edit_default = EditWithGeneratedProps;
export {
  edit_default as default
};
//# sourceMappingURL=edit.js.map
