/**
 * @fileoverview A custom element that loads the CT pending tasks queue and
 * displays it as a table.
 */

import '../../../elements-sk/modules/icons/delete-icon-sk';
import '../../../elements-sk/modules/icons/cancel-icon-sk';
import '../../../elements-sk/modules/icons/check-circle-icon-sk';
import '../../../elements-sk/modules/icons/help-icon-sk';
import '../../../elements-sk/modules/toast-sk';

import { html } from 'lit/html.js';
import { $$, DomReady } from '../../../infra-sk/modules/dom';
import { fromObject } from '../../../infra-sk/modules/query';
import { jsonOrThrow } from '../../../infra-sk/modules/jsonOrThrow';
import { define } from '../../../elements-sk/modules/define';
import { errorMessage } from '../../../elements-sk/modules/errorMessage';

import { ElementSk } from '../../../infra-sk/modules/ElementSk';
import {
  getFormattedTimestamp,
  taskDescriptors,
  getTimestamp,
  getCtDbTimestamp,
  TaskDescriptor,
} from '../ctfe_utils';

import { CommonCols, DeleteTaskRequest, GetTasksResponse } from '../json';

function hideDialog(e: Event) {
  const classList = (e.target as HTMLElement).classList;
  if (classList.contains('dialog-background')) {
    classList.add('hidden');
  }
}

function formatTask(task: CommonCols) {
  return JSON.stringify(task, null, 4);
}

export class TaskQueueSk extends ElementSk {
  private _pendingTasks: CommonCols[] = [];

  private _running: boolean = false;

  constructor() {
    super(TaskQueueSk.template);
  }

  private static template = (el: TaskQueueSk) => html`
    <table class="runssummary surface-themes-sk secondary-links" id="queue">
      <tr>
        <th>Queue Position</th>
        <th>Added</th>
        <th>Task Type</th>
        <th>User</th>
        <th>Swarming Logs</th>
        <th>Request</th>
      </tr>
      ${el._pendingTasks.map((task: CommonCols, index: number) =>
        TaskQueueSk.taskRowTemplate(el, task, index)
      )}
    </table>
    ${el._pendingTasks.map((task, index) => TaskQueueSk.taskDetailDialogTemplate(task, index))}
    <toast-sk id="confirm_toast" duration="5000"></toast-sk>
  `;

  private static taskRowTemplate = (el: TaskQueueSk, task: CommonCols, index: number) =>
    html` <tr>
      <td class="nowrap">
        ${index + 1}
        <delete-icon-sk
          title="Delete this task"
          alt="Delete"
          ?hidden=${!task.can_delete}
          @click=${() => el.confirmDeleteTask(index)}></delete-icon-sk>
      </td>
      <td>
        ${getFormattedTimestamp(task.ts_added)}
        ${task.future_date
          ? html`</br><span class=error-themes-sk>(scheduled in the future)</span>`
          : ''}
      </td>
      <td>${task.task_type}</td>
      <td>${task.username}</td>
      <td class="nowrap">
        ${task.future_date
          ? html`N/A`
          : task.swarming_logs
            ? html`<a href="${task.swarming_logs}" rel="noopener" target="_blank">Swarming Logs</a>`
            : html`No Swarming Logs`}
      </td>
      <td class="nowrap">
        <a href="#" class="details" @click=${() => el.showDetailsDialog(index)}>Task Details</a>
      </td>
    </tr>`;

  private static taskDetailDialogTemplate = (task: CommonCols, index: number) => html`
    <div
      id=${`detailsDialog${index}`}
      class="dialog-background hidden overlay-themes-sk"
      @click=${hideDialog}>
      <div class="dialog-content surface-themes-sk">
        <pre>${formatTask(task)}</pre>
      </div>
    </div>
  `;

  connectedCallback(): void {
    super.connectedCallback();
    if (this._running) {
      return;
    }
    this._running = true;
    // We wait for everything to load so scaffolding event handlers are
    // attached.
    DomReady.then(() => {
      this.dispatchEvent(new CustomEvent('begin-task', { bubbles: true }));
      this._render();
      this.loadTaskQueue().then(() => {
        this._render();
        this._running = false;
        this.dispatchEvent(new CustomEvent('end-task', { bubbles: true }));
      });
    });
  }

  showDetailsDialog(index: number): void {
    ($$(`#detailsDialog${index}`, this) as HTMLElement).classList.remove('hidden');
  }

  // Dispatch requests to fetch tasks in queue. Returns a promise that resolves
  // when all task data fetching/updating is complete.
  loadTaskQueue(): Promise<void[]> {
    this._pendingTasks = [];
    // TODO(rmistry):
    // This should really use the task_common.QueryParams type and
    // the parameters should be POST'ed instead of sent via queryStr.
    const queryParams = {
      size: 100,
      not_completed: true,
      include_future_runs: false,
    };
    let queryStr = `?${fromObject(queryParams)}`;
    const allPromises = [];
    for (const obj of taskDescriptors) {
      allPromises.push(
        fetch(obj.get_url + queryStr, { method: 'POST' })
          .then(jsonOrThrow)
          .then((json) => {
            this.updatePendingTasks(json, obj);
          })
          .catch(errorMessage)
      );
    }

    // Find all tasks scheduled in the future.
    const futureQueryParams = {
      include_future_runs: true,
    };
    queryStr = `?${fromObject(futureQueryParams)}`;
    for (const obj of taskDescriptors) {
      allPromises.push(
        fetch(obj.get_url + queryStr, { method: 'POST' })
          .then(jsonOrThrow)
          .then((json) => {
            this.updatePendingTasks(json, obj);
          })
          .catch(errorMessage)
      );
    }
    return Promise.all(allPromises);
  }

  // Add responses to pending tasks list.
  updatePendingTasks(json: GetTasksResponse, taskDescriptor: TaskDescriptor): void {
    const tasks = json.data;
    for (let i = 0; i < tasks.length; i++) {
      const task = tasks[i] as CommonCols;
      task.can_delete = json.permissions![i].DeleteAllowed;
      task.id = json.ids![i];
      task.task_type = taskDescriptor.type;
      task.get_url = taskDescriptor.get_url;
      task.delete_url = taskDescriptor.delete_url;
      // Check if this is a completed task set to repeat.
      if (task.repeat_after_days !== 0 && task.task_done) {
        // Calculate the future date.
        const timestamp = getTimestamp(task.ts_added);
        timestamp.setDate(timestamp.getDate() + task.repeat_after_days);
        task.future_date = true;
        task.ts_added = +getCtDbTimestamp(new Date(timestamp));
      }
    }
    this._pendingTasks = this._pendingTasks.concat(tasks);
    // Sort pending tasks according to TsAdded.
    this._pendingTasks.sort((a, b) => a.ts_added - b.ts_added);
  }

  confirmDeleteTask(index: number): void {
    const confirmed = window.confirm('Delete this task?');
    if (confirmed) {
      this.deleteTask(index);
    }
  }

  deleteTask(index: number): void {
    const pendingTask = this._pendingTasks[index];
    const params: DeleteTaskRequest = { id: pendingTask.id };
    // params.id = pendingTask.Id;
    fetch(pendingTask.delete_url, {
      method: 'POST',
      body: JSON.stringify(params),
    })
      .then((res) => {
        if (res.ok) {
          this._pendingTasks.splice(index, 1);
          window.alert(`Deleted ${pendingTask.task_type} task ${pendingTask.id}`);
          return;
        }
        // Non-OK status. Read the response and punt it to the catch.
        res.text().then((text) => {
          throw new Error(`Failed to delete the task: ${text}`);
        });
      })
      .then(() => {
        this._render();
      })
      .catch(errorMessage);
  }
}

define('task-queue-sk', TaskQueueSk);
