/**
 * @file
 * Progress tracker JavaScript.
 *
 * Polls the conversion progress endpoint and auto-reloads the status page
 * when the conversion status changes (pending→processing, processing→completed/failed).
 */

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

  /**
   * Polls for progress updates on processing conversions.
   */
  Drupal.behaviors.ffmpegProgressTracker = {
    attach: function (context) {
      const progressBars = once('ffmpeg-progress-tracker', '.ffmpeg-progress--processing', context);

      if (!progressBars.length) {
        return;
      }

      const settings = drupalSettings.ffmpegMediaUi || {};
      const mediaId = settings.mediaId;
      const progressUrl = settings.progressUrl || (mediaId ? Drupal.url(`ffmpeg-media/ajax/progress/${mediaId}`) : null);
      const configuredInterval = Number(settings.refreshInterval);
      const refreshInterval = Number.isFinite(configuredInterval) && configuredInterval >= 0
        ? configuredInterval
        : 5000;
      const notificationsEnabled = Boolean(settings.showNotifications) && ('Notification' in window);

      if (!mediaId || !progressUrl || refreshInterval === 0) {
        return;
      }

      const progressBar = progressBars[0];

      var pollProgress = function () {
        fetch(progressUrl, {
          credentials: 'same-origin',
          headers: { 'Accept': 'application/json' }
        })
          .then(function (response) {
            if (!response.ok) {
              throw new Error('HTTP ' + response.status);
            }
            return response.json();
          })
          .then(function (data) {
            if (!data.success) {
              setTimeout(pollProgress, refreshInterval);
              return;
            }

            // Update progress bar.
            var progressFill = progressBar.querySelector('.ffmpeg-progress-fill');
            var progressText = progressBar.querySelector('.ffmpeg-progress-text');

            if (data.elapsed_seconds !== null && data.elapsed_seconds !== undefined && data.progress === 0) {
              if (progressFill) {
                progressFill.style.width = '100%';
                progressFill.classList.add('ffmpeg-progress-fill--indeterminate');
              }
              if (progressText) {
                var totalSec = Math.floor(data.elapsed_seconds);
                var h = Math.floor(totalSec / 3600);
                var m = Math.floor((totalSec % 3600) / 60);
                var s = totalSec % 60;
                var pad = function (n) { return n < 10 ? '0' + n : '' + n; };
                progressText.textContent = Drupal.t('Elapsed: @time', {
                  '@time': pad(h) + ':' + pad(m) + ':' + pad(s)
                });
              }
            }
            else {
              if (progressFill) {
                progressFill.style.width = data.progress + '%';
                progressFill.classList.remove('ffmpeg-progress-fill--indeterminate');
              }
              if (progressText) {
                progressText.textContent = data.progress + '%';
              }
            }

            var messageEl = progressBar.querySelector('.ffmpeg-progress-message');
            if (messageEl && data.message) {
              messageEl.textContent = data.message;
            }

            // Terminal states: reload the page to show updated outputs/errors.
            if (data.status === 'completed' || data.status === 'failed') {
              if (notificationsEnabled && Notification.permission === 'granted') {
                var title = data.status === 'completed'
                  ? Drupal.t('Video conversion complete')
                  : Drupal.t('Video conversion failed');
                var body = data.status === 'completed'
                  ? Drupal.t('Your video has been converted successfully.')
                  : Drupal.t('The video conversion has failed.');
                new Notification(title, { body: body });
              }
              window.location.reload();
              return;
            }

            setTimeout(pollProgress, refreshInterval);
          })
          .catch(function (error) {
            console.error('Progress check failed:', error);
            setTimeout(pollProgress, refreshInterval * 2);
          });
      };

      if (notificationsEnabled && Notification.permission === 'default') {
        Notification.requestPermission();
      }

      setTimeout(pollProgress, refreshInterval);
    }
  };

  /**
   * Polls for status changes on pending/idle conversions.
   *
   * When a conversion transitions from pending/none to processing,
   * the page is reloaded to show the live progress tracker.
   */
  Drupal.behaviors.ffmpegStatusWatcher = {
    attach: function (context) {
      // Only attach to pending/none states (not already processing/completed/failed).
      var watchTargets = once(
        'ffmpeg-status-watcher',
        '.ffmpeg-progress--pending, .ffmpeg-progress--none',
        context
      );

      if (!watchTargets.length) {
        return;
      }

      var settings = drupalSettings.ffmpegMediaUi || {};
      var mediaId = settings.mediaId;
      var progressUrl = settings.progressUrl || (mediaId ? Drupal.url('ffmpeg-media/ajax/progress/' + mediaId) : null);
      var configuredInterval = Number(settings.refreshInterval);
      var refreshInterval = Number.isFinite(configuredInterval) && configuredInterval >= 0
        ? configuredInterval
        : 5000;

      if (!mediaId || !progressUrl || refreshInterval === 0) {
        return;
      }

      var initialStatus = watchTargets[0].classList.contains('ffmpeg-progress--pending')
        ? 'pending'
        : 'none';

      var pollStatus = function () {
        fetch(progressUrl, {
          credentials: 'same-origin',
          headers: { 'Accept': 'application/json' }
        })
          .then(function (response) {
            if (!response.ok) {
              throw new Error('HTTP ' + response.status);
            }
            return response.json();
          })
          .then(function (data) {
            if (!data.success) {
              setTimeout(pollStatus, refreshInterval);
              return;
            }

            // Status changed — reload to show the correct UI.
            if (data.status !== initialStatus) {
              window.location.reload();
              return;
            }

            setTimeout(pollStatus, refreshInterval);
          })
          .catch(function (error) {
            console.error('Status watch failed:', error);
            setTimeout(pollStatus, refreshInterval * 2);
          });
      };

      setTimeout(pollStatus, refreshInterval);
    }
  };

})(Drupal, drupalSettings, once);
