/**
 * @license
 * Copyright 2016 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '../../shared/gr-download-commands/gr-download-commands';
import {changeBaseURL, getRevisionKey} from '../../../utils/change-util';
import {ChangeInfo, DownloadInfo, PatchSetNum} from '../../../types/common';
import {GrDownloadCommands} from '../../shared/gr-download-commands/gr-download-commands';
import {GrButton} from '../../shared/gr-button/gr-button';
import {copyToClipbard, hasOwnProperty} from '../../../utils/common-util';
import {fire} from '../../../utils/event-util';
import {fontStyles} from '../../../styles/gr-font-styles';
import {sharedStyles} from '../../../styles/shared-styles';
import {LitElement, PropertyValues, html, css} from 'lit';
import {customElement, property, state, query} from 'lit/decorators.js';
import {assertIsDefined} from '../../../utils/common-util';
import {BindValueChangeEvent} from '../../../types/events';
import {ShortcutController} from '../../lit/shortcut-controller';
import {subscribe} from '../../lit/subscription-controller';
import {resolve} from '../../../models/dependency';
import {changeModelToken} from '../../../models/change/change-model';

@customElement('gr-download-dialog')
export class GrDownloadDialog extends LitElement {
  /**
   * Fired when the user presses the close button.
   *
   * @event close
   */

  @query('#download') protected download?: HTMLAnchorElement;

  @query('#downloadCommands') protected downloadCommands?: GrDownloadCommands;

  @query('#closeButton') protected closeButton?: GrButton;

  @property({type: Object})
  change: ChangeInfo | undefined;

  @property({type: Object})
  config?: DownloadInfo;

  @state() patchNum?: PatchSetNum;

  @state() private selectedScheme?: string;

  private readonly shortcuts = new ShortcutController(this);

  private readonly getChangeModel = resolve(this, changeModelToken);

  constructor() {
    super();
    subscribe(
      this,
      () => this.getChangeModel().patchNum$,
      x => (this.patchNum = x)
    );
    for (const key of ['1', '2', '3', '4', '5']) {
      this.shortcuts.addLocal({key}, e => this.handleNumberKey(e));
    }
  }

  static override get styles() {
    return [
      fontStyles,
      sharedStyles,
      css`
        :host {
          display: block;
          padding: var(--spacing-m) 0;
        }
        section {
          display: flex;
          padding: var(--spacing-m) var(--spacing-xl);
        }
        .flexContainer {
          display: flex;
          justify-content: space-between;
          padding-top: var(--spacing-m);
        }
        .footer {
          justify-content: flex-end;
        }
        .closeButtonContainer {
          align-items: flex-end;
          display: flex;
          flex: 0;
          justify-content: flex-end;
        }
        .patchFiles,
        .archivesContainer {
          padding-bottom: var(--spacing-m);
        }
        .patchFiles {
          margin-right: var(--spacing-xxl);
        }
        .patchFiles a,
        .archives a {
          display: inline-block;
          margin-right: var(--spacing-l);
        }
        .patchFiles a:last-of-type,
        .archives a:last-of-type {
          margin-right: 0;
        }
        gr-download-commands {
          width: min(80vw, 1200px);
        }
      `,
    ];
  }

  override render() {
    const revisions = this.change?.revisions;
    return html`
      <section>
        <h3 class="heading-3">
          Patch set ${this.patchNum} of
          ${revisions ? Object.keys(revisions).length : 0}
        </h3>
      </section>
      ${this.renderDownloadCommands()}
      <section class="flexContainer">
        ${this.renderPatchFiles()} ${this.renderArchives()}
      </section>
      <section class="footer">
        <span class="closeButtonContainer">
          <gr-button
            id="closeButton"
            link
            @click=${(e: Event) => {
              this.handleCloseTap(e);
            }}
            >Close</gr-button
          >
        </span>
      </section>
    `;
  }

  private renderDownloadCommands() {
    const cssClass = this.schemes.length ? '' : 'hidden';

    return html`
      <section class=${cssClass}>
        <gr-download-commands
          id="downloadCommands"
          .commands=${this.computeDownloadCommands()}
          .schemes=${this.schemes}
          .selectedScheme=${this.selectedScheme}
          show-keyboard-shortcut-tooltips
          @selected-scheme-changed=${(e: BindValueChangeEvent) => {
            this.selectedScheme = e.detail.value;
          }}
        ></gr-download-commands>
      </section>
    `;
  }

  private renderPatchFiles() {
    if (this.computeHidePatchFile()) return;

    return html`
      <div class="patchFiles">
        <label>Patch file</label>
        <div>
          <a id="download" .href=${this.computeDownloadLink()} download>
            ${this.computeDownloadFilename()}
          </a>
          <a .href=${this.computeDownloadLink(true)} download>
            ${this.computeDownloadFilename(true)}
          </a>
        </div>
      </div>
    `;
  }

  private renderArchives() {
    if (!this.config?.archives.length) return;

    return html`
      <div class="archivesContainer">
        <label>Archive</label>
        <div id="archives" class="archives">
          ${this.config.archives.map(format => this.renderArchivesLink(format))}
        </div>
      </div>
    `;
  }

  private renderArchivesLink(format: string) {
    return html`
      <a .href=${this.computeArchiveDownloadLink(format)} download>
        ${format}
      </a>
    `;
  }

  override firstUpdated(changedProperties: PropertyValues) {
    super.firstUpdated(changedProperties);
    if (!this.getAttribute('role')) this.setAttribute('role', 'dialog');
  }

  override willUpdate(changedProperties: PropertyValues) {
    if (changedProperties.has('change') || changedProperties.has('patchNum')) {
      this.schemesChanged();
    }
  }

  get schemes() {
    if (this.change === undefined || this.patchNum === undefined) {
      return [];
    }

    for (const rev of Object.values(this.change.revisions || {})) {
      if (rev._number === this.patchNum) {
        const fetch = rev.fetch;
        if (fetch) {
          return Object.keys(fetch).sort();
        }
        break;
      }
    }
    return [];
  }

  private async handleNumberKey(e: KeyboardEvent) {
    const index = Number(e.key) - 1;
    const commands = this.computeDownloadCommands();
    if (index > commands.length) return;
    await copyToClipbard(
      commands[index].command,
      `${commands[index].title} command`
    );
    fire(this, 'close', {});
  }

  override focus() {
    if (this.schemes.length) {
      assertIsDefined(this.downloadCommands, 'downloadCommands');
      this.updateComplete.then(() => this.downloadCommands!.focusOnCopy());
    } else {
      assertIsDefined(this.download, 'download');
      this.download.focus();
    }
  }

  private computeDownloadCommands() {
    let commandObj;
    if (!this.change || !this.selectedScheme) return [];
    for (const rev of Object.values(this.change.revisions || {})) {
      if (
        rev._number === this.patchNum &&
        rev &&
        rev.fetch &&
        hasOwnProperty(rev.fetch, this.selectedScheme)
      ) {
        commandObj = rev.fetch[this.selectedScheme].commands;
        break;
      }
    }
    const commands = [];
    for (const [title, command] of Object.entries(commandObj ?? {})) {
      commands.push({title, command});
    }
    return commands;
  }

  private computeDownloadLink(zip?: boolean) {
    if (this.change === undefined || this.patchNum === undefined) {
      return '';
    }
    return (
      changeBaseURL(this.change.project, this.change._number, this.patchNum) +
      '/patch?' +
      (zip ? 'zip' : 'download')
    );
  }

  private computeDownloadFilename(zip?: boolean) {
    if (this.change === undefined || this.patchNum === undefined) {
      return '';
    }

    const rev = getRevisionKey(this.change, this.patchNum) ?? '';
    const shortRev = rev.substr(0, 7);

    return shortRev + '.diff.' + (zip ? 'zip' : 'base64');
  }

  // private but used in test
  computeHidePatchFile() {
    if (this.change === undefined || this.patchNum === undefined) {
      return false;
    }
    for (const rev of Object.values(this.change.revisions || {})) {
      if (rev._number === this.patchNum) {
        const parentLength =
          rev.commit && rev.commit.parents ? rev.commit.parents.length : 0;
        return parentLength === 0 || parentLength > 1;
      }
    }
    return false;
  }

  // private but used in test
  computeArchiveDownloadLink(format?: string) {
    if (
      this.change === undefined ||
      this.patchNum === undefined ||
      format === undefined
    ) {
      return '';
    }
    return (
      changeBaseURL(this.change.project, this.change._number, this.patchNum) +
      '/archive?format=' +
      format
    );
  }

  private handleCloseTap(e: Event) {
    e.preventDefault();
    e.stopPropagation();
    fire(this, 'close', {});
  }

  private schemesChanged() {
    if (this.schemes.length === 0) {
      return;
    }
    if (!this.selectedScheme || !this.schemes.includes(this.selectedScheme)) {
      this.selectedScheme = this.schemes.sort()[0];
    }
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-download-dialog': GrDownloadDialog;
  }
}
