(() => {
  const terminalStatuses = new Set(['success', 'failed', 'partial', 'timeout', 'cancelled']);
  const dispatchingStatuses = new Set(['sending', 'running']);
  const bulkBlockedStatuses = new Set(['success', 'sending', 'running']);

  function init() {
    const table = document.querySelector('table[data-storage-key="software-jobs"]');
    if (!table) return;

    const rows = () => [...table.querySelectorAll('tbody tr[data-job-id]')];
    const activeRows = () => rows().filter(row => !terminalStatuses.has(row.dataset.jobStatus || 'created'));

    function renderRestartCell(row, status) {
      const cell = row.querySelector('[data-job-restart-cell]');
      if (!cell) return;
      const currentlyBlocked = Boolean(cell.querySelector('.muted'));
      const mustBlock = dispatchingStatuses.has(status);
      if (currentlyBlocked === mustBlock) return;

      cell.replaceChildren();
      if (mustBlock) {
        const placeholder = document.createElement('span');
        placeholder.className = 'muted';
        placeholder.textContent = '—';
        cell.appendChild(placeholder);
        return;
      }

      const form = document.createElement('form');
      form.method = 'post';
      form.action = `/jobs/${row.dataset.jobId}/restart`;
      form.className = 'inline-form';
      form.addEventListener('submit', event => {
        const message = table.dataset.restartConfirm || '';
        if (message && !window.confirm(message)) event.preventDefault();
      });
      const button = document.createElement('button');
      button.type = 'submit';
      button.className = 'button button-secondary button-small';
      button.textContent = table.dataset.restartLabel || '↻';
      form.appendChild(button);
      cell.appendChild(form);
    }

    function applyStatus(item) {
      const row = table.querySelector(`tbody tr[data-job-id="${CSS.escape(String(item.id))}"]`);
      if (!row) return;
      const status = String(item.status || 'created');
      const previous = row.dataset.jobStatus || '';
      row.dataset.jobStatus = status;

      const field = row.querySelector('[data-job-status-field]');
      if (field) {
        field.textContent = item.status_label || status;
        field.className = `job-status job-status-${status}`;
      }

      const checkbox = row.querySelector('.software-job-restart-select');
      if (checkbox) {
        const hasNode = row.dataset.jobHasNode === '1';
        checkbox.disabled = !hasNode || bulkBlockedStatuses.has(status);
        if (checkbox.disabled) checkbox.checked = false;
      }
      renderRestartCell(row, status);

      if (previous !== status) {
        window.dispatchEvent(new CustomEvent('software-job-status-changed', {detail: {row, status}}));
      }
    }

    let timer = null;
    let requestInProgress = false;
    async function refresh() {
      if (requestInProgress) return;
      const active = activeRows();
      if (!active.length) return;
      const ids = active.map(row => Number(row.dataset.jobId)).filter(Number.isInteger);
      requestInProgress = true;
      try {
        const response = await fetch('/api/software-jobs/statuses', {
          method: 'POST',
          cache: 'no-store',
          headers: {'Content-Type': 'application/json'},
          body: JSON.stringify(ids),
        });
        if (!response.ok) throw new Error(`HTTP ${response.status}`);
        const payload = await response.json();
        (payload.jobs || []).forEach(applyStatus);
        if (activeRows().length) timer = window.setTimeout(refresh, 3000);
      } catch (_) {
        timer = window.setTimeout(refresh, 5000);
      } finally {
        requestInProgress = false;
      }
    }

    if (activeRows().length) timer = window.setTimeout(refresh, 1200);
    window.addEventListener('asset-table-content-reloaded', event => {
      if (event.detail?.table !== table || !activeRows().length) return;
      if (timer) window.clearTimeout(timer);
      timer = window.setTimeout(refresh, 250);
    });
    window.addEventListener('beforeunload', () => {
      if (timer) window.clearTimeout(timer);
    }, {once: true});
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', init, {once: true});
  } else {
    init();
  }
})();
