/**
 * HoverAnimation - Block editor hover animation controls
 *
 * Adds hover animation type, intensity level, and trigger mode controls.
 * Supports self-hover and parent-hover trigger modes.
 *
 * Parent blocks (group, column, cover) get a "Hover Animation Trigger" toggle.
 * Child blocks choose trigger: "Self" or "Parent" to control when animation fires.
 *
 * Single file by design: no module system available (plain JS, no build step).
 */
(function () {
  var el = wp.element.createElement;
  var Fragment = wp.element.Fragment;
  var __ = wp.i18n.__;
  var addFilter = wp.hooks.addFilter;
  var createHigherOrderComponent = wp.compose.createHigherOrderComponent;
  var InspectorControls = wp.blockEditor.InspectorControls;
  var PanelBody = wp.components.PanelBody;
  var SelectControl = wp.components.SelectControl;
  var ToggleControl = wp.components.ToggleControl;
  var ColorPalette = wp.components.ColorPalette;
  var BaseControl = wp.components.BaseControl;

  // ── Supported blocks ────────────────────────────────────────────

  var SUPPORTED_BLOCKS = [
    "core/group",
    "core/image",
    "core/column",
    "core/cover",
    "core/heading",
    "core/paragraph",
    "woocommerce/product-image",
    "core/post-featured-image",
    "core/post-title",
    "core/button",
    "woocommerce/product-button",
    "brandy/add-to-wishlist",
    "woocommerce/product-price",
    "brandy/button"
  ];

  var TRIGGER_PARENT_BLOCKS = ["core/group", "core/column", "core/cover"];
  var TEXT_BLOCKS = ["core/heading", "core/paragraph", "core/post-title", "woocommerce/product-price"];
  var IMAGE_BLOCKS = ["core/image", "core/cover", "core/post-featured-image", "woocommerce/product-image", "core/group", "core/column"];

  function isSupportedBlock(blockName) {
    return SUPPORTED_BLOCKS.indexOf(blockName) !== -1;
  }

  function isTriggerParentBlock(blockName) {
    return TRIGGER_PARENT_BLOCKS.indexOf(blockName) !== -1;
  }

  function isTextBlock(blockName) {
    return TEXT_BLOCKS.indexOf(blockName) !== -1;
  }

  function isImageBlock(blockName) {
    return IMAGE_BLOCKS.indexOf(blockName) !== -1;
  }

  // ── Animation presets ───────────────────────────────────────────

  var ANIMATION_TYPES = [
    { label: "None", value: "" },
    { label: "Fly Up", value: "fly-up" },
    { label: "Fly Down", value: "fly-down" },
    { label: "Fly Left", value: "fly-left" },
    { label: "Fly Right", value: "fly-right" },
    { label: "Zoom In", value: "zoom-in" },
    { label: "Zoom Out", value: "zoom-out" },
    { label: "Fade", value: "fade" },
    { label: "Fade In", value: "fade-in" },
    { label: "Fade In Up", value: "fade-in-up" },
    { label: "Fade In Down", value: "fade-in-down" },
    { label: "Fade In Left", value: "fade-in-left" },
    { label: "Fade In Right", value: "fade-in-right" },
    { label: "Fade Out", value: "fade-out" },
    { label: "Rotate CW", value: "rotate-cw" },
    { label: "Rotate CCW", value: "rotate-ccw" },
    { label: "Bounce", value: "bounce" },
    { label: "Pulse", value: "pulse" },
    { label: "Skew", value: "skew" },
    { label: "Image Zoom", value: "image-zoom" },
    { label: "Color Overlay", value: "color-overlay" },
    { label: "Image Zoom & Overlay", value: "image-zoom-overlay" },
    { label: "Underline", value: "underline" },
    { label: "Text Underline", value: "text-underline" },
    { label: "Text Underline Slide", value: "text-underline-slide" },
  ];

  var ANIMATION_LEVELS = [
    { label: "Subtle", value: "subtle" },
    { label: "Medium", value: "medium" },
    { label: "Strong", value: "strong" },
    { label: "Extra", value: "extra" },
  ];

  var TRIGGER_OPTIONS = [
    { label: "Self", value: "self" },
    { label: "Parent", value: "parent" },
  ];

  // ── CSS class builder ───────────────────────────────────────────

  function getAnimationClasses(hoverAnimation) {
    var type = hoverAnimation && hoverAnimation.type;
    var level = hoverAnimation && hoverAnimation.level;
    var trigger = (hoverAnimation && hoverAnimation.trigger) || "self";

    if (!type || !level) return "";

    var baseClass =
      trigger === "parent" ? "has-hover-child-animation" : "has-hover-animation";

    return baseClass + " has-hover-" + type + " has-hover-level-" + level;
  }

  // ── Fade types (hide content in editor — need CSS override) ────

  var FADE_TYPES = ["fade", "fade-in", "fade-in-up", "fade-in-down", "fade-in-left", "fade-in-right", "fade-out"];

  function isFadeType(type) {
    return FADE_TYPES.indexOf(type) !== -1;
  }

  // ── Settings panel component ────────────────────────────────────

  function HoverAnimationPanel(props) {
    var attributes = props.attributes;
    var setAttributes = props.setAttributes;
    var blockName = props.name;

    var hoverAnimation = attributes.hoverAnimation || {};
    var animationType = hoverAnimation.type || "";
    var animationLevel = hoverAnimation.level || "";
    var animationTrigger = hoverAnimation.trigger || "self";
    var animationColor = hoverAnimation.color || "";

    var isTriggerParent = isTriggerParentBlock(blockName);
    var hoverAnimationTrigger = attributes.hoverAnimationTrigger || false;

    var children = [];

    // Trigger parent toggle (only for group, column, cover)
    if (isTriggerParent) {
      children.push(
        el(ToggleControl, {
          key: "trigger-toggle",
          label: __("Hover Animation Trigger", "brandy"),
          help: __(
            "When enabled, hovering this block triggers animations on child blocks set to 'Parent' trigger.",
            "brandy"
          ),
          checked: hoverAnimationTrigger,
          onChange: function (value) {
            setAttributes({ hoverAnimationTrigger: value });
          },
        })
      );
    }

    // Filter animation types by block capability
    var availableTypes = ANIMATION_TYPES.filter(function (t) {
      if (!t.value) return true;
      // Text animations only for text blocks
      if ((t.value === "text-underline-slide" || t.value === "text-underline") && !isTextBlock(blockName)) return false;
      // Image animations only for image/container blocks
      if ((t.value === "image-zoom" || t.value === "image-zoom-overlay") && !isImageBlock(blockName)) return false;
      return true;
    });

    // Animation type selector
    children.push(
      el(SelectControl, {
        key: "animation-type",
        label: __("Animation Type", "brandy"),
        value: animationType,
        options: availableTypes,
        onChange: function (value) {
          var newTrigger = value ? animationTrigger : "self";
          // Fade In variants only work with parent trigger
          if (value && value.indexOf("fade-in") === 0) {
            newTrigger = "parent";
          }
          // Color overlay uses color alpha for opacity — force level to "medium" (required by class system)
          var newLevel = value === "color-overlay" ? "medium" : (value ? animationLevel || "medium" : "");
          setAttributes({
            hoverAnimation: Object.assign({}, hoverAnimation, {
              type: value,
              level: newLevel,
              trigger: newTrigger,
            }),
          });
        },
      })
    );

    // Intensity selector (only when type is set, hidden for color-overlay)
    var isColorOverlay = animationType === "color-overlay";
    if (animationType) {
      if (!isColorOverlay) {
        children.push(
          el(SelectControl, {
            key: "animation-level",
            label: __("Intensity", "brandy"),
            value: animationLevel,
            options: ANIMATION_LEVELS,
            onChange: function (value) {
              setAttributes({
                hoverAnimation: Object.assign({}, hoverAnimation, {
                  level: value,
                }),
              });
            },
          })
        );
      }

      // Trigger mode selector (self or parent)
      // Fade In variants are locked to parent trigger
      var isFadeIn = animationType && animationType.indexOf("fade-in") === 0;
      children.push(
        el(SelectControl, {
          key: "animation-trigger",
          label: __("Trigger", "brandy"),
          help: isFadeIn
            ? __("Animation triggers when a parent block with 'Hover Animation Trigger' is hovered.", "brandy")
            : animationTrigger === "parent"
              ? __(
                  "Animation triggers when a parent block with 'Hover Animation Trigger' is hovered.",
                  "brandy"
                )
              : __("Animation triggers when this block itself is hovered.", "brandy"),
          value: animationTrigger,
          options: TRIGGER_OPTIONS,
          disabled: isFadeIn,
          onChange: function (value) {
            setAttributes({
              hoverAnimation: Object.assign({}, hoverAnimation, {
                trigger: value,
              }),
            });
          },
        })
      );

      // Underline color picker (only for underline animation types)
      var isUnderline =
        animationType === "underline" ||
        animationType === "text-underline" ||
        animationType === "text-underline-slide";

      if (isUnderline) {
        children.push(
          el(
            BaseControl,
            {
              key: "animation-color",
              label: __("Underline Color", "brandy"),
              help: __("Leave empty to use the text color.", "brandy"),
            },
            el(ColorPalette, {
              value: animationColor,
              onChange: function (value) {
                setAttributes({
                  hoverAnimation: Object.assign({}, hoverAnimation, {
                    color: value || "",
                  }),
                });
              },
              clearable: true,
            })
          )
        );
      }

      if (isColorOverlay || animationType === "image-zoom-overlay") {
        children.push(
          el(
            BaseControl,
            {
              key: "overlay-color",
              label: __("Overlay Color", "brandy"),
              help: __("Use color opacity to control overlay transparency.", "brandy"),
            },
            el(ColorPalette, {
              value: animationColor,
              enableAlpha: true,
              __experimentalIsRenderedInSidebar: true,
              onChange: function (value) {
                setAttributes({
                  hoverAnimation: Object.assign({}, hoverAnimation, {
                    color: value || "",
                  }),
                });
              },
              clearable: true,
            })
          )
        );
      }
    }

    return el(
      InspectorControls,
      null,
      el(
        PanelBody,
        {
          title: __("Hover Animation", "brandy"),
          initialOpen: false,
        },
        children
      )
    );
  }

  // ── Attribute registration filter ───────────────────────────────

  function registerHoverAnimationAttributes(settings) {
    if (typeof settings.attributes === "undefined") {
      return settings;
    }

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

    settings.attributes.hoverAnimation = {
      type: "object",
      default: {
        type: "",
        level: "",
        trigger: "self",
      },
    };

    // Trigger parent toggle for container blocks
    if (isTriggerParentBlock(settings.name)) {
      settings.attributes.hoverAnimationTrigger = {
        type: "boolean",
        default: false,
      };
    }

    return settings;
  }

  // ── Editor BlockEdit HOC ────────────────────────────────────────

  var addHoverAnimationControls = createHigherOrderComponent(
    function (BlockEdit) {
      return function (props) {
        var isSelected = props.isSelected;
        var blockName = props.name;

        return el(
          Fragment,
          null,
          el(BlockEdit, props),
          isSelected &&
            isSupportedBlock(blockName) &&
            el(HoverAnimationPanel, props)
        );
      };
    },
    "addHoverAnimationControls"
  );

  // ── Editor BlockListBlock HOC (live preview) ────────────────────

  var addHoverAnimationClassToBlock = createHigherOrderComponent(
    function (BlockListBlock) {
      return function (props) {
        var attributes = props.attributes;

        if (!isSupportedBlock(props.name)) {
          return el(BlockListBlock, props);
        }

        var classes = [];
        var animType = (attributes.hoverAnimation || {}).type || "";

        // Add trigger parent class
        var isTriggerEnabled = isTriggerParentBlock(props.name) && attributes.hoverAnimationTrigger;
        if (isTriggerEnabled) {
          classes.push("is-hover-trigger");
        }

        // Add animation classes
        var animClasses = getAnimationClasses(attributes.hoverAnimation);
        if (animClasses) {
          classes.push(animClasses);
        }

        // Add fade override class for editor
        if (animType && isFadeType(animType)) {
          classes.push("brandy-editor-fade-override");
        }

        if (classes.length === 0 && !animType && !isTriggerEnabled) {
          return el(BlockListBlock, props);
        }

        var existingClassName = props.className || "";
        var newClassName = classes.length > 0
          ? (existingClassName + " " + classes.join(" ")).trim()
          : existingClassName;

        // Build extra props
        var extraProps = { className: newClassName };
        var wrapperProps = props.wrapperProps || {};
        var styleObj = Object.assign({}, wrapperProps.style || {});

        // Add color CSS variables (underline or overlay)
        var animColor = (attributes.hoverAnimation || {}).color;
        if (animColor) {
          var cssVarName = (animType === "color-overlay" || animType === "image-zoom-overlay")
            ? "--brandy-overlay-color"
            : "--brandy-underline-color";
          styleObj[cssVarName] = animColor;
        }

        extraProps.wrapperProps = Object.assign({}, wrapperProps, {
          style: styleObj,
        });

        return el(
          BlockListBlock,
          Object.assign({}, props, extraProps)
        );
      };
    },
    "addHoverAnimationClassToBlock"
  );

  // ── Register filters ────────────────────────────────────────────

  addFilter(
    "blocks.registerBlockType",
    "brandy/hover-animation-attributes",
    registerHoverAnimationAttributes,
  );

  addFilter(
    "editor.BlockEdit",
    "brandy/hover-animation-controls",
    addHoverAnimationControls,
    100
  );

  addFilter(
    "editor.BlockListBlock",
    "brandy/hover-animation-class",
    addHoverAnimationClassToBlock
  );
})();
