class Utils {
  static elementFromString(string) {
    let tmpElement = document.createElement('div');
    tmpElement.innerHTML = string.trim();
    return tmpElement.firstChild;
  }

  static buildCorpusRequest(userId, corpusId) {
    return new Promise((resolve, reject) => {
      let corpus = app.data.users[userId].corpora[corpusId];

      fetch(`/corpora/${corpus.id}/build`, {method: 'POST', headers: {Accept: 'application/json'}})
        .then(
          (response) => {
            app.flash(`Corpus "${corpus.title}" marked for building`, 'corpus');
            resolve(response);
          },
          (response) => {
            if (response.status === 403) {app.flash('Forbidden', 'error');}
            if (response.status === 404) {app.flash('Not Found', 'error');}
            if (response.status === 409) {app.flash('Conflict', 'error');}
            reject(response);
          }
        );
    });
  }

  static deleteCorpusRequest(userId, corpusId) {
    return new Promise((resolve, reject) => {
      let corpus = app.data.users[userId].corpora[corpusId];

      let modalElement = Utils.elementFromString(
        `
          <div class="modal">
            <div class="modal-content">
              <h4>Confirm job deletion</h4>
              <p>Do you really want to delete the job <b>${corpus.title}</b>? All files will be permanently deleted!</p>
            </div>
            <div class="modal-footer">
              <a class="action-button btn modal-close waves-effect waves-light" data-action="cancel">Cancel</a>
              <a class="action-button btn modal-close red waves-effect waves-light" data-action="confirm">Delete</a>
            </div>
          </div>
        `
      );
      document.querySelector('#modals').appendChild(modalElement);
      let modal = M.Modal.init(
        modalElement,
        {
          dismissible: false,
          onCloseEnd: () => {
            modal.destroy();
            modalElement.remove();
          }
        }
      );
      
      let confirmElement = modalElement.querySelector('.action-button[data-action="confirm"]');
      confirmElement.addEventListener('click', (event) => {
        let corpusTitle = corpus.title;
        fetch(`/corpora/${corpus.id}`, {method: 'DELETE', headers: {Accept: 'application/json'}})
          .then(
            (response) => {
              app.flash(`Corpus "${corpusTitle}" marked for deletion`, 'corpus');
              resolve(response);
            },
            (response) => {
              if (response.status === 403) {app.flash('Forbidden', 'error');}
              if (response.status === 404) {app.flash('Not Found', 'error');}
              reject(response);
            }
          );
      });
      modal.open();
    });
  }

  static deleteCorpusFileRequest(userId, corpusId, corpusFileId) {
    return new Promise((resolve, reject) => {
      let corpus = app.data.users[userId].corpora[corpusId];
      let corpusFile = corpus.files[corpusFileId];

      let modalElement = Utils.elementFromString(
        `
          <div class="modal">
            <div class="modal-content">
              <h4>Confirm job deletion</h4>
              <p>Do you really want to delete the job <b>${corpusFile.title}</b>? All files will be permanently deleted!</p>
            </div>
            <div class="modal-footer">
              <a class="action-button btn modal-close waves-effect waves-light" data-action="cancel">Cancel</a>
              <a class="action-button btn modal-close red waves-effect waves-light" data-action="confirm">Delete</a>
            </div>
          </div>
        `
      );
      document.querySelector('#modals').appendChild(modalElement);
      let modal = M.Modal.init(
        modalElement,
        {
          dismissible: false,
          onCloseEnd: () => {
            modal.destroy();
            modalElement.remove();
          }
        }
      );

      let confirmElement = modalElement.querySelector('.action-button[data-action="confirm"]');
      confirmElement.addEventListener('click', (event) => {
        let corpusFileTitle = corpusFile.title;
        fetch(`/corpora/${corpusId}/files/${corpusFileId}`, {method: 'DELETE', headers: {Accept: 'application/json'}})
          .then(
            (response) => {
              app.flash(`Corpus file "${corpusFileTitle}" marked for deletion`, 'corpus');
              resolve(response);
            },
            (response) => {
              if (response.status === 403) {app.flash('Forbidden', 'error');}
              if (response.status === 404) {app.flash('Not Found', 'error');}
              reject(response);
            }
          );
      });
      modal.open();
    });
  }

  static deleteJobRequest(userId, jobId) {
    return new Promise((resolve, reject) => {
      let job = app.data.users[userId].jobs[jobId];

      let modalElement = Utils.elementFromString(
        `
          <div class="modal">
            <div class="modal-content">
              <h4>Confirm job deletion</h4>
              <p>Do you really want to delete the job <b>${job.title}</b>? All files will be permanently deleted!</p>
            </div>
            <div class="modal-footer">
              <a class="action-button btn modal-close waves-effect waves-light" data-action="cancel">Cancel</a>
              <a class="action-button btn modal-close red waves-effect waves-light" data-action="confirm">Delete</a>
            </div>
          </div>
        `
      );
      document.querySelector('#modals').appendChild(modalElement);
      let modal = M.Modal.init(
        modalElement,
        {
          dismissible: false,
          onCloseEnd: () => {
            modal.destroy();
            modalElement.remove();
          }
        }
      );

      let confirmElement = modalElement.querySelector('.action-button[data-action="confirm"]');
      confirmElement.addEventListener('click', (event) => {
        let jobTitle = job.title;
        fetch(`/jobs/${job.id}`, {method: 'DELETE', headers: {Accept: 'application/json'}})
          .then(
            (response) => {
              app.flash(`Job "${jobTitle}" marked for deletion`, 'job');
              resolve(response);
            },
            (response) => {
              if (response.status === 403) {app.flash('Forbidden', 'error');}
              if (response.status === 404) {app.flash('Not Found', 'error');}
              reject(response);
            }
          );
      });
      modal.open();
    });
  }

  static getJobLogRequest(userId, jobId) {
    return new Promise((resolve, reject) => {
      let job = app.data.users[userId].jobs[jobId];

      fetch(`/jobs/${job.id}/log`, {method: 'GET', headers: {Accept: 'application/json, text/plain'}})
        .then(
          (response) => {
            resolve(response);
            return response.text();
          },
          (response) => {
            if (response.status === 403) {app.flash('Forbidden', 'error');}
            if (response.status === 404) {app.flash('Not Found', 'error');}
            reject(response);
          }
        )
        .then(
          (text) => {
            let modalElement = Utils.elementFromString(
              `
                <div class="modal">
                  <div class="modal-content">
                    <h4>Job logs</h4>
                    <pre><code>${text}</code></pre>
                  </div>
                  <div class="modal-footer">
                    <a class="btn modal-close waves-effect waves-light">Close</a>
                  </div>
                </div>
              `
            );
            document.querySelector('#modals').appendChild(modalElement);
            let modal = M.Modal.init(
              modalElement,
              {
                onCloseEnd: () => {
                  modal.destroy();
                  modalElement.remove();
                }
              }
            );
            modal.open();
          }
        );
    });
  }

  static restartJobRequest(userId, jobId) {
    return new Promise((resolve, reject) => {
      let job = app.data.users[userId].jobs[jobId];

      let modalElement = Utils.elementFromString(
        `
          <div class="modal">
            <div class="modal-content">
              <h4>Confirm job restart</h4>
              <p>Do you really want to restart the job <b>${job.title}</b>? All log and result files will be permanently deleted.</p>
            </div>
            <div class="modal-footer">
              <a class="action-button btn modal-close waves-effect waves-light" data-action="cancel">Cancel</a>
              <a class="action-button btn modal-close red waves-effect waves-light" data-action="confirm">Restart</a>
            </div>
          </div>
        `
      );
      document.querySelector('#modals').appendChild(modalElement);
      let modal = M.Modal.init(
        modalElement,
        {
          dismissible: false,
          onCloseEnd: () => {
            modal.destroy();
            modalElement.remove();
          }
        }
      );

      let confirmElement = modalElement.querySelector('.action-button[data-action="confirm"]');
      confirmElement.addEventListener('click', (event) => {
        let jobTitle = job.title;
        fetch(`/jobs/${job.id}/restart`, {method: 'POST', headers: {Accept: 'application/json'}})
          .then(
            (response) => {
              app.flash(`Job "${jobTitle}" restarted.`, 'job');
              resolve(response);
            },
            (response) => {
              if (response.status === 403) {app.flash('Forbidden', 'error');}
              if (response.status === 404) {app.flash('Not Found', 'error');}
              if (response.status === 409) {app.flash('Conflict', 'error');}
              reject(response);
            }
          );
      });
      modal.open();
    });
  }

  static deleteUserRequest(userId) {
    return new Promise((resolve, reject) => {
      let user = app.data.users[userId];

      let modalElement = Utils.elementFromString(
        `
          <div class="modal">
            <div class="modal-content">
              <h4>Confirm job deletion</h4>
              <p>Do you really want to delete the user <b>${user.username}</b>? All files will be permanently deleted!</p>
            </div>
            <div class="modal-footer">
              <a class="action-button btn modal-close waves-effect waves-light" data-action="cancel">Cancel</a>
              <a class="action-button btn modal-close red waves-effect waves-light" data-action="confirm">Delete</a>
            </div>
          </div>
        `
      );
      document.querySelector('#modals').appendChild(modalElement);
      let modal = M.Modal.init(
        modalElement,
        {
          dismissible: false,
          onCloseEnd: () => {
            modal.destroy();
            modalElement.remove();
          }
        }
      );

      let confirmElement = modalElement.querySelector('.action-button[data-action="confirm"]');
      confirmElement.addEventListener('click', (event) => {
        let userName = user.username;
        fetch(`/users/${user.id}`, {method: 'DELETE', headers: {Accept: 'application/json'}})
          .then(
            (response) => {
              app.flash(`User "${userName}" marked for deletion`);
              resolve(response);
            },
            (response) => {
              if (response.status === 403) {app.flash('Forbidden', 'error');}
              if (response.status === 404) {app.flash('Not Found', 'error');}
              reject(response);
            }
          );
      });
      modal.open();
    });
  }
}