/**
 * @license
 * Copyright 2017 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import {Subscription} from 'rxjs';
import '@polymer/paper-tabs/paper-tab';
import '@polymer/paper-tabs/paper-tabs';
import '../gr-shell-command/gr-shell-command';
import {getAppContext} from '../../../services/app-context';
import {queryAndAssert} from '../../../utils/common-util';
import {GrShellCommand} from '../gr-shell-command/gr-shell-command';
import {paperStyles} from '../../../styles/gr-paper-styles';
import {sharedStyles} from '../../../styles/shared-styles';
import {LitElement, html, css} from 'lit';
import {customElement, property, state} from 'lit/decorators.js';
import {fire} from '../../../utils/event-util';
import {BindValueChangeEvent} from '../../../types/events';
import {resolve} from '../../../models/dependency';
import {userModelToken} from '../../../models/user/user-model';

declare global {
  interface HTMLElementEventMap {
    'selected-changed': CustomEvent<{value: number}>;
    'selected-scheme-changed': BindValueChangeEvent;
  }
  interface HTMLElementTagNameMap {
    'gr-download-commands': GrDownloadCommands;
  }
}

export interface Command {
  title: string;
  command: string;
}

@customElement('gr-download-commands')
export class GrDownloadCommands extends LitElement {
  @property({type: Array})
  commands: Command[] = [];

  // private but used in test
  @state() loggedIn = false;

  @property({type: Array})
  schemes: string[] = [];

  @property({type: String})
  selectedScheme?: string;

  // description of selected scheme
  @property({type: String})
  description?: string;

  @property({type: Boolean, attribute: 'show-keyboard-shortcut-tooltips'})
  showKeyboardShortcutTooltips = false;

  private readonly restApiService = getAppContext().restApiService;

  // Private but used in tests.
  readonly getUserModel = resolve(this, userModelToken);

  private subscriptions: Subscription[] = [];

  override connectedCallback() {
    super.connectedCallback();
    this.restApiService.getLoggedIn().then(loggedIn => {
      this.loggedIn = loggedIn;
    });
    this.subscriptions.push(
      this.getUserModel().preferences$.subscribe(prefs => {
        if (prefs?.download_scheme) {
          // Note (issue 5180): normalize the download scheme with lower-case.
          this.selectedScheme = prefs.download_scheme.toLowerCase();
          fire(this, 'selected-scheme-changed', {value: this.selectedScheme});
        }
      })
    );
  }

  override disconnectedCallback() {
    for (const s of this.subscriptions) {
      s.unsubscribe();
    }
    this.subscriptions = [];
    super.disconnectedCallback();
  }

  static override get styles() {
    return [
      paperStyles,
      sharedStyles,
      css`
        paper-tabs {
          height: 3rem;
          margin-bottom: var(--spacing-m);
          --paper-tabs-selection-bar-color: var(--link-color);
        }
        paper-tab {
          max-width: 15rem;
          text-transform: uppercase;
          --paper-tab-ink: var(--link-color);
          --paper-font-common-base_-_font-family: var(--header-font-family);
          --paper-font-common-base_-_-webkit-font-smoothing: initial;
          --paper-tab-content_-_margin-bottom: var(--spacing-s);
          /* paper-tabs uses 700 here, which can look awkward */
          --paper-tab-content-focused_-_font-weight: var(--font-weight-h3);
          --paper-tab-content-focused_-_background: var(
            --gray-background-focus
          );
          --paper-tab-content-unselected_-_opacity: 1;
          --paper-tab-content-unselected_-_color: var(
            --deemphasized-text-color
          );
        }
        label,
        input {
          display: block;
        }
        label {
          font-weight: var(--font-weight-bold);
        }
        .schemes {
          display: flex;
          justify-content: space-between;
        }
        .description {
          margin-bottom: var(--spacing-m);
        }
        .commands {
          display: flex;
          flex-direction: column;
        }
        gr-shell-command {
          margin-bottom: var(--spacing-m);
        }
        .hidden {
          display: none;
        }
      `,
    ];
  }

  override render() {
    return html`
      <div class="schemes">${this.renderDownloadTabs()}</div>
      ${this.renderDescription()} ${this.renderCommands()}
    `;
  }

  private renderDownloadTabs() {
    const selectedIndex =
      this.schemes.findIndex(scheme => scheme === this.selectedScheme) || 0;
    return html`
      <paper-tabs
        id="downloadTabs"
        class=${this.computeShowTabs()}
        .selected=${selectedIndex}
        @selected-changed=${this.handleTabChange}
      >
        ${this.schemes.map(scheme => this.renderPaperTab(scheme))}
      </paper-tabs>
    `;
  }

  private renderDescription() {
    if (!this.description) return;
    return html`<div class="description">${this.description}</div>`;
  }

  private renderPaperTab(scheme: string) {
    return html` <paper-tab data-scheme=${scheme}>${scheme}</paper-tab> `;
  }

  private renderCommands() {
    return html`
      <div class="commands" ?hidden=${!this.schemes.length}></div>
        ${this.commands?.map((command, index) =>
          this.renderShellCommand(command, index)
        )}
      </div>
    `;
  }

  private renderShellCommand(command: Command, index: number) {
    return html`
      <gr-shell-command
        class=${this.computeClass(command.title)}
        .label=${command.title}
        .command=${command.command}
        .tooltip=${this.computeTooltip(index)}
      ></gr-shell-command>
    `;
  }

  async focusOnCopy() {
    await this.updateComplete;
    await queryAndAssert<GrShellCommand>(
      this,
      'gr-shell-command'
    ).focusOnCopy();
  }

  private handleTabChange = (e: CustomEvent<{value: number}>) => {
    const scheme = this.schemes[e.detail.value];
    if (scheme && scheme !== this.selectedScheme) {
      this.selectedScheme = scheme;
      fire(this, 'selected-scheme-changed', {value: scheme});
      if (this.loggedIn) {
        this.getUserModel().updatePreferences({
          download_scheme: this.selectedScheme,
        });
      }
    }
  };

  private computeTooltip(index: number) {
    return index <= 4 && this.showKeyboardShortcutTooltips
      ? `Keyboard shortcut: ${index + 1}`
      : '';
  }

  private computeShowTabs() {
    return this.schemes.length > 1 ? '' : 'hidden';
  }

  // TODO: maybe unify with strToClassName from dom-util
  private computeClass(title: string) {
    // Only retain [a-z] chars, so "Cherry Pick" becomes "cherrypick".
    return '_label_' + title.replace(/[^a-z]+/gi, '').toLowerCase();
  }
}
