/**
 * @module incident-sk
 * @description <h2><code>incident-sk</code></h2>
 *
 * <p>
 *   Displays a single Incident.
 * </p>
 *
 * @attr minimized {boolean} If not set then the incident is displayed in expanded
 *    mode, otherwise it is displayed in compact mode.
 *
 * @attr params {boolean} If set then the incident params are displayed, only
 *    applicable if minimized is true.
 *
 * @evt add-note Sent when the user adds a note to an incident.
 *    The detail includes the text of the note and the key of the incident.
 *
 *   <pre>
 *     detail {
 *       key: "12312123123",
 *       text: "blah blah blah",
 *     }
 *   </pre>
 *
 * @evt del-note Sent when the user deletes a note on an incident.
 *    The detail includes the index of the note and the key of the incident.
 *
 *   <pre>
 *     detail {
 *       key: "12312123123",
 *       index: 0,
 *     }
 *   </pre>
 *
 * @evt take Sent when the user wants the incident assigned to themselves.
 *    The detail includes the key of the incident.
 *
 *   <pre>
 *     detail {
 *       key: "12312123123",
 *     }
 *   </pre>
 *
 * @evt assign Sent when the user want to assign the incident to someone else.
 *    The detail includes the key of the incident.
 *
 *   <pre>
 *     detail {
 *       key: "12312123123",
 *     }
 *   </pre>
 *
 */
import { define } from '../../../elements-sk/modules/define';
import '../../../elements-sk/modules/icons/alarm-off-icon-sk';
import '../../../elements-sk/modules/icons/delete-icon-sk';
import '../../../elements-sk/modules/icons/thumbs-up-down-icon-sk';
import '../../../infra-sk/modules/clipboard-sk';
import '../silence-sk';

import { $$ } from '../../../infra-sk/modules/dom';
import { diffDate, strDuration } from '../../../infra-sk/modules/human';
import { errorMessage } from '../../../elements-sk/modules/errorMessage';
import { html, render, TemplateResult } from 'lit-html';
import { until } from 'lit-html/directives/until';
import { jsonOrThrow } from '../../../infra-sk/modules/jsonOrThrow';
import { abbr, linkify, displayNotes } from '../am';
import * as paramset from '../paramset';
import {
  Silence, Incident, Params, RecentIncidentsResponse, Note,
} from '../json';

const MAX_MATCHING_SILENCES_TO_DISPLAY = 50;

const PARAMS_TO_DISPLAY_COPY_ICON = ['abbr', 'alertname', 'app', 'bot'];

class State {
  key: string = '';

  id: string = '';

  params: Params = {};

  start: number = 0;

  last_seen: number = 0;

  active: boolean = false;

  notes: Note[] = [];
}

export class IncidentSk extends HTMLElement {
  private silences: Silence[] = [];

  private displaySilencesWithComments: boolean = false;

  private flaky: boolean = false;

  private recently_expired_silence: boolean = false;

  private state: State = {
    key: '',
    id: '',
    params: {},
    start: 0,
    last_seen: 0,
    active: false,
    notes: [],
  };

  private static template = (ele: IncidentSk) => html`
  <h2 class=${ele.classOfH2()}>${ele.state.params.alertname} ${abbr(ele.state.params.abbr)} ${ele.displayRecentlyExpired(ele.recently_expired_silence)} ${ele.displayFlakiness(ele.flaky)}</h2>
  <section class=detail>
    ${ele.actionButtons()}
    <table class=timing>
      <tr><th>Started</th><td title=${new Date(ele.state.start * 1000).toLocaleString()}>${diffDate(ele.state.start * 1000)}</td></tr>
      ${ele.lastSeen()}
      ${ele.duration()}
    </table>
    <table class=params>
      ${ele.table()}
    </table>
    ${displayNotes(ele.state.notes, ele.state.key, 'del-note')}
    <section class=addNote>
      <textarea rows=2 cols=80></textarea>
      <button @click=${ele.addNote}>Submit</button>
    </section>
    <section class=matchingSilences>
      <span class=matchingSilencesHeaders>
        <h3>Matching Silences</h3>
        <checkbox-sk ?checked=${ele.displaySilencesWithComments} @click=${ele.toggleSilencesWithComments} label="Show only silences with comments">
        </checkbox-sk>
      </span>
      ${ele.matchingSilences()}
    </section>
    <section class=history>
      <h3>History</h3>
      ${until(ele.history(), html`<div class=loading>Loading...</div>`)}
    </section>
  </section>
`;

  /** @prop incident_state An Incident. */
  get incident_state(): State { return this.state; }

  set incident_state(val: State) {
    this.state = val;
    this._render();
  }

  /** @prop incident_silences The list of active silences. */
  get incident_silences(): Silence[] { return this.silences; }

  set incident_silences(val: Silence[]) {
    this._render();
    this.silences = val;
  }

  /** @prop recently_expired_silence Whether silence recently expired. */
  get incident_has_recently_expired_silence(): boolean { return this.recently_expired_silence; }

  set incident_has_recently_expired_silence(val: boolean) {
    // No need to render again if value is same as old value.
    if (val !== this.recently_expired_silence) {
      this.recently_expired_silence = val;
      this._render();
    }
  }

  /** @prop flaky Whether this incident has been flaky. */
  get incident_flaky(): boolean { return this.flaky; }

  set incident_flaky(val: boolean) {
    // No need to render again if value is same as old value.
    if (val !== this.flaky) {
      this.flaky = val;
      this._render();
    }
  }

  private classOfH2(): string {
    if (!this.state.active) {
      return 'inactive';
    }
    if (this.state.params.assigned_to) {
      return 'assigned';
    }
    return '';
  }

  private table(): TemplateResult[] {
    const params = this.state.params;
    const keys = Object.keys(params);
    keys.sort();
    return keys.filter((k) => !k.startsWith('__')).map((k) => html`
      <tr>
        <th>${k}</th>
        <td>
          <span class="respect-newlines">${linkify(params[k])}</span>
          ${this.maybeDisplayCopyIcon(k)}
        </td>
      </tr>
    `);
  }

  private maybeDisplayCopyIcon(k: string): TemplateResult {
    if (PARAMS_TO_DISPLAY_COPY_ICON.includes(k)) {
      return html`<clipboard-sk value=${this.state.params[k]}></clipboard-sk>`;
    }
    return html``;
  }

  private actionButtons(): TemplateResult {
    if (this.state.active) {
      let assignToOwnerButton = html``;
      if (this.state.params.owner) {
        assignToOwnerButton = html`<button @click=${this.assignToOwner}>Assign to Owner</button>`;
      }
      return html`<section class=assign>
        <button @click=${this.take}>Take</button>
        ${assignToOwnerButton}
        <button @click=${this.assign}>Assign</button>
      </section>`;
    }
    return html``;
  }

  private matchingSilences(): TemplateResult[] {
    if (this.hasAttribute('minimized')) {
      return [];
    }
    // Filter out silences whose paramsets do not match and
    // which have no notes if displaySilencesWithComments is true.
    const filteredSilences = this.silences.filter((silence: Silence) => paramset.match(silence.param_set, this.state.params)
                                               && !(this.displaySilencesWithComments && this.doesSilenceHaveNoNotes(silence)));
    const ret = filteredSilences.slice(0, MAX_MATCHING_SILENCES_TO_DISPLAY).map((silence: Silence) => html`<silence-sk .silence_state=${silence} collapsable collapsed></silence-sk>`);
    if (!ret.length) {
      ret.push(html`<div class=nosilences>None</div>`);
    }
    return ret;
  }

  private doesSilenceHaveNoNotes(silence: Silence): boolean {
    return !silence.notes || (silence.notes.length === 1 && silence.notes[0].text === '');
  }

  private lastSeen(): TemplateResult {
    if (this.state.active) {
      return html``;
    }
    return html`<tr><th>Last Seen</th><td title=${new Date(this.state.last_seen * 1000).toLocaleString()}>${diffDate(this.state.last_seen * 1000)}</td></tr>`;
  }

  private duration(): TemplateResult {
    if (this.state.active) {
      return html``;
    }
    return html`<tr><th>Duration</th><td>${strDuration(this.state.last_seen - this.state.start)}</td></tr>`;
  }

  private history(): Promise<any> {
    if (this.hasAttribute('minimized') || this.state.id === '' || this.state.key === '') {
      return Promise.resolve();
    }
    return fetch(`/_/recent_incidents?id=${this.state.id}&key=${this.state.key}`, {
      headers: {
        'content-type': 'application/json',
      },
      credentials: 'include',
      method: 'GET',
    }).then(jsonOrThrow).then((json: RecentIncidentsResponse) => {
      const incidents = json.incidents || [];
      this.incident_flaky = json.flaky;
      this.incident_has_recently_expired_silence = json.recently_expired_silence;
      return incidents.map((i: Incident) => html`<incident-sk .incident_state=${i} minimized></incident-sk>`);
    }).catch(errorMessage);
  }

  private toggleSilencesWithComments(e: Event): void {
    // This prevents a double event from happening.
    e.preventDefault();
    this.displaySilencesWithComments = !this.displaySilencesWithComments;
    this._render();
  }

  private displayRecentlyExpired(recentlyExpiredSilence: boolean): TemplateResult {
    if (recentlyExpiredSilence) {
      return html`<alarm-off-icon-sk title='This alert has a recently expired silence'></alarm-off-icon-sk>`;
    }
    return html``;
  }

  private displayFlakiness(flaky: boolean): TemplateResult {
    if (flaky) {
      return html`<thumbs-up-down-icon-sk title='This alert is possibly flaky'></thumbs-up-down-icon-sk>`;
    }
    return html``;
  }

  private take(): void {
    const detail = {
      key: this.state.key,
    };
    this.dispatchEvent(new CustomEvent('take', { detail: detail, bubbles: true }));
  }

  private assignToOwner(): void {
    const detail = {
      key: this.state.key,
    };
    this.dispatchEvent(new CustomEvent('assign-to-owner', { detail: detail, bubbles: true }));
  }

  private assign(): void {
    const detail = {
      key: this.state.key,
    };
    this.dispatchEvent(new CustomEvent('assign', { detail: detail, bubbles: true }));
  }

  private addNote(): void {
    const textarea = $$('textarea', this) as HTMLInputElement;
    const detail = {
      key: this.state.key,
      text: textarea.value,
    };
    this.dispatchEvent(new CustomEvent('add-note', { detail: detail, bubbles: true }));
    textarea.value = '';
  }

  private _render(): void {
    if (!this.state) {
      return;
    }
    render(IncidentSk.template(this), this, { eventContext: this });
  }
}

define('incident-sk', IncidentSk);
