/**
 * @module modules/job-search-sk
 * @description <h2><code>job-search-sk</code></h2>
 *
 * Provides UI for searching the jobs in the DB.
 */
import { define } from 'elements-sk/define';
import { html } from 'lit-html';
import { ElementSk } from '../../../infra-sk/modules/ElementSk';
import { ParamSet, toParamSet, fromParamSet } from 'common-sk/modules/query';
import {
  TaskSchedulerService,
  SearchJobsResponse,
  SearchJobsRequest,
  Job,
  JobStatus,
} from '../rpc';
import 'elements-sk/icon/delete-icon-sk';
import 'elements-sk/styles/buttons';
import 'elements-sk/styles/table';
import { $$ } from 'common-sk/modules/dom';

// Names and types of search terms.
interface DisplaySearchTerm {
  label: string;
  type: string;
}

// TODO(borenet): Find a way not to duplicate the contents of SearchJobRequest.
const searchTerms: { [key: string]: DisplaySearchTerm } = {
  name: { label: 'Name', type: 'text' },
  repo: { label: 'Repo', type: 'text' },
  revision: { label: 'Revision', type: 'text' },
  issue: { label: 'Issue', type: 'text' },
  patchset: { label: 'Patchset', type: 'text' },
  buildbucketBuildId: { label: 'Buildbucket Build ID', type: 'text' },
  isForce: { label: 'Manually Triggered', type: 'checkbox' },
  status: { label: 'Status', type: 'text' },
  timeStart: { label: 'Start Time', type: 'datetime-local' },
  timeEnd: { label: 'End Time', type: 'datetime-local' },
};

// Display parameters for job results.
interface DisplayJobResult {
  label: string;
  class: string;
}

const jobStatusToLabelAndClass: { [key: string]: DisplayJobResult } = {
  [JobStatus.JOB_STATUS_IN_PROGRESS]: {
    label: 'in progress',
    class: 'bg-in-progress',
  },
  [JobStatus.JOB_STATUS_SUCCESS]: {
    label: 'succeeded',
    class: 'bg-success',
  },
  [JobStatus.JOB_STATUS_FAILURE]: {
    label: 'failed',
    class: 'bg-failure',
  },
  [JobStatus.JOB_STATUS_MISHAP]: {
    label: 'mishap',
    class: 'bg-mishap',
  },
  [JobStatus.JOB_STATUS_CANCELED]: {
    label: 'canceled',
    class: 'bg-canceled',
  },
};

interface SearchTerm {
  key: string;
  value: string;
}

export class JobSearchSk extends ElementSk {
  private static template = (ele: JobSearchSk) => html`
    <div class="container">
      <table class="searchTerms">
        ${Array.from(ele.searchTerms.values()).map(
          (term: SearchTerm) => html`
        <tr class="searchTerms">
          <th>
            <label for="${term.key}">
              ${searchTerms[term.key]!.label}
            </label>
          </th>
          <td>
            <input
                .id="${term.key}"
                .type="${searchTerms[term.key]!.type}"
                .value="${term.value}"
                ?checked="${
                  searchTerms[term.key]!.type == 'checkbox' &&
                  term.value == 'true'
                }"
                @change="${(ev: Event) => {
                  const input = (<HTMLInputElement>ev.target)!;
                  if (searchTerms[term.key]!.type == 'checkbox') {
                    term.value = input.checked ? 'true' : 'false';
                  } else {
                    term.value = input.value;
                  }
                  ele.updateQuery();
                }}"
                >
            </input>
          </td>
          <td>
            <button class="delete" @click="${() => {
              ele.searchTerms.delete(term.key);
              ele._render();
              ele.updateQuery();
            }}">
              <delete-icon-sk></delete-icon-sk>
            </button>
        </tr>
      `
        )}
        <tr class="searchTerms">
          <td>
            <select
              @change="${(ev: Event) => {
                const select = <HTMLSelectElement>ev.target!;
                const selected = select.value;
                ele.searchTerms.set(selected, {
                  key: select.value,
                  value: '',
                });
                select.selectedIndex = 0;
                ele._render();
                ele.updateQuery();
                // Auto-focus the new input field.
                const inp = $$<HTMLInputElement>('#' + selected, ele)!;
                console.log(inp);
                inp?.focus();
              }}"
            >
              <option disabled selected>Add Search Term</option>
              ${Object.entries(searchTerms)
                .filter(([key, _]) => !ele.searchTerms.get(key))
                .map(
                  ([key, term]) => html`
                    <option .value="${key}">${term.label}</option>
                  `
                )}
            </select>
          </td>
          <td></td>
          <td>
            <button class="search" @click="${ele.search}">Search</button>
          </td>
        </tr>
      </table>
    </div>
    ${ele.results && ele.results.length > 0
      ? html`
          <div class="container">
            <table>
              <tr>
                <th>ID</th>
                <th>Name</th>
                <th>Repo</th>
                <th>Revision</th>
                <th>Codereview Link</th>
                <th>Status</th>
                <th>Manually Triggered</th>
                <th>Created At</th>
                <th>
                  <button class="cancel" @click="${ele.cancelAll}">
                    <delete-icon-sk></delete-icon-sk>
                    Cancel All
                  </button>
                </th>
              </tr>

              ${ele.results.map(
                (job: Job) => html`
                  <tr>
                    <td>
                      <a href="/job/${job.id}" target="_blank">${job.id}</a>
                    </td>
                    <td>${job.name}</td>
                    <td>
                      <a href="${job.repoState?.repo}" target="_blank">
                        ${job.repoState?.repo}
                      </a>
                    </td>
                    <td>
                      <a
                        href="${job.repoState!.repo}/+show/${job.repoState!
                          .revision}"
                        target="_blank"
                      >
                        ${job.repoState!.revision.substring(0, 12)}
                      </a>
                    </td>
                    <td>
                      ${job.repoState?.patch?.issue &&
                      job.repoState?.patch?.patchset &&
                      job.repoState?.patch?.server
                        ? html`
                            <a
                              href="${job.repoState?.patch?.server}/c/${job
                                .repoState?.patch?.issue}/${job.repoState?.patch
                                ?.patchset}"
                              target="_blank"
                              >${job.repoState?.patch?.server}/c/${job.repoState
                                ?.patch?.issue}/${job.repoState?.patch
                                ?.patchset}
                            </a>
                          `
                        : html``}
                    </td>
                    <td class="${jobStatusToLabelAndClass[job.status]!.class}">
                      ${jobStatusToLabelAndClass[job.status]!.label}
                    </td>
                    <td>${job.isForce ? 'true' : 'false'}</td>
                    <td>${job.createdAt}</td>
                    <td>
                      ${job.status === JobStatus.JOB_STATUS_IN_PROGRESS
                        ? html`
                            <button
                              class="cancel"
                              @click="${() => ele.cancel(job)}"
                            >
                              <delete-icon-sk></delete-icon-sk>
                              Cancel
                            </button>
                          `
                        : html``}
                    </td>
                  </tr>
                `
              )}
            </table>
          </div>
        `
      : html``}
  `;

  private results: Job[] = [];
  private _rpc: TaskSchedulerService | null = null;
  private searchTerms: Map<string, SearchTerm> = new Map();

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

  get rpc(): TaskSchedulerService | null {
    return this._rpc;
  }

  set rpc(rpc: TaskSchedulerService | null) {
    this._rpc = rpc;
    if (this.searchTerms.size > 0) {
      this.search();
    }
  }

  connectedCallback() {
    super.connectedCallback();
    if (window.location.search) {
      const params = toParamSet(window.location.search.substring(1));
      Object.entries(params).forEach((entry: [string, string[]]) => {
        const key = entry[0];
        const value = entry[1][0]; // Just take the first one.
        this.searchTerms.set(key, {
          key: key,
          value: value,
        });
      });
      if (this.rpc) {
        this.search();
      }
    }
    this._render();
  }

  private updateQuery() {
    const params: ParamSet = {};
    this.searchTerms.forEach((term: SearchTerm) => {
      params[term.key] = [term.value];
    });
    const newUrl =
      window.location.href.split('?')[0] + '?' + fromParamSet(params);
    window.history.replaceState('', '', newUrl);
  }

  private search() {
    const req: SearchJobsRequest = {
      buildbucketBuildId: parseInt(
        this.searchTerms.get('buildbucketBuildId')?.value || '0'
      ),
      hasBuildbucketBuildId: !!this.searchTerms.get('buildbucketBuildId'),
      isForce: this.searchTerms.get('isForce')?.value === 'true',
      hasIsForce: !!this.searchTerms.get('isForce'),
      issue: this.searchTerms.get('issue')?.value || '',
      hasIssue: !!this.searchTerms.get('issue'),
      name: this.searchTerms.get('name')?.value || '',
      hasName: !!this.searchTerms.get('name'),
      patchset: this.searchTerms.get('patchset')?.value || '',
      hasPatchset: !!this.searchTerms.get('patchset'),
      repo: this.searchTerms.get('repo')?.value || '',
      hasRepo: !!this.searchTerms.get('repo'),
      revision: this.searchTerms.get('revision')?.value || '',
      hasRevision: !!this.searchTerms.get('revision'),
      status: (this.searchTerms.get('status')?.value || '') as JobStatus,
      hasStatus: !!this.searchTerms.get('status'),
      timeEnd: this.searchTerms.get('timeEnd')?.value || '',
      hasTimeEnd: !!this.searchTerms.get('timeEnd'),
      timeStart: this.searchTerms.get('timeStart')?.value || '',
      hasTimeStart: !!this.searchTerms.get('timeStart'),
    };
    this.rpc!.searchJobs(req as SearchJobsRequest).then(
      (resp: SearchJobsResponse) => {
        this.results = resp.jobs!;
        this._render();
      }
    );
  }

  private cancel(job: Job) {
    this.rpc!.cancelJob({ id: job.id }).then(() => {
      const result = this.results.find((result: Job) => result.id == job.id);
      if (result) {
        result.status = JobStatus.JOB_STATUS_CANCELED;
        this._render();
      }
    });
  }

  private cancelAll() {
    this.results.forEach((job: Job) => {
      if (job.status == JobStatus.JOB_STATUS_IN_PROGRESS) {
        this.cancel(job);
      }
    });
  }
}

define('job-search-sk', JobSearchSk);
