/**
 * @file
 * Entity Builder UI YAML editor functionality.
 */

((Drupal, drupalSettings, once) => {
  'use strict';

  /**
   * YAML editor manager.
   */
  Drupal.ebUiYamlEditor = {
    editor: null,
    textarea: null,
    settings: null,

    /**
     * Initialize the YAML editor.
     *
     * @param {HTMLTextAreaElement} textarea
     *   The textarea element.
     * @param {object} settings
     *   Editor settings from drupalSettings.
     */
    init(textarea, settings) {
      this.textarea = textarea;
      this.settings = settings;

      if (settings.yamlEditorType === 'codemirror_cdn' && typeof CodeMirror !== 'undefined') {
        this.initCodeMirror();
      } else {
        this.initPlainTextarea();
      }

      this.initToolbarButtons();
    },

    /**
     * Initialize CodeMirror editor.
     */
    initCodeMirror() {
      this.editor = CodeMirror.fromTextArea(this.textarea, {
        mode: 'yaml',
        theme: 'default',
        lineNumbers: true,
        indentUnit: 2,
        tabSize: 2,
        indentWithTabs: false,
        lineWrapping: true,
        matchBrackets: true,
        autoCloseBrackets: true,
      });

      // Sync content back to textarea on change.
      this.editor.on('change', () => {
        this.textarea.value = this.editor.getValue();
      });

      // Set editor height.
      this.editor.setSize(null, '500px');
    },

    /**
     * Initialize plain textarea (no CodeMirror).
     */
    initPlainTextarea() {
      this.textarea.classList.add('eb-yaml-plain-editor');
    },

    /**
     * Get current YAML content.
     *
     * @return {string}
     *   The YAML content.
     */
    getContent() {
      if (this.editor) {
        return this.editor.getValue();
      }
      return this.textarea.value;
    },

    /**
     * Set YAML content.
     *
     * @param {string} content
     *   The YAML content.
     */
    setContent(content) {
      if (this.editor) {
        this.editor.setValue(content);
      } else {
        this.textarea.value = content;
      }
    },

    /**
     * Initialize toolbar buttons.
     */
    initToolbarButtons() {
      const validateBtn = document.querySelector('.eb-validate-btn');
      const previewBtn = document.querySelector('.eb-preview-btn');

      if (validateBtn) {
        validateBtn.addEventListener('click', () => this.validate());
      }

      if (previewBtn) {
        previewBtn.addEventListener('click', () => this.preview());
      }
    },

    /**
     * Validate the current YAML content.
     */
    async validate() {
      const content = this.getContent();
      if (!content.trim()) {
        this.showStatus('warning', Drupal.t('No content to validate'));
        return;
      }

      this.showStatus('loading', Drupal.t('Validating...'));

      try {
        const response = await fetch('/eb/api/validate', {
          method: 'POST',
          headers: {
            'Content-Type': 'text/plain',
            'X-Requested-With': 'XMLHttpRequest',
            'X-CSRF-Token': this.settings.csrfToken,
          },
          body: content,
        });

        const result = await response.json();

        // Update inline status.
        if (result.valid) {
          this.showStatus('success', Drupal.t('Valid (@count operations)', {
            '@count': result.operation_count || 0,
          }));
        } else {
          this.showStatus('error', Drupal.t('@count error(s)', {
            '@count': result.errors?.length || 0,
          }));
        }

        // Open the validation modal with full results.
        Drupal.ebUi.openValidationModal(result);
      } catch (error) {
        this.showStatus('error', Drupal.t('Validation request failed'));
        console.error('Validation error:', error);
      }
    },

    /**
     * Preview the current YAML content.
     */
    async preview() {
      const content = this.getContent();
      if (!content.trim()) {
        this.showStatus('warning', Drupal.t('No content to preview'));
        return;
      }

      this.showStatus('loading', Drupal.t('Generating preview...'));

      const self = this;
      const headers = {
        'Content-Type': 'text/plain',
        'X-Requested-With': 'XMLHttpRequest',
        'X-CSRF-Token': this.settings.csrfToken,
      };

      // Open the preview modal with validate-first flow.
      Drupal.ebUi.openPreviewModal({
        validateFn: () => {
          return fetch('/eb/api/validate', {
            method: 'POST',
            headers,
            body: content,
          })
            .then((response) => {
              if (!response.ok) {
                throw new Error(`HTTP ${response.status}`);
              }
              return response.json();
            })
            .then((result) => {
              if (result.valid) {
                self.showStatus('success', Drupal.t('Valid'));
              } else {
                self.showStatus('error', Drupal.t('@count error(s)', {
                  '@count': result.errors?.length || 0,
                }));
              }
              return result;
            });
        },
        previewFn: () => {
          return fetch('/eb/api/preview', {
            method: 'POST',
            headers,
            body: content,
          })
            .then((response) => {
              if (!response.ok) {
                throw new Error(`HTTP ${response.status}`);
              }
              return response.json();
            })
            .then((result) => {
              if (result.success) {
                self.showStatus('success', Drupal.t('Preview: @count operations', {
                  '@count': result.operation_count || 0,
                }));
              } else {
                self.showStatus('error', Drupal.t('Preview failed'));
              }
              return result;
            })
            .catch((error) => {
              self.showStatus('error', Drupal.t('Preview request failed'));
              throw error;
            });
        }
      });
    },

    /**
     * Show validation/preview status in inline indicator.
     *
     * @param {string} type
     *   Status type: 'success', 'error', 'warning', 'loading'.
     * @param {string} message
     *   Status message.
     */
    showStatus(type, message) {
      const statusContainer = document.querySelector('.eb-validation-status');
      if (!statusContainer) return;

      const iconEl = statusContainer.querySelector('.eb-validation-status__icon');
      const textEl = statusContainer.querySelector('.eb-validation-status__text');

      // Remove existing status classes.
      statusContainer.classList.remove('eb-validation-status--success', 'eb-validation-status--error', 'eb-validation-status--warning', 'eb-validation-status--loading');

      // Add new status class.
      statusContainer.classList.add(`eb-validation-status--${type}`);

      // Set icon.
      const icons = {
        success: '\u2713',
        error: '\u2717',
        warning: '\u26A0',
        loading: '\u27F3',
      };
      iconEl.textContent = icons[type] || '';

      // Set message.
      textEl.textContent = message;
    },
  };

  /**
   * Drupal behavior for YAML editor.
   */
  Drupal.behaviors.ebUiYamlEditor = {
    attach(context) {
      const textareas = once('eb-yaml-editor', '#eb-yaml-editor', context);

      textareas.forEach((textarea) => {
        const settings = drupalSettings.ebUi || {};
        Drupal.ebUiYamlEditor.init(textarea, settings);
      });
    },
  };

})(Drupal, drupalSettings, once);
