class CorpusAnalysisApp {
  constructor(corpusId) {
    this.data = {};

    // HTML elements
    this.elements = {
      container: document.querySelector('#corpus-analysis-app-container'),
      extensionTabs: document.querySelector('#corpus-analysis-app-extension-tabs'),
      initModal: document.querySelector('#corpus-analysis-app-init-modal'),
      initError: document.querySelector('#corpus-analysis-app-init-error'),
      initProgress: document.querySelector('#corpus-analysis-app-init-progress'),
      overview: document.querySelector('#corpus-analysis-app-overview')
    };
    // Materialize elements
    this.elements.m = {
      extensionTabs: M.Tabs.init(this.elements.extensionTabs),
      initModal: M.Modal.init(this.elements.initModal, {dismissible: false})
    };

    this.extensions = {};

    this.settings = {
      corpusId: corpusId
    };
  }

  init() {
    this.disableActionElements();
    this.elements.m.initModal.open();
    // Init data
    this.data.cQiClient = new CQiClient(this.settings.corpusId);
    this.data.cQiClient.connect()
      .then(cQiStatus => {
        return this.data.cQiClient.corpora.get(`NOPAQUE_${this.settings.corpusId}`);
      })
      .then(
        cQiCorpus => {
          this.data.corpus = {o: cQiCorpus};
          // TODO: Don't do this here
          cQiCorpus.updateDb();
          this.enableActionElements();
          for (let extension of Object.values(this.extensions)) {extension.init();}
          this.elements.m.initModal.close();
        },
        cQiError => {
          this.elements.initError.innerText = JSON.stringify(cQiError);
          this.elements.initError.classList.remove('hide');
          this.elements.initProgress.classList.add('hide');
          if ('payload' in cQiError && 'code' in cQiError.payload && 'msg' in cQiError.payload) {
            app.flash(`${cQiError.payload.code}: ${cQiError.payload.msg}`, 'error');
          }
        }
      );
    // Add event listeners
    for (let extensionSelectorElement of this.elements.overview.querySelectorAll('.extension-selector')) {
      extensionSelectorElement.addEventListener('click', () => {
        this.elements.m.extensionTabs.select(extensionSelectorElement.dataset.target);
      });
    }
  }

  registerExtension(extension) {
    if (extension.name in this.extensions) {
      console.error(`Can't register extension ${extension.name}: Already registered`);
      return;
    }
    this.extensions[extension.name] = extension;
    if ('cQiClient' in this.data && this.data.cQiClient.connected) {extension.init();}
  }

  disableActionElements() {
    let actionElements = this.elements.container.querySelectorAll('.corpus-analysis-action');
    for (let actionElement of actionElements) {
      if (actionElement.nodeName === 'INPUT') {
        actionElement.disabled = true;
      } else if (actionElement.nodeName === 'SELECT') {
        actionElement.parentNode.querySelector('input.select-dropdown').disabled = true;
      } else {
        actionElement.classList.add('disabled');
      }
    }
  }

  enableActionElements() {
    let actionElements = this.elements.container.querySelectorAll('.corpus-analysis-action');
    for (let actionElement of actionElements) {
      if (actionElement.nodeName === 'INPUT') {
        actionElement.disabled = false;
      } else if (actionElement.nodeName === 'SELECT') {
        actionElement.parentNode.querySelector('input.select-dropdown').disabled = false;
      } else {
        actionElement.classList.remove('disabled');
      }
    }
  }
}
