/**
 * @file
 * Transcode form JavaScript.
 */

(function (Drupal, once) {
  'use strict';

  /**
   * Enhances the transcode form.
   */
  Drupal.behaviors.ffmpegTranscodeForm = {
    attach: function (context) {
      const forms = once('ffmpeg-transcode-form', '.ffmpeg-media-info', context);

      if (!forms.length) {
        return;
      }

      const clearCheckbox = document.getElementById('edit-clear-existing');
      const submitButton = document.getElementById('edit-submit');
      const profileSelect = document.getElementById('edit-profile');

      if (submitButton) {
        var clickHandler = function (e) {
          // Get selected profile name.
          var profileName = Drupal.t('default');
          if (profileSelect) {
            var selectedOption = profileSelect.options[profileSelect.selectedIndex];
            if (selectedOption) {
              profileName = selectedOption.textContent.trim();
            }
          }

          // Confirm when clearing existing outputs via accessible dialog.
          if (clearCheckbox && clearCheckbox.checked) {
            e.preventDefault();
            _showConfirmDialog(profileName, function () {
              submitButton.removeEventListener('click', clickHandler);
              submitButton.click();
            });
            return false;
          }

          // Add loading state to prevent double-submit.
          // Use setTimeout(0) to defer disabling until after the browser
          // has initiated the form submission. Disabling synchronously in
          // the click handler causes Chromium to abort the submission
          // because the triggering element is no longer submittable.
          setTimeout(function () {
            submitButton.disabled = true;
            submitButton.classList.add('is-loading');
            submitButton.setAttribute('aria-busy', 'true');
          }, 0);

          // Re-enable after timeout in case form submission fails.
          setTimeout(function () {
            submitButton.disabled = false;
            submitButton.classList.remove('is-loading');
            submitButton.removeAttribute('aria-busy');
          }, 30000);
        };

        submitButton.addEventListener('click', clickHandler);
        // Store reference for detach cleanup.
        forms[0]._ffmpegClickHandler = clickHandler;
        forms[0]._ffmpegSubmitButton = submitButton;
      }
    },

    detach: function (context, settings, trigger) {
      if (trigger !== 'unload') {
        return;
      }

      var forms = once.remove('ffmpeg-transcode-form', '.ffmpeg-media-info', context);
      if (!forms.length) {
        return;
      }

      forms.forEach(function (form) {
        if (form._ffmpegClickHandler && form._ffmpegSubmitButton) {
          form._ffmpegSubmitButton.removeEventListener('click', form._ffmpegClickHandler);
          delete form._ffmpegClickHandler;
          delete form._ffmpegSubmitButton;
        }
      });
    }
  };

  /**
   * Shows an accessible confirmation dialog.
   *
   * @param {string} profileName - The profile name for the message.
   * @param {Function} onConfirm - Callback when user confirms.
   */
  function _showConfirmDialog(profileName, onConfirm) {
    var dialogId = 'ffmpeg-transcode-confirm-dialog';
    var titleId = dialogId + '-title';
    var bodyId = dialogId + '-body';

    var modal = document.createElement('div');
    modal.className = 'ffmpeg-queue-modal';
    modal.innerHTML =
      '<div class="ffmpeg-queue-modal__backdrop"></div>' +
      '<div class="ffmpeg-queue-modal__content" role="alertdialog" aria-modal="true" aria-labelledby="' + titleId + '" aria-describedby="' + bodyId + '" tabindex="-1">' +
        '<div class="ffmpeg-queue-modal__header">' +
          '<h4 id="' + titleId + '">' + Drupal.t('Confirm Transcode') + '</h4>' +
          '<button type="button" class="ffmpeg-queue-modal__close" aria-label="' + Drupal.t('Close') + '">' +
            '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">' +
              '<line x1="18" y1="6" x2="6" y2="18"/>' +
              '<line x1="6" y1="6" x2="18" y2="18"/>' +
            '</svg>' +
          '</button>' +
        '</div>' +
        '<div class="ffmpeg-queue-modal__body" id="' + bodyId + '">' +
          '<p>' + Drupal.t('This will delete all existing transcoded files and start a new conversion with the "@profile" profile. Continue?', {'@profile': profileName}) + '</p>' +
        '</div>' +
        '<div class="ffmpeg-queue-modal__footer">' +
          '<button type="button" class="button ffmpeg-confirm-cancel">' + Drupal.t('Cancel') + '</button>' +
          '<button type="button" class="button button--primary ffmpeg-confirm-ok">' + Drupal.t('Continue') + '</button>' +
        '</div>' +
      '</div>';

    document.body.appendChild(modal);
    document.body.classList.add('ffmpeg-queue-modal-open');

    var closeButton = modal.querySelector('.ffmpeg-queue-modal__close');
    var backdrop = modal.querySelector('.ffmpeg-queue-modal__backdrop');
    var dialog = modal.querySelector('.ffmpeg-queue-modal__content');
    var cancelButton = modal.querySelector('.ffmpeg-confirm-cancel');
    var okButton = modal.querySelector('.ffmpeg-confirm-ok');
    var previousFocus = document.activeElement instanceof HTMLElement ? document.activeElement : null;

    // Mark all other body children as inert so focus stays within the dialog.
    Array.from(document.body.children).forEach(function (child) {
      if (child !== modal) {
        child.inert = true;
      }
    });

    function cleanup() {
      document.removeEventListener('keydown', onDocumentKeydown);
    }

    function close() {
      cleanup();

      Array.from(document.body.children).forEach(function (child) {
        child.inert = false;
      });

      modal.remove();
      document.body.classList.remove('ffmpeg-queue-modal-open');

      if (previousFocus && document.contains(previousFocus)) {
        previousFocus.focus();
      }
    }

    function onDocumentKeydown(event) {
      if (event.key === 'Escape') {
        event.preventDefault();
        close();
        return;
      }

      // Focus trap: cycle Tab/Shift+Tab within the dialog.
      if (event.key === 'Tab') {
        var focusable = dialog.querySelectorAll(
          'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
        );
        if (focusable.length === 0) {
          return;
        }
        var first = focusable[0];
        var last = focusable[focusable.length - 1];

        if (event.shiftKey) {
          if (document.activeElement === first) {
            event.preventDefault();
            last.focus();
          }
        }
        else {
          if (document.activeElement === last) {
            event.preventDefault();
            first.focus();
          }
        }
      }
    }

    closeButton.addEventListener('click', close);
    cancelButton.addEventListener('click', close);
    backdrop.addEventListener('click', function (event) {
      if (event.target === backdrop) {
        close();
      }
    });
    okButton.addEventListener('click', function () {
      close();
      onConfirm();
    });

    document.addEventListener('keydown', onDocumentKeydown);

    // Focus the dialog.
    if (dialog) {
      dialog.focus();
    }
  }

})(Drupal, once);
