/**
 * @module modules/details-dialog-sk
 * @description <h2><code>details-dialog-sk</code></h2>
 *
 * @property repo {string} - The repo associated with the tasks/taskspecs/commits that will be
 * displayed.
 */
import { define } from 'elements-sk/define';
import { errorMessage } from 'elements-sk/errorMessage';
import { html, TemplateResult } from 'lit-html';
import { until } from 'lit-html/directives/until.js';
import { jsonOrThrow } from 'common-sk/modules/jsonOrThrow';
import { $$ } from 'common-sk/modules/dom';
import { ElementSk } from '../../../infra-sk/modules/ElementSk';
import { Login } from '../../../infra-sk/modules/login';
import { escapeAndLinkify } from '../../../infra-sk/modules/linkify';
import { Commit } from '../util';
import { Task, Comment } from '../rpc';
import { CommentData } from '../comments-sk/comments-sk';
import {
  logsUrl, revisionUrlTemplate, swarmingUrl, taskSchedulerUrl,
} from '../settings';

import '../comments-sk';
import 'elements-sk/styles/buttons';
import 'elements-sk/icon/close-icon-sk';
import 'elements-sk/icon/content-copy-icon-sk';
import 'elements-sk/icon/launch-icon-sk';
import '../../../infra-sk/modules/task-driver-sk';

// Type defining the text and action of the upper-right button of the dialog.
// For reverts of commits and re-running of tasks.
interface Action {
  buttonText: string;
  handler: ()=> void;
}

export class DetailsDialogSk extends ElementSk {
  // This template is essentially a title section with optional action button, an optional details
  // section, and a comments-sk section. Task, TaskSpec, and Commits set the appropriate sections
  // before rendering.
  private static template = (el: DetailsDialogSk) => html`
      <div class="dialog" @click=${(e: Event) => e.stopPropagation()}>
        <header>
          <div>${el.titleSection}</div>
          <div class=spacer></div>
          ${
            el.actionButton
              ? html`<button class="action" @click=${el.actionButton.handler}>
                  ${el.actionButton.buttonText}
                </button>`
              : html``
          }
          <button class=close @click=${() => el.close()}><close-icon-sk></close-icon-sk></button>
        </header>
        ${
          el.detailsSection
            ? [
              el.detailsSection,
              html`
                  <br />
                  <hr />
                `,
            ]
            : html``
        }
        <div>
          <comments-sk
            .commentData=${el.commentData}
            .allowAdd=${true}
            .allowDelete=${true}
            .showIgnoreFailure=${el.showCommentsIgnoreFailure}
            .showFlaky=${el.showCommentsFlaky}
            .editRights=${el.canEditComments}
          ></comments-sk>
        </div>
      </div>
    `;

  private titleSection: TemplateResult = html``;

  private detailsSection: TemplateResult | null = null;

  private actionButton: Action | null = null;

  private showCommentsIgnoreFailure: boolean = false;

  private showCommentsFlaky: boolean = false;

  private canEditComments = false;

  private _repo: string = '';

  private commentData?: CommentData;

  constructor() {
    super(DetailsDialogSk.template);
    this._upgradeProperty('repo');
  }

  connectedCallback() {
    super.connectedCallback();
    Login.then((res: any) => {
      this.canEditComments = res.Email !== '';
      this._render();
    });
    this._render();
  }

  private open() {
    this._render();
    (<HTMLElement> this).style.display = 'block';
    document.addEventListener('keydown', this.keydown);
  }

  close() {
    (<HTMLElement> this).style.display = 'none';
    document.removeEventListener('keydown', this.keydown);
  }

  private keydown = (e: KeyboardEvent) => {
    if (e.key === 'Escape') {
      this.close();
    }
  };

  // reset clears the computed templates to ensure we don't have any leftovers if switching from
  // e.g.a task view to a taskspec view.
  private reset() {
    this.actionButton = null;
    this.titleSection = html``;
    this.detailsSection = null;
    this.showCommentsFlaky = false;
    this.showCommentsIgnoreFailure = false;
    const commentInput = $$('comments-sk input-sk', this) as HTMLInputElement;
    if (commentInput) {
      commentInput.value = '';
    }
  }

  displayTask(task: Task, comments: Array<Comment>, commitsByHash: Map<string, Commit>) {
    this.reset();
    this.commentData = {
      comments: comments,
      taskId: task.id,
      commit: '',
      taskSpec: '',
      repo: this.repo,
    };
    const td = fetch(`/json/td/${task.id}`)
      .then(jsonOrThrow)
      .then((td) => html`<br /><task-driver-sk id="tdStatus" .data=${td} embedded></task-driver-sk>`);
    // We don't catch failures, since we don't want the promise to resolve (and be used below)
    // unless the task-driver-sk has data.
    this.titleSection = html`${until(
      td,
      html`
        <h3>
          <span>${task.name}</span
          ><a target="_blank" rel="noopener noreferrer" href="${logsUrl(task.swarmingTaskId)}"
            ><launch-icon-sk></launch-icon-sk>
          </a>
        </h3>
        <div>
          <table>
            <tr>
              <td>Status:</td>
              <td class=${`task-${(task.status || 'PENDING').toLowerCase()}`}>${task.status}</td>
            </tr>
            <tr>
              <td>Context:</td>
              <td>
                <a href=${this.taskUrl(task)} target="_blank" rel="noopener noreferrer">
                  View on Task Scheduler
                </a>
              </td>
            </tr>
            <tr>
              <td>This Task:</td>
              <td>
                <a
                  target="_blank"
                  rel="noopener noreferrer"
                  href="${swarmingUrl()}/task?id=${task.swarmingTaskId}"
                >
                  View on Swarming
                </a>
              </td>
            </tr>
            <tr>
              <td>Other Tasks Like This:</td>
              <td>
                <a target="_blank" rel="noopener noreferrer" href=${this.swarmingUrl(task.name)}>
                  View on Swarming
                </a>
              </td>
            </tr>
          </table>
        </div>
      `,
    )}`;

    this.detailsSection = html`
      <h3>Blamelist</h3>
      <table class="blamelist">
        ${task.commits?.map((hash: string) => {
    const commit = commitsByHash.get(hash);
    return html`
            <tr>
              <td>
                <a href="${revisionUrlTemplate(this.repo)}${hash}">${commit?.shortHash || ''}</a>
              </td>
              <td>${commit?.shortAuthor || ''}</td>
              <td>${commit?.shortSubject || ''}</td>
            </tr>
          `;
  })}
      </table>
    `;

    this.actionButton = { buttonText: 'Re-run Job', handler: () => this.rerunJob(task) };
    this.open();
  }

  displayTaskSpec(taskspec: string, comments: Comment[]) {
    this.reset();
    this.showCommentsFlaky = true;
    this.showCommentsIgnoreFailure = true;
    this.commentData = {
      comments: comments,
      taskId: '',
      commit: '',
      taskSpec: taskspec,
      repo: this.repo,
    };
    this.titleSection = html` <h3>
      <a href="${this.swarmingUrl(taskspec)}" target="_blank" rel="noopener noreferrer">
        ${taskspec}
      </a>
    </h3>`;
    this.open();
  }

  displayCommit(commit: Commit, comments: Array<Comment>) {
    this.reset();
    this.showCommentsIgnoreFailure = true;
    this.commentData = {
      comments: comments,
      taskId: '',
      commit: commit.hash,
      taskSpec: '',
      repo: this.repo,
    };
    this.titleSection = html`
      <p>
        <a
          href="${revisionUrlTemplate(this.repo)}${commit.hash}"
          target="_blank"
          rel="noopener noreferrer"
        >
          ${commit.hash}
        </a>
        <content-copy-icon-sk
          class="small-icon clickable"
          @click=${() => {
    navigator.clipboard.writeText(commit.hash);
  }}
        ></content-copy-icon-sk>
        <br />
        ${commit.author}
        <br />
        <span title="${commit.timestamp!}">${this.humanDate(commit.timestamp!)}</span>
      </p>
    `;

    this.detailsSection = html`
      <h3>${escapeAndLinkify(commit.subject)}</h3>
      <p>${escapeAndLinkify(commit.body)}</p>
    `;
    if (commit.issue) {
      this.actionButton = { buttonText: 'Revert', handler: () => this.revertCommit(commit) };
    }
    this.open();
  }

  private rerunJob(task: Task) {
    if (!task || !task.name || !task.revision) {
      errorMessage("Invalid task, can't be re-run");
    }
    // TODO(borenet): This is not correct in some cases. Now that we have a
    // link from Task to Job in the scheduler, we should be able to come up
    // with a better way to "re-open" a failed Job, essentially resetting
    // the attempt counts so that we can retry the failed task(s).
    let job = task.name;
    const uploadPrefix = 'Upload-';
    if (job.indexOf(uploadPrefix) == 0) {
      job = job.substring(uploadPrefix.length);
    }
    const url = `${taskSchedulerUrl()}/trigger?submit=true&job=${job}@${task.revision}`;
    const win = window.open(url, '_blank') as Window;
    win.focus();
  }

  private revertCommit(commit: Commit) {
    const url = commit.patchStorage === 'gerrit'
      ? `https://skia-review.googlesource.com/c/${commit.issue}/?revert`
      : `https://codereview.chromium.org/${commit.issue}/revert`;
    const win = window.open(url, '_blank') as Window;
    win.focus();
  }

  private taskUrl(task: Task) {
    const url = taskSchedulerUrl();
    if (!task || !task.id || !url) {
      return '';
    }
    return `${url}/task/${task.id}`;
  }

  private swarmingUrl(taskSpec: string) {
    return `${swarmingUrl()}/tasklist?f=sk_name%3A${taskSpec}`;
  }

  private humanDate(timestamp: string) {
    const date = new Date(timestamp);
    const str = date.toString();
    return `${date.toLocaleString()} ${str.substring(str.indexOf('('))}`;
  }

  get repo(): string {
    return this._repo;
  }

  set repo(value) {
    this._repo = value;
  }
}

define('details-dialog-sk', DetailsDialogSk);
