import { ajax, delegate } from '@utils';

addEventListener('DOMContentLoaded', () => {
  attachementPoller.deactivate();
  exportPoller.deactivate();

  const attachments = document.querySelectorAll('[data-attachment-poll-url]');
  const exports = document.querySelectorAll('[data-export-poll-url]');

  for (let { dataset } of attachments) {
    attachementPoller.add(dataset.attachmentPollUrl);
  }

  for (let { dataset } of exports) {
    exportPoller.add(dataset.exportPollUrl);
  }
});

addEventListener('attachment:update', ({ detail: { url } }) => {
  attachementPoller.add(url);
});

addEventListener('export:update', ({ detail: { url } }) => {
  exportPoller.add(url);
});

delegate('click', '[data-attachment-refresh]', (event) => {
  event.preventDefault();
  attachementPoller.check();
});

// Periodically check the state of a set of URLs.
//
// Each time the given URL is requested, the matching `show.js.erb` view is rendered,
// causing the state to be refreshed.
//
// This is used mainly to refresh attachments during the anti-virus check,
// but also to refresh the state of a pending spreadsheet export.
class RemotePoller {
  urls = new Set();
  timeout;
  checks = 0;

  constructor(settings = {}) {
    this.interval = settings.interval;
    this.maxChecks = settings.maxChecks;
  }

  get isEnabled() {
    return this.checks <= this.maxChecks;
  }

  get isActive() {
    return this.timeout !== undefined;
  }

  add(url) {
    if (this.isEnabled) {
      if (!this.isActive) {
        this.activate();
      }
      this.urls.add(url);
    }
  }

  check() {
    let urls = this.urls;
    this.reset();
    for (let url of urls) {
      // Start the request. The JS payload in the response will update the page.
      // (Errors are ignored, because background tasks shouldn't report errors to the user.)
      ajax({ url, type: 'get' }).catch(() => {});
    }
  }

  activate() {
    clearTimeout(this.timeout);
    this.timeout = setTimeout(() => {
      this.checks++;
      this.currentInterval = this.interval * 1.5;
      this.check();
    }, this.currentInterval);
  }

  deactivate() {
    this.checks = 0;
    this.currentInterval = this.interval;
    this.reset();
  }

  reset() {
    clearTimeout(this.timeout);
    this.urls = new Set();
    this.timeout = undefined;
  }
}

const attachementPoller = new RemotePoller({ interval: 3000, maxChecks: 5 });
const exportPoller = new RemotePoller({ interval: 6000, maxChecks: 10 });