/**
 * DisplayAnimation - Block editor animation controls
 *
 * Adds animation type, duration, delay, scale, and distance controls
 * to all blocks via the inspector sidebar.
 *
 * 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 SelectControl = wp.components.SelectControl;
  var RangeControl = wp.components.RangeControl;
  var ToggleControl = wp.components.ToggleControl;
  var PanelBody = wp.components.PanelBody;
  var NumberControl = wp.components.__experimentalNumberControl;

  var defaultAnimationSettings = {
    type: "none",
    duration: 1,
    delay: 0,
    scale: 1.3,
    distanceFromOrigin: 50,
    animateOnce: false,
    wordDelay: 0.2,
  };

  var FADE_SLIDE_TYPES = [
    "fade_in_down",
    "fade_in_up",
    "fade_in_left",
    "fade_in_right",
    "slide_in_left",
    "slide_in_right",
    "slide_out_left",
    "slide_out_right",
  ];

  var SCALE_TYPES = ["scale_down", "scale_up"];

  var SLIDE_TEXT_TYPES = ["slide_text_up", "slide_text_left", "slide_text_right"];

  function isScaleType(type) {
    return SCALE_TYPES.indexOf(type) !== -1;
  }

  function isFadeSlideType(type) {
    return FADE_SLIDE_TYPES.indexOf(type) !== -1;
  }

  function isSlideTextType(type) {
    return SLIDE_TEXT_TYPES.indexOf(type) !== -1;
  }

  // ── Register attribute ──────────────────────────────────────────────

  addFilter(
    "blocks.registerBlockType",
    "brandy/display-animation-attribute",
    function (settings) {
      if (typeof settings.attributes === "undefined") {
        return settings;
      }
      if (!settings.attributes.style) {
        settings.attributes.style = {};
      }
      settings.attributes.style = Object.assign(settings.attributes.style, {
        displayAnimation: {
          type: "object",
          default: defaultAnimationSettings,
        },
      });
      return settings;
    }
  );

  // ── Animation options as children elements ──────────────────────────

  function buildAnimationOptions() {
    return [
      el("option", { key: "none", value: "none" }, "None"),
      el(
        "optgroup",
        { key: "fade", label: "Fade in" },
        el("option", { value: "fade_in_down" }, "Fade in down"),
        el("option", { value: "fade_in_up" }, "Fade in up"),
        el("option", { value: "fade_in_left" }, "Fade in left"),
        el("option", { value: "fade_in_right" }, "Fade in right")
      ),
      el(
        "optgroup",
        { key: "slide", label: "Slide" },
        el("option", { value: "slide_in_left" }, "Slide in from the left"),
        el("option", { value: "slide_in_right" }, "Slide in from the right"),
        el("option", { value: "slide_out_left" }, "Slide out to the left"),
        el("option", { value: "slide_out_right" }, "Slide out to the right")
      ),
      el(
        "optgroup",
        { key: "bounce", label: "Bounce" },
        el("option", { value: "bounce" }, "Standing bounce"),
        el("option", { value: "bounce_in" }, "Bounce in")
      ),
      el(
        "optgroup",
        { key: "scale", label: "Scale" },
        el("option", { value: "scale_down" }, "Scale down"),
        el("option", { value: "scale_up" }, "Scale up")
      ),
      el(
        "optgroup",
        { key: "zoom", label: "Zoom" },
        el("option", { value: "zoom_in" }, "Zoom in"),
        el("option", { value: "zoom_out" }, "Zoom out")
      ),
      el(
        "optgroup",
        { key: "sliding_text", label: "Sliding Text" },
        el("option", { value: "slide_text_up" }, "Slide text up"),
        el("option", { value: "slide_text_left" }, "Slide text left"),
        el("option", { value: "slide_text_right" }, "Slide text right")
      ),
    ];
  }

  // ── Helper to update animation attributes ───────────────────────────

  function updateAnimation(attributes, setAttributes, updates) {
    var style = attributes.style || {};
    var displayAnimation =
      style.displayAnimation || defaultAnimationSettings;
    setAttributes({
      style: Object.assign({}, style, {
        displayAnimation: Object.assign({}, displayAnimation, updates),
      }),
    });
  }

  // ── Add controls to inspector ───────────────────────────────────────

  addFilter(
    "editor.BlockEdit",
    "brandy/display-animation-controls",
    createHigherOrderComponent(function (BlockEdit) {
      return function (props) {
        var attributes = props.attributes;
        var setAttributes = props.setAttributes;
        var isSelected = props.isSelected;

        var style = attributes.style || {};
        var displayAnimation =
          style.displayAnimation || defaultAnimationSettings;
        var animType = displayAnimation.type || defaultAnimationSettings.type;

        var controls = [];

        // Type selector
        controls.push(
          el(
            SelectControl,
            {
              key: "type",
              label: __("Display animation effect"),
              __next40pxDefaultSize: true,
              value: animType,
              onChange: function (selection) {
                updateAnimation(attributes, setAttributes, {
                  type: selection,
                });
              },
              __nextHasNoMarginBottom: true,
            },
            buildAnimationOptions()
          )
        );

        // Conditional controls when animation is active
        if (animType && animType !== "none") {
          // Duration (not for scale types)
          if (!isScaleType(animType)) {
            controls.push(
              el(RangeControl, {
                key: "duration",
                __nextHasNoMarginBottom: true,
                label: isSlideTextType(animType)
                  ? "Duration per word (s)"
                  : "Animation duration (s)",
                value:
                  displayAnimation.duration != null
                    ? displayAnimation.duration
                    : defaultAnimationSettings.duration,
                onChange: function (value) {
                  updateAnimation(attributes, setAttributes, {
                    duration: value,
                  });
                },
                min: 0,
                max: 10,
                step: 0.1,
              })
            );
          }

          // Word delay (only for slide text types)
          if (isSlideTextType(animType)) {
            controls.push(
              el(RangeControl, {
                key: "wordDelay",
                __nextHasNoMarginBottom: true,
                label: "Word delay (s)",
                value:
                  displayAnimation.wordDelay != null
                    ? displayAnimation.wordDelay
                    : defaultAnimationSettings.wordDelay,
                onChange: function (value) {
                  updateAnimation(attributes, setAttributes, {
                    wordDelay: value,
                  });
                },
                min: 0.02,
                max: 0.2,
                step: 0.01,
              })
            );
          }

          // Distance from origin (fade/slide types)
          if (isFadeSlideType(animType)) {
            controls.push(
              el(RangeControl, {
                key: "distance",
                __nextHasNoMarginBottom: true,
                label: "Distance from origin (px)",
                value:
                  displayAnimation.distanceFromOrigin != null
                    ? displayAnimation.distanceFromOrigin
                    : defaultAnimationSettings.distanceFromOrigin,
                onChange: function (value) {
                  updateAnimation(attributes, setAttributes, {
                    distanceFromOrigin: value,
                  });
                },
                min: 0,
                max: 1000,
                step: 10,
              })
            );
          }

          // Delay (not for scale or slide text types)
          if (!isScaleType(animType) && !isSlideTextType(animType)) {
            controls.push(
              el(RangeControl, {
                key: "delay",
                __nextHasNoMarginBottom: true,
                label: "Animation delay (s)",
                value:
                  displayAnimation.delay != null
                    ? displayAnimation.delay
                    : defaultAnimationSettings.delay,
                onChange: function (value) {
                  updateAnimation(attributes, setAttributes, {
                    delay: value,
                  });
                },
                min: 0,
                max: 10,
                step: 0.1,
              })
            );
          }

          // Scale control (only for scale types)
          if (isScaleType(animType)) {
            controls.push(
              el(NumberControl, {
                key: "scale",
                __next40pxDefaultSize: true,
                isShiftStepEnabled: true,
                onChange: function (value) {
                  updateAnimation(attributes, setAttributes, {
                    scale: value,
                  });
                },
                value:
                  displayAnimation.scale != null
                    ? displayAnimation.scale
                    : defaultAnimationSettings.scale,
                label: __(
                  animType === "scale_down"
                    ? "Origin scale rate"
                    : "Final scale rate"
                ),
                min: 0,
                step: 0.1,
              })
            );
          }

          // Animate once toggle (not for scale types)
          if (!isScaleType(animType)) {
            controls.push(
              el(ToggleControl, {
                key: "animateOnce",
                label: __("Animate once", "brandy"),
                checked: !!displayAnimation.animateOnce,
                onChange: function (value) {
                  updateAnimation(attributes, setAttributes, {
                    animateOnce: value,
                  });
                },
              })
            );
          }
        }

        return el(
          Fragment,
          null,
          el(BlockEdit, props),
          isSelected &&
            el(
              InspectorControls,
              null,
              el(
                PanelBody,
                { title: "Display Animation", initialOpen: false },
                controls
              )
            )
        );
      };
    }, "displayAnimationControls")
  );
})();
