/* global IconPicker */
/**
 * @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/
 *
 * @param {object} Drupal The Drupal API namespace.
 * @param {Function} once The "once" deduplication library.
 */

((Drupal, once) => {
  /**
   * 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.
   * @return {{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").
   * @return {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 {object}
   *
   * @prop {Function} 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);
