/**
 * @license
 * Copyright 2021 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '../shared/gr-icon/gr-icon';
import {fontStyles} from '../../styles/gr-font-styles';
import {customElement, property} from 'lit/decorators.js';
import './gr-checks-action';
import {CheckRun} from '../../models/checks/checks-model';
import {
  AttemptDetail,
  ChecksIcon,
  iconFor,
  runActions,
  worstCategory,
} from '../../models/checks/checks-util';
import {durationString, fromNow} from '../../utils/date-util';
import {RunStatus} from '../../api/checks';
import {ordinal} from '../../utils/string-util';
import {HovercardMixin} from '../../mixins/hovercard-mixin/hovercard-mixin';
import {css, html, LitElement} from 'lit';
import {checksStyles} from './gr-checks-styles';

// This avoids JSC_DYNAMIC_EXTENDS_WITHOUT_JSDOC closure compiler error.
const base = HovercardMixin(LitElement);

@customElement('gr-hovercard-run')
export class GrHovercardRun extends base {
  @property({type: Object})
  run?: CheckRun;

  static override get styles() {
    return [
      fontStyles,
      checksStyles,
      base.styles || [],
      css`
        #container {
          min-width: 356px;
          padding: var(--spacing-xl) 0 var(--spacing-m) 0;
        }
        .row {
          display: flex;
          margin-top: var(--spacing-s);
        }
        .attempts.row {
          flex-wrap: wrap;
        }
        .chipRow {
          display: flex;
          margin-top: var(--spacing-s);
        }
        .chip {
          background: var(--gray-background);
          color: var(--gray-foreground);
          border-radius: 20px;
          padding: var(--spacing-xs) var(--spacing-m) var(--spacing-xs)
            var(--spacing-s);
        }
        .title {
          color: var(--deemphasized-text-color);
          margin-right: var(--spacing-m);
        }
        div.section {
          margin: 0 var(--spacing-xl) var(--spacing-m) var(--spacing-xl);
          display: flex;
        }
        div.sectionIcon {
          flex: 0 0 30px;
        }
        div.chip gr-icon {
          font-size: 16px;
          /* Positioning of a 16px icon in the middle of a 20px line. */
          position: relative;
          top: 2px;
        }
        div.sectionIcon gr-icon {
          position: relative;
          top: 2px;
          font-size: 20px;
        }
        div.sectionIcon gr-icon.small {
          position: relative;
          top: 6px;
          font-size: 16px;
        }
        div.sectionContent gr-icon.link {
          color: var(--link-color);
        }
        div.sectionContent .attemptIcon gr-icon,
        div.sectionContent gr-icon.small {
          font-size: 16px;
          margin-right: var(--spacing-s);
          /* Positioning of a 16px icon in the middle of a 20px line. */
          position: relative;
          top: 2px;
        }
        div.sectionContent .attemptIcon gr-icon {
          margin-right: 0;
        }
        .attemptIcon,
        .attemptNumber {
          margin-right: var(--spacing-s);
          color: var(--deemphasized-text-color);
          text-align: center;
          width: 24px;
          font-size: var(--font-size-small);
        }
        div.action {
          border-top: 1px solid var(--border-color);
          margin-top: var(--spacing-m);
          padding: var(--spacing-m) var(--spacing-xl) 0;
        }
      `,
    ];
  }

  override render() {
    if (!this.run) return '';
    const icon = this.computeIcon();
    const chipIcon = this.computeChipIcon();
    return html`
      <div id="container" role="tooltip" tabindex="-1">
        <div class="section">
          <div
            ?hidden=${!this.run || this.run.status === RunStatus.RUNNABLE}
            class="chipRow"
          >
            <div class="chip">
              <gr-icon
                icon=${chipIcon.name}
                ?filled=${chipIcon.filled}
              ></gr-icon>
              <span>${this.run.status}</span>
            </div>
          </div>
        </div>
        <div class="section">
          <div class="sectionIcon" ?hidden=${icon.name.length === 0}>
            <gr-icon
              icon=${icon.name}
              class=${icon.name}
              ?filled=${icon.filled}
            ></gr-icon>
          </div>
          <div class="sectionContent">
            <h3 class="name heading-3">
              <span>${this.run.checkName}</span>
            </h3>
          </div>
        </div>
        ${this.renderStatusSection()} ${this.renderAttemptSection()}
        ${this.renderTimestampSection()} ${this.renderDescriptionSection()}
        ${this.renderActions()}
      </div>
    `;
  }

  private renderStatusSection() {
    if (!this.run || (!this.run.statusLink && !this.run.statusDescription))
      return;

    return html`
      <div class="section">
        <div class="sectionIcon">
          <gr-icon icon="info" class="small"></gr-icon>
        </div>
        <div class="sectionContent">
          ${this.run.statusLink
            ? html` <div class="row">
                <div class="title">Status</div>
                <div>
                  <a href=${this.run.statusLink} target="_blank"
                    ><gr-icon
                      icon="open_in_new"
                      aria-label="external link to check status"
                      class="small link"
                    ></gr-icon
                    >${this.computeHostName(this.run.statusLink)}
                  </a>
                </div>
              </div>`
            : ''}
          ${this.run.statusDescription
            ? html` <div class="row">
                <div class="title">Message</div>
                <div>${this.run.statusDescription}</div>
              </div>`
            : ''}
        </div>
      </div>
    `;
  }

  private renderAttemptSection() {
    if (this.hideAttempts()) return;
    const attempts = this.computeAttempts();
    return html`
      <div class="section">
        <div class="sectionIcon">
          <gr-icon icon="arrow_forward" class="small"></gr-icon>
        </div>
        <div class="sectionContent">
          <div class="attempts row">
            <div class="title">Attempt</div>
            ${attempts.map(a => this.renderAttempt(a))}
          </div>
        </div>
      </div>
    `;
  }

  private renderAttempt(attempt: AttemptDetail) {
    const attemptNumber = attempt.attempt;
    const icon = attempt.icon ?? {name: ''};
    if (attemptNumber !== undefined && typeof attemptNumber !== 'number') {
      return;
    }
    return html`
      <div>
        <div class="attemptIcon">
          <gr-icon class=${icon.name} icon=${icon.name} ?filled=${icon.filled}>
          </gr-icon>
        </div>
        <div class="attemptNumber">${ordinal(attemptNumber)}</div>
      </div>
    `;
  }

  private renderTimestampSection() {
    if (
      !this.run ||
      (!this.run.startedTimestamp &&
        !this.run.scheduledTimestamp &&
        !this.run.finishedTimestamp)
    )
      return;

    const scheduled =
      this.run.scheduledTimestamp && !this.run.startedTimestamp
        ? html`<div class="row">
            <div class="title">Scheduled</div>
            <div>${fromNow(this.run.scheduledTimestamp)}</div>
          </div>`
        : '';

    const started = this.run.startedTimestamp
      ? html`<div class="row">
          <div class="title">Started</div>
          <div>${fromNow(this.run.startedTimestamp)}</div>
        </div>`
      : '';

    const finished =
      this.run.finishedTimestamp && this.run.status === RunStatus.COMPLETED
        ? html`<div class="row">
            <div class="title">Ended</div>
            <div>${fromNow(this.run.finishedTimestamp)}</div>
          </div>`
        : '';

    const completed =
      this.run.startedTimestamp &&
      this.run.finishedTimestamp &&
      this.run.status === RunStatus.COMPLETED
        ? html`<div class="row">
            <div class="title">Completion</div>
            <div>
              ${durationString(
                this.run.startedTimestamp,
                this.run.finishedTimestamp,
                true
              )}
            </div>
          </div>`
        : '';

    const eta =
      this.run.finishedTimestamp && this.run.status === RunStatus.RUNNING
        ? html`<div class="row">
            <div class="title">ETA</div>
            <div>
              ${durationString(new Date(), this.run.finishedTimestamp, true)}
            </div>
          </div>`
        : '';

    return html`
      <div class="section">
        <div class="sectionIcon">
          <gr-icon icon="schedule" class="small"></gr-icon>
        </div>
        <div class="sectionContent">
          ${scheduled} ${started} ${finished} ${completed} ${eta}
        </div>
      </div>
    `;
  }

  private renderDescriptionSection() {
    if (!this.run || (!this.run.checkLink && !this.run.checkDescription))
      return;
    return html`
      <div class="section">
        <div class="sectionIcon">
          <gr-icon icon="link" class="small"></gr-icon>
        </div>
        <div class="sectionContent">
          ${this.run.checkDescription
            ? html` <div class="row">
                <div class="title">Description</div>
                <div>${this.run.checkDescription}</div>
              </div>`
            : ''}
          ${this.run.checkLink
            ? html` <div class="row">
                <div class="title">Documentation</div>
                <div>
                  <a href=${this.run.checkLink} target="_blank"
                    ><gr-icon
                      icon="open_in_new"
                      aria-label="external link to check documentation"
                      class="small link"
                    ></gr-icon
                    >${this.computeHostName(this.run.checkLink)}
                  </a>
                </div>
              </div>`
            : ''}
        </div>
      </div>
    `;
  }

  private renderActions() {
    const actions = runActions(this.run);
    return actions.map(
      action =>
        html`
          <div class="action">
            <gr-checks-action
              context="hovercard"
              .eventTarget=${this._target}
              .action=${action}
            ></gr-checks-action>
          </div>
        `
    );
  }

  computeIcon(): ChecksIcon {
    if (!this.run) return {name: ''};
    const category = worstCategory(this.run);
    if (category) return iconFor(category);
    return this.run.status === RunStatus.COMPLETED
      ? iconFor(RunStatus.COMPLETED)
      : {name: ''};
  }

  computeAttempts(): AttemptDetail[] {
    const details: AttemptDetail[] = this.run?.attemptDetails ?? [];
    const more: AttemptDetail[] =
      details.length > 7
        ? [{icon: {name: 'more_horiz'}, attempt: undefined}]
        : [];
    return [...more, ...details.slice(-7)];
  }

  private computeChipIcon(): ChecksIcon {
    if (this.run?.status === RunStatus.COMPLETED) {
      return {name: 'check'};
    }
    if (this.run?.status === RunStatus.RUNNING) {
      return iconFor(RunStatus.RUNNING);
    }
    if (this.run?.status === RunStatus.SCHEDULED) {
      return iconFor(RunStatus.SCHEDULED);
    }
    return {name: ''};
  }

  private computeHostName(link?: string) {
    return link ? new URL(link).hostname : '';
  }

  private hideAttempts() {
    const attemptCount = this.run?.attemptDetails?.length;
    return attemptCount === undefined || attemptCount < 2;
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-hovercard-run': GrHovercardRun;
  }
}
