(function () {
  /**
   * Generate a looped SVG wave mask URL with `count` full cycles.
   * Each cycle = one peak (y=0) + one trough via cubic bezier segments,
   * mirroring the PHP build_wave_styles logic exactly.
   */
  function buildMaskUrl(amp, count) {
    var h = amp * 2 + 4;
    var midY = (h * 0.4).toFixed(1);
    var troughY = (h * 0.8).toFixed(1);
    var segW = 1440 / (count * 2);

    var path = "M0," + midY;
    for (var i = 0; i < count * 2; i++) {
      var cp1x = (i * segW + segW * 0.33).toFixed(1);
      var cp2x = (i * segW + segW * 0.67).toFixed(1);
      var endX = ((i + 1) * segW).toFixed(1);
      var targetY = i % 2 === 0 ? "0" : troughY;
      path +=
        " C" +
        cp1x +
        "," +
        targetY +
        " " +
        cp2x +
        "," +
        targetY +
        " " +
        endX +
        "," +
        midY;
    }
    path += " L1440," + h + " L0," + h + " Z";

    var svg =
      '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 ' +
      h +
      '" preserveAspectRatio="none"><path d="' +
      path +
      '" fill="black"/></svg>';
    return "url(data:image/svg+xml," + encodeURIComponent(svg) + ")";
  }

  // ── 1. Register custom attributes ────────────────────────────────────────
  wp.hooks.addFilter(
    "blocks.registerBlockType",
    "brandy/separator-wave-attrs",
    function (settings) {
      if (settings.name !== "core/separator") return settings;
      settings.attributes = Object.assign({}, settings.attributes, {
        waveColor: { type: "string", default: "#000000" },
        waveRipple: { type: "number", default: 50 },
        waveCount: { type: "number", default: 4 },
      });
      return settings;
    },
  );

  // ── 2. Single BlockEdit HOC: style injection + InspectorControls ─────────
  wp.hooks.addFilter(
    "editor.BlockEdit",
    "brandy/separator-wave",
    wp.compose.createHigherOrderComponent(function (BlockEdit) {
      return function (props) {
        var name = props.name;
        var attributes = props.attributes;
        var setAttributes = props.setAttributes;
        var clientId = props.clientId;

        var isWave =
          name === "core/separator" &&
          typeof attributes.className === "string" &&
          attributes.className.includes("is-style-wave");

        React.useEffect(
          function () {
            var styleId = "brandy-wave-" + clientId;

            // WordPress 6.3+ renders the editor canvas inside an iframe.
            // Find which document hosts the block so styles are injected there.
            function getBlockDoc() {
              var sel = '[data-block="' + clientId + '"]';
              if (document.querySelector(sel)) return document;
              var frames = document.getElementsByTagName("iframe");
              for (var i = 0; i < frames.length; i++) {
                try {
                  var d = frames[i].contentDocument;
                  if (d && d.querySelector(sel)) return d;
                } catch (e) {}
              }
              return document;
            }

            var doc = getBlockDoc();
            var styleEl = doc.getElementById(styleId);

            if (!isWave) {
              if (styleEl) styleEl.remove();
              return;
            }

            var amp = Math.max(20, Math.min(120, attributes.waveRipple || 50));
            var count = Math.max(1, Math.min(10, attributes.waveCount || 4));
            var h = amp * 2 + 4;
            var color = attributes.waveColor || "#000000";

            // Modern Gutenberg: <hr data-block="…"> — the hr IS the block root.
            // Older Gutenberg:  <div data-block="…"><hr/></div>.
            var styles =
              "border:none!important;border-top:none!important;outline:none!important;" +
              "background-color:" +
              color +
              "!important;" +
              "height:" +
              h +
              "px!important;" +
              "-webkit-mask-image:" +
              buildMaskUrl(amp, count) +
              ";" +
              "mask-image:" +
              buildMaskUrl(amp, count) +
              ";" +
              "-webkit-mask-size:100% 100%;mask-size:100% 100%;" +
              "-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;" +
              "width:100%!important;max-width:100%!important;" +
              "margin-left:0!important;margin-right:0!important";
            var css =
              'hr[data-block="' +
              clientId +
              '"]{' +
              styles +
              "}" +
              '[data-block="' +
              clientId +
              '"] hr{' +
              styles +
              "}";

            if (!styleEl) {
              styleEl = doc.createElement("style");
              styleEl.id = styleId;
              doc.head.appendChild(styleEl);
            }
            styleEl.textContent = css;
          },
          [
            isWave,
            attributes.waveRipple,
            attributes.waveColor,
            attributes.waveCount,
            clientId,
          ],
        );

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

        return React.createElement(
          wp.element.Fragment,
          null,
          React.createElement(BlockEdit, props),
          React.createElement(
            wp.blockEditor.InspectorControls,
            null,
            React.createElement(
              wp.components.PanelBody,
              {
                title: wp.i18n.__("Wave Settings", "brandy"),
                initialOpen: true,
              },
              React.createElement(
                "div",
                { style: { marginBottom: "16px" } },
                React.createElement(
                  "p",
                  { style: { marginBottom: "8px", fontWeight: 600 } },
                  wp.i18n.__("Color", "brandy"),
                ),
                React.createElement(wp.blockEditor.ColorPalette, {
                  value: attributes.waveColor,
                  onChange: function (value) {
                    setAttributes({ waveColor: value || "#000000" });
                  },
                  clearable: false,
                }),
              ),
              React.createElement(wp.components.RangeControl, {
                label: wp.i18n.__("Wave cycles", "brandy"),
                value:
                  attributes.waveCount !== undefined ? attributes.waveCount : 4,
                onChange: function (value) {
                  setAttributes({ waveCount: value });
                },
                min: 1,
                max: 10,
                __nextHasNoMarginBottom: true,
                __next40pxDefaultSize: true,
              }),
              React.createElement(wp.components.RangeControl, {
                label: wp.i18n.__("Wave height", "brandy"),
                value:
                  attributes.waveRipple !== undefined
                    ? attributes.waveRipple
                    : 50,
                onChange: function (value) {
                  setAttributes({ waveRipple: value });
                },
                min: 20,
                max: 120,
                __nextHasNoMarginBottom: true,
                __next40pxDefaultSize: true,
              }),
            ),
          ),
        );
      };
    }, "BrandyWaveSeparator"),
  );
})();
