/**
 * @file
 * Icon picker behavior for FlowDrop.
 *
 * Enhances icon textfields with the Vanilla Icon Picker library,
 * providing an interactive interface to search and select icons
 * from Material Design Icons. Creates an input-group wrapper with
 * icon preview similar to the Vanilla Icon Picker demo.
 *
 * @see https://github.com/AppoloDev/vanilla-icon-picker
 * @see https://appolodev.github.io/vanilla-icon-picker/
 */

((Drupal, once) => {
  "use strict";

  /**
   * Creates the preview wrapper structure around the input field.
   *
   * This creates a Bootstrap-style input-group with an icon preview
   * prepended to the input field, matching the demo page structure.
   *
   * @param {HTMLInputElement} textfield
   *   The textfield element to wrap.
   * @returns {{wrapper: HTMLDivElement, previewSpan: HTMLSpanElement}}
   *   Object containing the wrapper and preview span elements.
   */
  function createPreviewWrapper(textfield) {
    // Create wrapper div with input-group class.
    const wrapper = document.createElement("div");
    wrapper.className = "input-group flowdrop-icon-picker-wrapper";

    // Create icon preview span.
    const previewSpan = document.createElement("span");
    previewSpan.className = "input-group-text flowdrop-icon-preview";
    previewSpan.setAttribute("aria-hidden", "true");

    // Create placeholder icon element.
    const iconElement = document.createElement("i");
    iconElement.className = "mdi mdi-help-circle-outline flowdrop-icon-preview__icon";
    iconElement.setAttribute("aria-hidden", "true");
    previewSpan.appendChild(iconElement);

    // Insert wrapper at textfield position.
    const parent = textfield.parentNode;
    if (parent) {
      parent.insertBefore(wrapper, textfield);
    }

    // Move textfield into wrapper with preview.
    wrapper.appendChild(previewSpan);
    wrapper.appendChild(textfield);

    // Add form-control class to textfield for Bootstrap styling.
    textfield.classList.add("form-control");

    return { wrapper, previewSpan };
  }

  /**
   * Updates the icon preview with the selected icon.
   *
   * @param {HTMLSpanElement} previewSpan
   *   The span element containing the icon preview.
   * @param {string} iconName
   *   The icon name (e.g., "account", "cog"). Empty string for no icon.
   */
  function updatePreview(previewSpan, iconName) {
    const iconElement = previewSpan.querySelector(".flowdrop-icon-preview__icon");
    if (!iconElement) {
      return;
    }

    // Remove all mdi-* classes except the base mdi class.
    const classesToRemove = [];
    iconElement.classList.forEach((cls) => {
      if (cls.startsWith("mdi-")) {
        classesToRemove.push(cls);
      }
    });
    classesToRemove.forEach((cls) => iconElement.classList.remove(cls));

    // Add the new icon class, or placeholder if empty.
    if (iconName) {
      iconElement.classList.add("mdi-" + iconName);
    } else {
      iconElement.classList.add("mdi-help-circle-outline");
    }
  }

  /**
   * Extracts icon name from various formats.
   *
   * @param {string} value
   *   The icon value (e.g., "mdi:account", "mdi-account", "account").
   * @returns {string}
   *   The clean icon name (e.g., "account").
   */
  function extractIconName(value) {
    if (!value) {
      return "";
    }
    // Handle mdi:icon-name format.
    if (value.startsWith("mdi:")) {
      return value.substring(4);
    }
    // Handle mdi-icon-name format.
    if (value.startsWith("mdi-")) {
      return value.substring(4);
    }
    return value;
  }

  /**
   * Attaches the Vanilla Icon Picker to icon text fields.
   *
   * This behavior finds textfields with the "flowdrop-icon-field" class
   * and enhances them with an interactive icon picker with preview.
   *
   * @type {Drupal~behavior}
   *
   * @prop {Drupal~behaviorAttach} attach
   *   Attaches the icon picker behavior to relevant elements.
   */
  Drupal.behaviors.flowdropIconPicker = {
    attach(context) {
      // Wait for IconPicker to be available.
      if (typeof IconPicker === "undefined") {
        return;
      }

      // Find all icon fields that should be enhanced.
      const iconFields = once(
        "flowdrop-icon-picker",
        ".flowdrop-icon-field",
        context
      );

      iconFields.forEach((textfield) => {
        this.initializeIconPicker(textfield);
      });
    },

    /**
     * Initializes the icon picker for a given textfield.
     *
     * Creates the preview wrapper structure and attaches the
     * Vanilla Icon Picker with Bootstrap 5 theme.
     *
     * @param {HTMLInputElement} textfield
     *   The textfield element to enhance with the icon picker.
     */
    initializeIconPicker(textfield) {
      // Ensure the textfield has an id for accessibility.
      if (!textfield.id) {
        textfield.id = "flowdrop-icon-field-" + Math.random().toString(36).substring(2, 9);
      }

      // Create the preview wrapper structure.
      const { previewSpan } = createPreviewWrapper(textfield);

      // Get current value and set initial preview.
      const currentValue = textfield.value.trim();
      const iconName = extractIconName(currentValue);
      if (iconName) {
        updatePreview(previewSpan, iconName);
      }

      // Initialize the Vanilla Icon Picker with Bootstrap 5 theme.
      // @see https://appolodev.github.io/vanilla-icon-picker/
      const picker = new IconPicker(textfield, {
        theme: "bootstrap-5",
        iconSource: ["Material Design Icons"],
        closeOnSelect: true,
        defaultValue: iconName || null,
        i18n: {
          "input:placeholder": Drupal.t("Search icon…"),
          "text:title": Drupal.t("Select Icon"),
          "text:empty": Drupal.t("No results found…"),
          "btn:save": Drupal.t("Save")
        }
      });

      // Listen for icon selection/save events.
      picker.on("save", (icon) => {
        // Convert to mdi:icon-name format for consistency with Iconify.
        const iconValue = "mdi:" + icon.name;
        textfield.value = iconValue;

        // Update the preview icon.
        updatePreview(previewSpan, icon.name);

        // Trigger change event for form validation.
        textfield.dispatchEvent(new Event("change", { bubbles: true }));
      });

      // Also listen for manual input changes to update preview.
      textfield.addEventListener("input", () => {
        const newIconName = extractIconName(textfield.value.trim());
        updatePreview(previewSpan, newIconName);
      });
    }
  };
})(Drupal, once);
