/**
 * Image Performance Block Settings
 * Adds fetchpriority and loading controls to core/image block
 *
 * @package Brandy
 * @since 1.5.0
 */

(function () {
  const { addFilter } = wp.hooks;
  const { createHigherOrderComponent } = wp.compose;
  const { Fragment } = wp.element;
  const { InspectorControls } = wp.blockEditor;
  const {
    __experimentalToolsPanel: ToolsPanel,
    __experimentalToolsPanelItem: ToolsPanelItem,
    __experimentalToggleGroupControl: ToggleGroupControl,
    __experimentalToggleGroupControlOption: ToggleGroupControlOption,
  } = wp.components;
  const { __ } = wp.i18n;

  /**
   * Check if block is an image block
   */
  function isSupported(name) {
    return ["core/image", "woocommerce/product-image", "core/post-featured-image"].includes(name);
  }

  /**
   * Add custom attributes to image block
   */
  function addImagePerformanceAttributes(settings) {
    if (typeof settings.attributes === "undefined") {
      return settings;
    }

    if (!isSupported(settings.name)) {
      return settings;
    }

    settings.attributes = Object.assign(settings.attributes, {
      fetchPriority: {
        type: "string",
        default: "",
      },
      loading: {
        type: "string",
        default: "",
      },
    });

    return settings;
  }

  addFilter(
    "blocks.registerBlockType",
    "brandy-blocks/image-performance-attributes",
    addImagePerformanceAttributes
  );

  /**
   * Add inspector controls for image performance settings
   */
  const ImagePerformanceControls = createHigherOrderComponent(
    (BlockEdit) => {
      return (props) => {
        const { isSelected, attributes, setAttributes, name } = props;

        if (!isSupported(name)) {
          return React.createElement(BlockEdit, props);
        }

        const { fetchPriority, loading } = attributes;

        return React.createElement(
          Fragment,
          null,
          React.createElement(BlockEdit, props),
          isSelected &&
            React.createElement(
              InspectorControls,
              {},
              React.createElement(
                ToolsPanel,
                {
                  label: __("Performance", "brandy"),
                  resetAll: () =>
                    setAttributes({
                      fetchPriority: "",
                      loading: "",
                    }),
                },
                // Fetch Priority Control
                React.createElement(
                  ToolsPanelItem,
                  {
                    label: __("Fetch Priority", "brandy"),
                    isShownByDefault: true,
                    hasValue: () => !!fetchPriority,
                    onDeselect: () =>
                      setAttributes({ fetchPriority: "" }),
                    __nextHasNoMarginBottom: true,
                  },
                  React.createElement(
                    ToggleGroupControl,
                    {
                      label: __("Fetch Priority", "brandy"),
                      value: fetchPriority || "auto",
                      isBlock: true,
                      __next40pxDefaultSize: true,
                      __nextHasNoMarginBottom: true,
                      help: __(
                        "High priority for above-fold images (LCP). Low for below-fold.",
                        "brandy"
                      ),
                      onChange: (value) => {
                        setAttributes({
                          fetchPriority: value === "auto" ? "" : value,
                        });
                      },
                    },
                    React.createElement(ToggleGroupControlOption, {
                      value: "auto",
                      label: __("Auto", "brandy"),
                    }),
                    React.createElement(ToggleGroupControlOption, {
                      value: "high",
                      label: __("High", "brandy"),
                    }),
                    React.createElement(ToggleGroupControlOption, {
                      value: "low",
                      label: __("Low", "brandy"),
                    })
                  )
                ),
                // Loading Control
                React.createElement(
                  ToolsPanelItem,
                  {
                    label: __("Loading", "brandy"),
                    isShownByDefault: true,
                    hasValue: () => !!loading,
                    onDeselect: () => setAttributes({ loading: "" }),
                    __nextHasNoMarginBottom: true,
                  },
                  React.createElement(
                    ToggleGroupControl,
                    {
                      label: __("Loading Behavior", "brandy"),
                      value: loading || "auto",
                      isBlock: true,
                      __next40pxDefaultSize: true,
                      __nextHasNoMarginBottom: true,
                      help: __(
                        "Eager for above-fold images. Lazy for below-fold (default).",
                        "brandy"
                      ),
                      onChange: (value) => {
                        setAttributes({
                          loading: value === "auto" ? "" : value,
                        });
                      },
                    },
                    React.createElement(ToggleGroupControlOption, {
                      value: "auto",
                      label: __("Auto", "brandy"),
                    }),
                    React.createElement(ToggleGroupControlOption, {
                      value: "lazy",
                      label: __("Lazy", "brandy"),
                    }),
                    React.createElement(ToggleGroupControlOption, {
                      value: "eager",
                      label: __("Eager", "brandy"),
                    })
                  )
                )
              )
            )
        );
      };
    },
    "ImagePerformanceControls"
  );

  addFilter(
    "editor.BlockEdit",
    "brandy-blocks/image-performance-controls",
    ImagePerformanceControls,
    1
  );
})();
