/**
 * @file
 * FlowDrop Schema Form Integration for Drupal
 *
 * @description
 * Provides Drupal behavior for initializing and managing SchemaForm components.
 * This script automatically mounts SchemaForm instances for elements with the
 * [data-schema-form] attribute.
 *
 * Requires the shared FlowDrop library (flowdrop_ui_components/flowdrop).
 *
 * @param {Function} once The "once" deduplication library.
 * @param {object} Drupal The Drupal API namespace.
 */

((once, Drupal) => {
  /**
   * Drupal behavior for mounting SchemaForm components
   *
   * @type {object}
   */
  Drupal.behaviors.flowdropSchemaForm = {
    /**
     * Attach behavior to schema form containers
     *
     * @param {HTMLElement} context - The context element to search within
     */
    attach(context) {
      once('flowdrop-schema-form', '[data-schema-form]', context).forEach(
        (formContainer) => {
          initializeSchemaForm(formContainer);
        },
      );
    },

    /**
     * Detach behavior and cleanup mounted components
     *
     * @param {HTMLElement} context - The context element to search within
     * @param {object} settings - Drupal settings object
     * @param {string} trigger - The trigger for detachment
     */
    detach(context, settings, trigger) {
      if (trigger !== 'unload') {
        return;
      }

      const containers = context.querySelectorAll('[data-schema-form]');
      containers.forEach((formContainer) => {
        if (
          formContainer.schemaFormInstance &&
          typeof formContainer.schemaFormInstance.destroy === 'function'
        ) {
          formContainer.schemaFormInstance.destroy();
          formContainer.schemaFormInstance = null;
        }
      });
    },
  };

  /**
   * Initialize a SchemaForm component in the given container
   *
   * @param {HTMLElement} formContainer - The container element for the form
   */
  async function initializeSchemaForm(formContainer) {
    if (formContainer.dataset.flowdropInitialized === 'true') {
      return;
    }

    // Check if shared FlowDrop library is available
    if (typeof window.FlowDrop === 'undefined') {
      showError(
        formContainer,
        'FlowDrop Library Not Available',
        'The FlowDrop library could not be loaded. Please ensure flowdrop_ui_components module is enabled.',
      );
      return;
    }

    if (typeof window.FlowDrop.mountSchemaForm !== 'function') {
      showError(
        formContainer,
        'SchemaForm mount function not available',
        'The mountSchemaForm function is not available in the FlowDrop library.',
      );
      return;
    }

    // Parse schema from data attribute
    let schema;
    try {
      const schemaStr = formContainer.dataset.schema;
      if (!schemaStr) {
        throw new Error('No schema provided');
      }
      schema = JSON.parse(schemaStr);
    } catch (error) {
      showError(
        formContainer,
        'Invalid JSON Schema',
        `Failed to parse the JSON Schema: ${error.message}`,
      );
      return;
    }

    // Parse initial values
    let values = {};
    try {
      const valuesStr = formContainer.dataset.values;
      if (valuesStr) {
        values = JSON.parse(valuesStr);
      }
    } catch (error) {
      // Bad initial-values JSON — keep the empty object and let the form
      // surface validation when the user tries to submit.
    }

    // Parse configuration
    const showActions = formContainer.dataset.showActions === 'true';
    const enableCodeEditor = formContainer.dataset.enableCodeEditor === 'true';

    // Clear loading state
    const loadingElement = formContainer.querySelector(
      '.fd-schema-form__loading',
    );
    if (loadingElement) {
      loadingElement.style.display = 'none';
    }

    // Set initialized flag immediately to prevent duplicate initialization
    formContainer.dataset.flowdropInitialized = 'true';
    try {
      // Register code editor field if enabled (async — loads CodeMirror chunk on demand)
      if (
        enableCodeEditor &&
        typeof window.FlowDrop.registerCodeEditorField === 'function'
      ) {
        await window.FlowDrop.registerCodeEditorField();
      }

      // Mount the SchemaForm component (async — lazy-loads the form chunk)
      const formInstance = await window.FlowDrop.mountSchemaForm(
        formContainer,
        {
          schema,
          values,
          showActions,
          onChange(newValues) {
            formContainer.dispatchEvent(
              new CustomEvent('flowdrop:schemaform:change', {
                detail: { formId: formContainer.id, values: newValues },
                bubbles: true,
              }),
            );

            formContainer.dataset.values = JSON.stringify(newValues);

            if (typeof Drupal.behaviors.formUpdated !== 'undefined') {
              const formElement = formContainer.closest('form');
              if (formElement) {
                formElement.classList.add('form-updated');
              }
            }
          },
          onSave(savedValues) {
            formContainer.dispatchEvent(
              new CustomEvent('flowdrop:schemaform:save', {
                detail: { formId: formContainer.id, values: savedValues },
                bubbles: true,
              }),
            );
          },
          onCancel() {
            formContainer.dispatchEvent(
              new CustomEvent('flowdrop:schemaform:cancel', {
                detail: { formId: formContainer.id },
                bubbles: true,
              }),
            );
          },
        },
      );

      formContainer.schemaFormInstance = formInstance;

      formContainer.dispatchEvent(
        new CustomEvent('flowdrop:schemaform:init', {
          detail: { formId: formContainer.id, instance: formInstance },
          bubbles: true,
        }),
      );
    } catch (error) {
      // Clear initialization flag so retry is possible
      formContainer.removeAttribute('data-flowdrop-initialized');
      showError(
        formContainer,
        'Failed to initialize form',
        `An error occurred while initializing the SchemaForm: ${error.message}`,
      );
    }
  }

  /**
   * Display an error message in the form container
   *
   * @param {HTMLElement} container - The container element
   * @param {string} title - Error title
   * @param {string} message - Error message details
   */
  function showError(container, title, message) {
    const loadingElement = container.querySelector('.fd-schema-form__loading');
    if (loadingElement) {
      loadingElement.remove();
    }

    // Clear container safely
    while (container.firstChild) {
      container.removeChild(container.firstChild);
    }

    // Build error UI with safe DOM construction
    const errorDiv = document.createElement('div');
    errorDiv.className = 'fd-schema-form__error';

    const iconDiv = document.createElement('div');
    iconDiv.className = 'fd-schema-form__error-icon';
    const svgNS = 'http://www.w3.org/2000/svg';
    const svg = document.createElementNS(svgNS, 'svg');
    svg.setAttribute('xmlns', svgNS);
    svg.setAttribute('width', '24');
    svg.setAttribute('height', '24');
    svg.setAttribute('viewBox', '0 0 24 24');
    svg.setAttribute('fill', 'none');
    svg.setAttribute('stroke', 'currentColor');
    svg.setAttribute('stroke-width', '2');
    const circle = document.createElementNS(svgNS, 'circle');
    circle.setAttribute('cx', '12');
    circle.setAttribute('cy', '12');
    circle.setAttribute('r', '10');
    svg.appendChild(circle);
    const line1 = document.createElementNS(svgNS, 'line');
    line1.setAttribute('x1', '12');
    line1.setAttribute('y1', '8');
    line1.setAttribute('x2', '12');
    line1.setAttribute('y2', '12');
    svg.appendChild(line1);
    const line2 = document.createElementNS(svgNS, 'line');
    line2.setAttribute('x1', '12');
    line2.setAttribute('y1', '16');
    line2.setAttribute('x2', '12.01');
    line2.setAttribute('y2', '16');
    svg.appendChild(line2);
    iconDiv.appendChild(svg);
    errorDiv.appendChild(iconDiv);

    const h4 = document.createElement('h4');
    h4.className = 'fd-schema-form__error-title';
    h4.textContent = Drupal.checkPlain(title);
    errorDiv.appendChild(h4);

    const p = document.createElement('p');
    p.className = 'fd-schema-form__error-message';
    p.textContent = Drupal.checkPlain(message);
    errorDiv.appendChild(p);

    container.appendChild(errorDiv);
    container.classList.add('fd-schema-form--error');
  }

  /**
   * Public API for SchemaForm
   */
  Drupal.flowdropSchemaForm = {
    getValues(formIdOrElement) {
      const container =
        typeof formIdOrElement === 'string'
          ? document.getElementById(formIdOrElement)
          : formIdOrElement;

      if (!container) {
        return null;
      }

      try {
        return JSON.parse(container.dataset.values || '{}');
      } catch (error) {
        return null;
      }
    },

    destroy(formIdOrElement) {
      const container =
        typeof formIdOrElement === 'string'
          ? document.getElementById(formIdOrElement)
          : formIdOrElement;

      if (
        container &&
        container.schemaFormInstance &&
        typeof container.schemaFormInstance.destroy === 'function'
      ) {
        container.schemaFormInstance.destroy();
        container.schemaFormInstance = null;
        container.removeAttribute('data-flowdrop-initialized');
      }
    },
  };
})(once, Drupal);
