function isSupportedBlock(settings) {
  return ["core/group", "core/columns", "core/column", "core/buttons", "core/paragraph", "core/heading"].includes(settings.name);
}

const TEXT_ALIGN_BLOCKS = ["core/paragraph", "core/heading"];

/** Paragraph uses "align", heading uses "textAlign" */
function getTextAlignAttr(blockName) {
  return blockName === "core/heading" ? "textAlign" : "align";
}

const CONTENT_RESPONSIVE_PRIORITY = 9;

const DEFAULT_VALUE = {
  textAlign: {
    tablet: { enabled: false, value: "left" },
    mobile: { enabled: false, value: "left" },
  },
  justifyContent: {
    tablet: { enabled: false, value: "left" },
    mobile: { enabled: false, value: "left" },
  },
};

/** Register attribute */
function addContentResponsiveControlsAttributes(settings) {
  if (typeof settings.attributes === "undefined") {
    return settings;
  }
  if (!isSupportedBlock(settings)) {
    return settings;
  }
  settings.attributes = Object.assign(settings.attributes, {
    responsiveControls: {
      type: "object",
      default: {},
    },
  });
  return settings;
}

wp.hooks.addFilter(
  "blocks.registerBlockType",
  "brandy-blocks/content-responsive-controls-attribute",
  addContentResponsiveControlsAttributes
);

/** Blocks that support text align & justification toolbars */
const JUSTIFY_BLOCKS = ["core/group", "core/columns", "core/column", "core/buttons"];

/**
 * Text align: intercept native toolbar on non-desktop (reads from props — works).
 * Justification: custom toolbar buttons on non-desktop (native reads from store — can't intercept).
 */
const ContentResponsiveControls = wp.compose.createHigherOrderComponent(
  (BlockEdit) => {
    return (props) => {
      const { Fragment } = wp.element;
      const { ToolbarButton, ToolbarGroup, DropdownMenu } = wp.components;
      const { BlockControls } = wp.blockEditor;
      const { isSelected, attributes, setAttributes, name } = props;
      const canAddSettings = isSupportedBlock(props);
      const { useSelect } = wp.data;
      const previewDevice = useSelect((select) =>
        (
          (
            select("core/edit-post") ?? select("core/edit-site")
          )?.__experimentalGetPreviewDeviceType() ?? ""
        ).toLowerCase()
      );

      const isNonDesktop = previewDevice !== "desktop";
      const isTextBlock = TEXT_ALIGN_BLOCKS.includes(name);
      const isJustifyBlock = JUSTIFY_BLOCKS.includes(name);
      const responsive = attributes.responsiveControls ?? {};

      // --- Text align: intercept native toolbar for paragraph/heading (non-desktop only) ---
      let wrappedAttributes = attributes;
      let wrappedSetAttributes = setAttributes;

      if (isTextBlock && isNonDesktop) {
        const attrName = getTextAlignAttr(name);
        const textOverride = responsive?.textAlign?.[previewDevice];

        // Feed responsive value into native attribute so toolbar shows it
        if (textOverride?.enabled) {
          wrappedAttributes = { ...attributes, [attrName]: textOverride.value };
        }

        // Redirect text align changes to responsiveControls
        wrappedSetAttributes = (newAttrs) => {
          if (attrName in newAttrs) {
            const val = newAttrs[attrName];
            const { [attrName]: _, ...rest } = newAttrs;

            const updatedTextAlign = {
              ...(responsive.textAlign ?? {}),
            };
            updatedTextAlign[previewDevice] = val
              ? { enabled: true, value: val }
              : { enabled: false, value: "left" };

            setAttributes({
              ...rest,
              responsiveControls: {
                ...responsive,
                textAlign: updatedTextAlign,
              },
            });
            return;
          }
          setAttributes(newAttrs);
        };
      }

      // --- Justification: dropdown toolbar on non-desktop (like native) ---
      const deviceLabel =
        previewDevice.charAt(0).toUpperCase() + previewDevice.slice(1);
      const justifyOverride = responsive?.justifyContent?.[previewDevice];
      const nativeJustify =
        attributes.layout?.justifyContent ?? "left";
      const activeJustify = justifyOverride?.enabled
        ? justifyOverride.value
        : null;
      /**
       * Fallback priority: active override → upper device → native (desktop).
       * Mobile falls back to tablet, tablet falls back to native.
       */
      const getJustifyFallback = () => {
        if (activeJustify) return activeJustify;
        if (previewDevice === "mobile") {
          const tabletOverride = responsive?.justifyContent?.tablet;
          if (tabletOverride?.enabled) return tabletOverride.value;
        }
        return nativeJustify;
      };
      const displayJustify = getJustifyFallback();

      /** SVG justify icons matching native WordPress justify toolbar */
      const justifySvg = (paths) =>
        React.createElement(
          "svg",
          { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", width: 24, height: 24 },
          ...paths.map((d) => React.createElement("path", { d }))
        );
      const justifyIconMap = {
        left: justifySvg(["M9 9v6h11V9H9zM4 20h1.5V4H4v16z"]),
        center: justifySvg(["M20 9h-7.2V4h-1.6v5H4v6h7.2v5h1.6v-5H20z"]),
        right: justifySvg(["M4 15h11V9H4v6zM18.5 4v16H20V4h-1.5z"]),
      };

      const onJustifyChange = (value) => {
        const updatedJustify = {
          ...(responsive.justifyContent ?? {}),
        };
        // Click active value → unset (fall back to desktop)
        if (activeJustify === value) {
          updatedJustify[previewDevice] = { enabled: false, value: "left" };
        } else {
          updatedJustify[previewDevice] = { enabled: true, value };
        }
        setAttributes({
          responsiveControls: {
            ...responsive,
            justifyContent: updatedJustify,
          },
        });
      };

      // --- Text align: dropdown toolbar for group/column/buttons on non-desktop ---
      const textAlignSvg = (paths) =>
        React.createElement(
          "svg",
          { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", width: 24, height: 24 },
          ...paths.map((d) => React.createElement("path", { d }))
        );
      const textAlignIconMap = {
        left: textAlignSvg(["M13 5.5H4V4h9v1.5Zm7 7H4V11h16v1.5Zm-7 7H4V18h9v1.5Z"]),
        center: textAlignSvg(["M7.5 5.5h9V4h-9v1.5Zm-3.5 7h16V11H4v1.5Zm3.5 7h9V18h-9v1.5Z"]),
        right: textAlignSvg(["M11.111 5.5H20V4h-8.889v1.5ZM4 12.5h16V11H4v1.5Zm7.111 7H20V18h-8.889v1.5Z"]),
      };

      const textOverrideForBlock = responsive?.textAlign?.[previewDevice];
      const activeTextAlign = textOverrideForBlock?.enabled
        ? textOverrideForBlock.value
        : null;
      const getTextFallback = () => {
        if (activeTextAlign) return activeTextAlign;
        if (previewDevice === "mobile") {
          const tabletText = responsive?.textAlign?.tablet;
          if (tabletText?.enabled) return tabletText.value;
        }
        return "left";
      };
      const displayTextAlign = getTextFallback();

      const onTextAlignChange = (value) => {
        const updatedTextAlign = { ...(responsive.textAlign ?? {}) };
        if (activeTextAlign === value) {
          updatedTextAlign[previewDevice] = { enabled: false, value: "left" };
        } else {
          updatedTextAlign[previewDevice] = { enabled: true, value };
        }
        setAttributes({
          responsiveControls: {
            ...responsive,
            textAlign: updatedTextAlign,
          },
        });
      };

      const textAlignToolbar =
        isSelected && canAddSettings && isJustifyBlock
          ? React.createElement(
              BlockControls,
              null,
              React.createElement(
                ToolbarGroup,
                null,
                React.createElement(DropdownMenu, {
                  icon: textAlignIconMap[displayTextAlign] ?? textAlignIconMap.left,
                  label: `${deviceLabel}: ${wp.i18n.__("Change text alignment")}`,
                  controls: [
                    {
                      icon: textAlignIconMap.left,
                      title: wp.i18n.__("Align text left"),
                      isActive: activeTextAlign === "left",
                      onClick: () => onTextAlignChange("left"),
                    },
                    {
                      icon: textAlignIconMap.center,
                      title: wp.i18n.__("Align text center"),
                      isActive: activeTextAlign === "center",
                      onClick: () => onTextAlignChange("center"),
                    },
                    {
                      icon: textAlignIconMap.right,
                      title: wp.i18n.__("Align text right"),
                      isActive: activeTextAlign === "right",
                      onClick: () => onTextAlignChange("right"),
                    },
                  ],
                })
              )
            )
          : null;

      const justifyToolbar =
        isSelected && canAddSettings && isJustifyBlock
          ? React.createElement(
              BlockControls,
              null,
              React.createElement(
                ToolbarGroup,
                null,
                React.createElement(DropdownMenu, {
                  icon: justifyIconMap[displayJustify] ?? justifyIconMap.left,
                  label: `${deviceLabel}: ${wp.i18n.__(
                    "Change items justification"
                  )}`,
                  toggleProps: {
                    children: React.createElement(
                      "span",
                      { style: { marginLeft: "4px", fontSize: "12px" } },
                      deviceLabel
                    ),
                  },
                  controls: [
                    {
                      icon: justifyIconMap.left,
                      title: wp.i18n.__("Justify items left"),
                      isActive: activeJustify === "left",
                      onClick: () => onJustifyChange("left"),
                    },
                    {
                      icon: justifyIconMap.center,
                      title: wp.i18n.__("Justify items center"),
                      isActive: activeJustify === "center",
                      onClick: () => onJustifyChange("center"),
                    },
                    {
                      icon: justifyIconMap.right,
                      title: wp.i18n.__("Justify items right"),
                      isActive: activeJustify === "right",
                      onClick: () => onJustifyChange("right"),
                    },
                  ],
                })
              )
            )
          : null;

      return React.createElement(
        Fragment,
        null,
        React.createElement(BlockEdit, {
          ...props,
          attributes: wrappedAttributes,
          setAttributes: wrappedSetAttributes,
        }),
        textAlignToolbar,
        isNonDesktop ? justifyToolbar : null
      );
    };
  },
  "ContentResponsiveControls"
);

wp.hooks.addFilter(
  "editor.BlockEdit",
  "brandy-blocks/content-responsive-controls",
  ContentResponsiveControls,
  CONTENT_RESPONSIVE_PRIORITY
);

const AddContentResponsiveControlsStyleToBlock =
  wp.compose.createHigherOrderComponent((BlockListBlock) => {
    return (props) => {
      const {
        attributes,
        block: { name: blockName },
      } = props;

      const { useSelect } = wp.data;
      const previewDevice = useSelect((select) =>
        (
          (
            select("core/edit-post") ?? select("core/edit-site")
          )?.__experimentalGetPreviewDeviceType() ?? ""
        ).toLowerCase()
      );

      const extraProps = { ...props };
      extraProps.className = props.className ?? "";

      const devices = ["desktop", "tablet", "mobile"];

      if (isSupportedBlock(props.block)) {
        // Add CSS classes for frontend rendering (media queries)
        // Always use "justify" prefix — CSS differentiates via .is-layout-flex / .is-vertical selectors
        devices.forEach((device) => {
          const prefix = device === "desktop" ? "" : device === "tablet" ? "md" : "sm";
          if (attributes.responsiveControls?.textAlign?.[device]?.enabled) {
            if ( device === "desktop" ) {
              extraProps.className += attributes.responsiveControls?.textAlign?.[device]?.value ? `has-text-align-${
                attributes.responsiveControls?.textAlign?.[device]?.value
              }` : '';
            } else {
              extraProps.className += ` ${prefix}-text-${
                attributes.responsiveControls?.textAlign?.[device]?.value ??
                "left"
                }`;
            }
          }
          if (
            attributes.responsiveControls?.justifyContent?.[device]?.enabled
          ) {
            extraProps.className += ` ${prefix}-justify-${
              attributes.responsiveControls?.justifyContent?.[device]?.value ??
              "left"
            }`;
          }
        });

        // Editor preview: inject scoped CSS for current device
        // (media queries don't fire in editor — viewport doesn't change)
        const isNonDesktop = previewDevice !== "desktop";
        if (isNonDesktop) {
          return React.createElement(
            wp.element.Fragment,
            null,
            React.createElement(BlockListBlock, extraProps)
          );
        }
      }

      return React.createElement(BlockListBlock, extraProps);
    };
  }, "AddContentResponsiveControlsStyleToBlock");

wp.hooks.addFilter(
  "editor.BlockListBlock",
  "brandy/content-responsive-controls-style",
  AddContentResponsiveControlsStyleToBlock,
  CONTENT_RESPONSIVE_PRIORITY
);
