document.addEventListener('DOMContentLoaded', function () {
  var state = {
    items: [],
    workspaceId: null,
    loading: false,
    error: '',
    openId: null,
  };

  var list = document.getElementById('async-jobs-list');
  var summary = document.getElementById('async-jobs-summary');
  var refreshButton = document.getElementById('async-jobs-refresh');
  var statusFilter = document.getElementById('async-jobs-status');

  function tKey(key, vars) {
    if (!window.t) return key;
    return t(key, vars);
  }

  function currentWorkspaceId() {
    var workspace = window.getCurrentWorkspace ? window.getCurrentWorkspace() : null;
    return workspace ? workspace.id : null;
  }

  function formatJson(value) {
    if (value === null || value === undefined) return '';
    if (typeof value === 'string') return value;
    return JSON.stringify(value, null, 2);
  }

  function formatDateTime(value) {
    if (!value) return '—';
    return new Date(value).toLocaleString();
  }

  function element(tag, className, text) {
    var node = document.createElement(tag);
    if (className) node.className = className;
    if (text !== undefined && text !== null) node.textContent = text;
    return node;
  }

  function renderEmpty(title, body) {
    list.innerHTML = '';
    var empty = element('div', 'empty-state');
    empty.appendChild(element('div', 'empty-state-title', title));
    empty.appendChild(element('div', 'empty-state-text', body));
    list.appendChild(empty);
  }

  function appendMetaItem(parent, label, value) {
    var item = element('div', 'resource-meta-item');
    item.appendChild(element('div', 'resource-meta-label', label));
    item.appendChild(element('div', 'resource-meta-value', value));
    parent.appendChild(item);
  }

  function appendDetailBlock(parent, title, value, dataResultFor) {
    var block = element('div', 'resource-detail-block');
    block.appendChild(element('div', 'resource-detail-title', title));
    var pre = element('pre', 'resource-detail-pre', value);
    if (dataResultFor) pre.setAttribute('data-result-for', dataResultFor);
    block.appendChild(pre);
    parent.appendChild(block);
  }

  function renderJobCard(item) {
    var open = state.openId === item.id;
    var card = element('div', 'resource-card');
    card.setAttribute('data-job-id', item.id);

    var header = element('div', 'resource-card-header');
    var headerMain = element('div');
    headerMain.appendChild(element('div', 'resource-card-title', item.id));
    headerMain.appendChild(element('div', 'resource-card-subtitle', tKey('async_jobs.operation', { operation: item.operation_id })));

    var pillRow = element('div', 'resource-pill-row');
    pillRow.appendChild(
      element('span', 'resource-status-pill ' + String(item.status || '').toLowerCase(), tKey('async_jobs.status.' + item.status))
    );
    headerMain.appendChild(pillRow);
    header.appendChild(headerMain);

    var actions = element('div', 'resource-card-actions');
    if (item.status === 'created' || item.status === 'running') {
      var cancelButton = element('button', 'btn-secondary', tKey('async_jobs.cancel'));
      cancelButton.setAttribute('data-action', 'cancel');
      cancelButton.setAttribute('data-job-id', item.id);
      actions.appendChild(cancelButton);
    }
    var toggleButton = element(
      'button',
      'btn-secondary',
      open ? tKey('async_jobs.hide_details') : tKey('async_jobs.show_details')
    );
    toggleButton.setAttribute('data-action', 'toggle');
    toggleButton.setAttribute('data-job-id', item.id);
    actions.appendChild(toggleButton);
    header.appendChild(actions);
    card.appendChild(header);

    var metaGrid = element('div', 'resource-meta-grid');
    appendMetaItem(metaGrid, tKey('async_jobs.meta.created'), formatDateTime(item.created_at));
    appendMetaItem(metaGrid, tKey('async_jobs.meta.updated'), formatDateTime(item.updated_at));
    appendMetaItem(metaGrid, tKey('async_jobs.meta.finished'), formatDateTime(item.finished_at));
    appendMetaItem(metaGrid, tKey('async_jobs.meta.expires'), formatDateTime(item.expires_at));
    card.appendChild(metaGrid);

    if (open) {
      appendDetailBlock(card, tKey('async_jobs.progress'), formatJson(item.progress));
      appendDetailBlock(card, tKey('async_jobs.error_preview'), formatJson(item.error));
      if (
        item.status === 'completed' ||
        item.status === 'failed' ||
        item.status === 'cancelled' ||
        item.status === 'expired'
      ) {
        appendDetailBlock(card, tKey('async_jobs.result'), tKey('async_jobs.result_loading'), item.id);
      }
    }

    return card;
  }

  function render() {
    summary.textContent = tKey('async_jobs.summary', { count: state.items.length });

    if (state.loading && state.items.length === 0) {
      renderEmpty(tKey('async_jobs.loading.title'), tKey('async_jobs.loading.body'));
      return;
    }

    if (state.error) {
      renderEmpty(tKey('async_jobs.error.title'), state.error);
      return;
    }

    if (!state.items.length) {
      renderEmpty(tKey('async_jobs.empty.title'), tKey('async_jobs.empty.body'));
      return;
    }

    list.innerHTML = '';
    state.items.forEach(function(item) {
      list.appendChild(renderJobCard(item));
    });

    list.querySelectorAll('[data-action="toggle"]').forEach(function(button) {
      button.addEventListener('click', function () {
        var jobId = this.getAttribute('data-job-id');
        state.openId = state.openId === jobId ? null : jobId;
        if (state.openId) {
          void loadDetail(jobId);
        } else {
          render();
        }
      });
    });

    list.querySelectorAll('[data-action="cancel"]').forEach(function(button) {
      button.addEventListener('click', async function () {
        try {
          var jobId = this.getAttribute('data-job-id');
          await window.CrankApi.cancelAsyncJob(state.workspaceId, jobId);
          if (window.CrankUi) {
            window.CrankUi.success(tKey('async_jobs.toast.cancel.body'), tKey('async_jobs.toast.cancel.title'));
          }
          await load();
        } catch (error) {
          if (window.CrankUi) {
            window.CrankUi.error(error.message || tKey('async_jobs.toast.cancel_error.body'), tKey('async_jobs.toast.cancel_error.title'));
          }
        }
      });
    });
  }

  async function loadResult(jobId) {
    try {
      var result = await window.CrankApi.getAsyncJobResult(state.workspaceId, jobId);
      var node = document.querySelector('[data-result-for="' + jobId + '"]');
      if (node) node.textContent = formatJson(result);
    } catch (error) {
      var failedNode = document.querySelector('[data-result-for="' + jobId + '"]');
      if (failedNode) failedNode.textContent = error.message || tKey('async_jobs.result_error');
    }
  }

  async function loadDetail(jobId) {
    var detail = await window.CrankApi.getAsyncJob(state.workspaceId, jobId);
    state.items = state.items.map(function(item) {
      return item.id === jobId ? detail : item;
    });
    render();
    if (detail.status === 'completed' || detail.status === 'failed' || detail.status === 'cancelled' || detail.status === 'expired') {
      await loadResult(jobId);
    }
  }

  async function load() {
    state.workspaceId = currentWorkspaceId();
    if (!state.workspaceId) {
      state.items = [];
      state.error = tKey('async_jobs.error.workspace');
      render();
      return;
    }

    state.loading = true;
    state.error = '';
    render();

    try {
      var response = await window.CrankApi.listAsyncJobs(state.workspaceId, {
        status: statusFilter.value || null,
        page: 1,
        page_size: 50,
      });
      state.items = response.items || [];
    } catch (error) {
      state.error = error.message || tKey('async_jobs.error.load');
    } finally {
      state.loading = false;
      render();
    }
  }

  refreshButton.addEventListener('click', load);
  statusFilter.addEventListener('change', load);
  document.addEventListener('workspace:changed', load);
  void load();
});
