/**
 * BlockPresets - Unified preset system for Brandy blocks and patterns
 *
 * Two data providers feed one modal UI:
 * 1. Registry: presets registered via brandy_register_block_preset() (PHP)
 *    → localized to window.brandyBlockPresets
 * 2. Pattern: auto-detected from metadata.patternName + categories (WP 6.3+)
 *    → fetched via select('core').getBlockPatterns()
 *
 * Both sources merge into one grid. Apply replaces block via replaceBlock().
 */
(function () {
  var el = wp.element.createElement;
  var useState = wp.element.useState;
  var useMemo = wp.element.useMemo;
  var Fragment = wp.element.Fragment;
  var __ = wp.i18n.__;
  var addFilter = wp.hooks.addFilter;
  var createHigherOrderComponent = wp.compose.createHigherOrderComponent;
  var BlockControls = wp.blockEditor.BlockControls;
  var BlockPreview = wp.blockEditor.BlockPreview;
  var ToolbarGroup = wp.components.ToolbarGroup;
  var ToolbarButton = wp.components.ToolbarButton;
  var Modal = wp.components.Modal;
  var Button = wp.components.Button;
  var useSelect = wp.data.useSelect;
  var useDispatch = wp.data.useDispatch;
  var parse = wp.blocks.parse;

  // Registry presets localized from PHP
  var registryPresets = window.brandyBlockPresets || {};

  // ── Helper functions ────────────────────────────────────────────

  /**
   * Get registered presets for a block type from PHP registry.
   */
  function getRegistryPresets(blockName) {
    return registryPresets[blockName] || [];
  }

  /**
   * Extract preset category from block metadata (pattern provider).
   * Prefers specific brandy-* categories over generic ones.
   * Falls back to pattern name prefix if only generic category exists.
   */
  function getPresetCategory(metadata) {
    if (!metadata || !metadata.patternName) return null;
    if (metadata.patternName.indexOf("brandy/") !== 0) return null;

    var categories = metadata.categories || [];
    var specific = categories.filter(function (c) {
      return c.indexOf("brandy-") === 0;
    });
    if (specific.length > 0) return specific[0];

    // Fallback: extract type from patternName
    var slug = metadata.patternName.replace("brandy/", "");
    var match = slug.match(/^(.+?)-(\d+)$/);
    var prefix = match ? match[1] : slug;
    return prefix ? "brandy-" + prefix : null;
  }

  /**
   * Find all patterns matching a category.
   * Tries category match first, falls back to name prefix.
   */
  function getMatchingPatterns(category, patternName, allPatterns) {
    if (!category || !allPatterns) return [];

    var byCategory = allPatterns.filter(function (p) {
      return p.categories && p.categories.indexOf(category) !== -1;
    });
    if (byCategory.length > 1) return byCategory;

    var slug = patternName.replace("brandy/", "");
    var match = slug.match(/^(.+?)-\d+$/);
    if (!match) return byCategory;
    var prefix = "brandy/" + match[1] + "-";
    return allPatterns.filter(function (p) {
      return p.name && p.name.indexOf(prefix) === 0;
    });
  }

  /**
   * Build modal title from category or block name.
   */
  function getModalTitle(patternCategory, blockName) {
    if (patternCategory) {
      var label = patternCategory.replace("brandy-", "").replace(/-/g, " ");
      return (
        label.replace(/\b\w/g, function (c) {
          return c.toUpperCase();
        }) +
        " " +
        __("Presets", "brandy")
      );
    }
    if (blockName) {
      var name = blockName.replace(/^.*\//, "").replace(/-/g, " ");
      return (
        name.replace(/\b\w/g, function (c) {
          return c.toUpperCase();
        }) +
        " " +
        __("Presets", "brandy")
      );
    }
    return __("Presets", "brandy");
  }

  // ── Preset icon (grid layout) ───────────────────────────────────

  var presetIcon = el(
    "svg",
    {
      xmlns: "http://www.w3.org/2000/svg",
      viewBox: "0 0 24 24",
      width: 24,
      height: 24,
      fill: "currentColor",
    },
    el("path", {
      d: "M4 4h7v7H4V4zm9 0h7v7h-7V4zM4 13h7v7H4v-7zm9 0h7v7h-7v-7z",
      fillRule: "evenodd",
      clipRule: "evenodd",
    })
  );

  // ── PresetCard component ────────────────────────────────────────

  function PresetCard(props) {
    var preset = props.preset;
    var isSelected = props.isSelected;
    var isCurrent = props.isCurrent;
    var onClick = props.onClick;

    var blocks = useMemo(function () {
      return parse(preset.content || "");
    }, [preset.content]);

    var borderColor = isSelected
      ? "#0073aa"
      : isCurrent
        ? "#b0b0b0"
        : "#e0e0e0";

    var cardStyle = {
      border: "2px solid " + borderColor,
      borderRadius: "4px",
      cursor: "pointer",
      position: "relative",
      overflow: "hidden",
      background: "#fff",
      transition: "border-color 0.15s",
    };

    var previewStyle = {
      height: "160px",
      overflow: "hidden",
      pointerEvents: "none",
    };

    var title = (preset.title || "").replace(/^Brandy\s+/i, "");

    return el(
      "div",
      {
        className:
          "brandy-preset-card" +
          (isSelected ? " is-selected" : "") +
          (isCurrent ? " is-current" : ""),
        style: cardStyle,
        onClick: onClick,
        role: "button",
        tabIndex: 0,
        "aria-label": preset.title || preset.name,
        onKeyDown: function (e) {
          if (e.key === "Enter" || e.key === " ") {
            e.preventDefault();
            onClick();
          }
        },
      },
      el(
        "div",
        { style: previewStyle },
        blocks.length > 0 &&
          el(BlockPreview, {
            blocks: blocks,
            viewportWidth: preset.viewportWidth || 1200,
          })
      ),
      el(
        "div",
        { style: { padding: "12px" } },
        el(
          "div",
          {
            style: {
              fontWeight: 600,
              fontSize: "12px",
              textTransform: "uppercase",
            },
          },
          title
        ),
        preset.description &&
          el(
            "div",
            {
              style: {
                fontSize: "11px",
                color: "#757575",
                marginTop: "4px",
              },
            },
            preset.description
          )
      ),
      isSelected &&
        el(
          "div",
          {
            style: {
              position: "absolute",
              top: "8px",
              right: "8px",
              width: "24px",
              height: "24px",
              borderRadius: "50%",
              background: "#0073aa",
              color: "#fff",
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
              fontSize: "14px",
              lineHeight: 1,
            },
          },
          "\u2713"
        )
    );
  }

  // ── PresetsModal component ──────────────────────────────────────

  function PresetsModal(props) {
    var clientId = props.clientId;
    var blockName = props.blockName;
    var metadata = props.metadata;
    var registryItems = props.registryItems;
    var patternCategory = props.patternCategory;
    var onClose = props.onClose;

    var selectedState = useState(null);
    var selectedName = selectedState[0];
    var setSelectedName = selectedState[1];

    // Fetch pattern data (only needed if patternCategory exists)
    var allPatterns = useSelect(function (select) {
      if (!patternCategory) return [];
      return select("core").getBlockPatterns();
    }, [patternCategory]);

    // Merge registry + pattern presets into one array
    var allPresets = useMemo(
      function () {
        var items = [];

        // Add registry presets
        registryItems.forEach(function (preset) {
          items.push({
            name: preset.name,
            title: preset.title || preset.name,
            description: preset.description || "",
            content: preset.content,
            viewportWidth: preset.viewportWidth || 1200,
          });
        });

        // Add pattern presets
        if (patternCategory && metadata && metadata.patternName) {
          var patternItems = getMatchingPatterns(
            patternCategory,
            metadata.patternName,
            allPatterns || []
          );
          patternItems.forEach(function (p) {
            items.push({
              name: p.name,
              title: p.title || p.name,
              description: p.description || "",
              content: p.content,
              viewportWidth: p.viewportWidth || 1850,
            });
          });
        }

        return items;
      },
      [registryItems, patternCategory, metadata, allPatterns]
    );

    var replaceBlock = useDispatch("core/block-editor").replaceBlock;

    function handleApply() {
      if (!selectedName) return;
      var preset = allPresets.find(function (p) {
        return p.name === selectedName;
      });
      if (!preset) return;

      var blocks = parse(preset.content);
      if (blocks.length > 0) {
        replaceBlock(clientId, blocks);
      }
      onClose();
    }

    var currentPatternName = metadata ? metadata.patternName : null;

    var gridStyle = {
      display: "grid",
      gridTemplateColumns: "1fr 1fr",
      gap: "16px",
      maxHeight: "60vh",
      overflowY: "auto",
    };

    var footerStyle = {
      display: "flex",
      justifyContent: "flex-end",
      gap: "12px",
      marginTop: "20px",
      paddingTop: "16px",
      borderTop: "1px solid #e0e0e0",
    };

    return el(
      Modal,
      {
        title: getModalTitle(patternCategory, blockName),
        onRequestClose: onClose,
        className: "brandy-block-presets-modal",
        size: "large",
      },
      el(
        "p",
        {
          style: {
            marginTop: 0,
            fontSize: "11px",
            textTransform: "uppercase",
            letterSpacing: "1px",
            color: "#757575",
          },
        },
        __("Transform the layout instantly", "brandy")
      ),
      allPresets.length === 0
        ? el(
            "p",
            {
              style: {
                textAlign: "center",
                padding: "40px 0",
                color: "#757575",
              },
            },
            __("No presets available.", "brandy")
          )
        : el(
            "div",
            { style: gridStyle },
            allPresets.map(function (preset) {
              var isSelected = selectedName === preset.name;
              var isCurrent = currentPatternName === preset.name;
              return el(PresetCard, {
                key: preset.name,
                preset: preset,
                isSelected: isSelected,
                isCurrent: isCurrent,
                onClick: function () {
                  setSelectedName(preset.name);
                },
              });
            })
          ),
      el(
        "div",
        { style: footerStyle },
        el(
          Button,
          { variant: "tertiary", onClick: onClose },
          __("Cancel", "brandy")
        ),
        el(
          Button,
          {
            variant: "primary",
            onClick: handleApply,
            disabled: !selectedName || selectedName === currentPatternName,
          },
          __("Apply Preset", "brandy")
        )
      )
    );
  }

  // ── BlockPresetsToolbar component ───────────────────────────────

  function BlockPresetsToolbar(props) {
    var modalState = useState(false);
    var isModalOpen = modalState[0];
    var setIsModalOpen = modalState[1];

    var label = getModalTitle(props.patternCategory, props.blockName);

    return el(
      Fragment,
      null,
      el(
        BlockControls,
        { group: "other" },
        el(
          ToolbarGroup,
          null,
          el(ToolbarButton, {
            icon: presetIcon,
            label: label,
            onClick: function () {
              setIsModalOpen(true);
            },
          })
        )
      ),
      isModalOpen &&
        el(PresetsModal, {
          clientId: props.clientId,
          blockName: props.blockName,
          metadata: props.metadata,
          registryItems: props.registryItems,
          patternCategory: props.patternCategory,
          onClose: function () {
            setIsModalOpen(false);
          },
        })
    );
  }

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

  var addBlockPresetsControls = createHigherOrderComponent(
    function (BlockEdit) {
      return function (props) {
        if (!props.isSelected) {
          return el(BlockEdit, props);
        }

        var blockName = props.name;
        var metadata = props.attributes && props.attributes.metadata;
        var registryItems = getRegistryPresets(blockName);
        var patternCategory = getPresetCategory(metadata);

        // Need at least one source
        if (registryItems.length === 0 && !patternCategory) {
          return el(BlockEdit, props);
        }

        return el(
          Fragment,
          null,
          el(BlockEdit, props),
          el(BlockPresetsToolbar, {
            clientId: props.clientId,
            blockName: blockName,
            metadata: metadata,
            registryItems: registryItems,
            patternCategory: patternCategory,
          })
        );
      };
    },
    "addBlockPresetsControls"
  );

  // ── Register filter ─────────────────────────────────────────────

  addFilter(
    "editor.BlockEdit",
    "brandy/block-presets-controls",
    addBlockPresetsControls,
    30
  );
})();
