/**
 * @license
 * Copyright 2017 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '../../../styles/shared-styles';
import '../gr-button/gr-button';
import '../gr-date-formatter/gr-date-formatter';
import '../gr-file-status/gr-file-status';
import '../gr-vote-chip/gr-vote-chip';
import {css, html, LitElement, nothing, PropertyValues} from 'lit';
import {customElement, property, query, state} from 'lit/decorators.js';
import {ApprovalInfo, LabelInfo} from '../../../api/rest-api';
import {CommentThread, Timestamp} from '../../../types/common';
import {NormalizedFileInfo} from '../../change/gr-file-list/gr-file-list';
import {GrButton} from '../gr-button/gr-button';
import {assertIsDefined} from '../../../utils/common-util';
import {sharedStyles} from '../../../styles/shared-styles';
import {ValueChangedEvent} from '../../../types/events';
import {incrementalRepeat} from '../../lit/incremental-repeat';
import {when} from 'lit/directives/when.js';
import {computeTruncatedPath, isMagicPath} from '../../../utils/path-list-util';
import {fireNoBubble} from '../../../utils/event-util';
import {classMap} from 'lit/directives/class-map.js';
import '@material/web/divider/divider';
import '@material/web/menu/menu';
import '@material/web/menu/menu-item';
import {MdMenu} from '@material/web/menu/menu';
import {isSafari, Key} from '../../../utils/dom-util';
import {GrCursorManager} from '../gr-cursor-manager/gr-cursor-manager';

/**
 * Required values are text and value. mobileText and triggerText will
 * fall back to text if not provided.
 *
 * If bottomText is not provided, nothing will display on the second
 * line.
 *
 * If date is not provided, nothing will be displayed in its place.
 */
export interface DropdownItem {
  text: string;
  value: string | number;
  bottomText?: string;
  triggerText?: string;
  mobileText?: string;
  date?: Timestamp;
  disabled?: boolean;
  file?: NormalizedFileInfo;
  commentThreads?: CommentThread[];
  deemphasizeReason?: string;
  vote?: ApprovalInfo;
  label?: LabelInfo;
}

declare global {
  interface HTMLElementEventMap {
    'value-change': ValueChangedEvent<string>;
  }
}
@customElement('gr-dropdown-list')
export class GrDropdownList extends LitElement {
  @query('#dropdown')
  dropdown?: MdMenu;

  @query('#trigger')
  trigger?: GrButton;

  /**
   * Fired when the selected value changes
   *
   * @event value-change
   *
   * @property {string} value
   */

  @property({type: Number})
  initialCount = 75;

  @property({type: Array})
  items?: DropdownItem[];

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

  @property({type: Boolean})
  disabled = false;

  @property({type: String})
  value = '';

  @property({type: Boolean, attribute: 'show-copy-for-trigger-text'})
  showCopyForTriggerText = false;

  @state()
  selectedIndex = 0;

  @state()
  private opened = false;

  @state() private hadKeyboardEvent = false;

  cursor = new GrCursorManager();

  constructor() {
    super();
    this.cursor.cursorTargetAttribute = 'selected';
    this.cursor.focusOnMove = true;
  }

  static override get styles() {
    return [
      sharedStyles,
      css`
        :host {
          display: inline-block;
        }
        #triggerText {
          -moz-user-select: text;
          -ms-user-select: text;
          -webkit-user-select: text;
          user-select: text;
        }
        .dropdown-trigger {
          cursor: pointer;
          padding: 0;
        }
        md-menu {
          white-space: nowrap;
          --md-menu-container-color: var(--dropdown-background-color);
          --md-menu-top-space: 0px;
          --md-menu-bottom-space: 0px;
          --md-focus-ring-duration: 0s;
          max-height: calc(100vh - 48px);
        }
        md-divider {
          margin: auto;
          --md-divider-color: var(--border-color);
        }
        md-menu-item {
          max-height: 70vh;
          min-width: 266px;
          --md-sys-color-on-surface: var(
            --gr-dropdown-item-color,
            var(--primary-text-color, black)
          );
          --md-sys-color-on-secondary-container: var(
            --gr-dropdown-item-color,
            var(--primary-text-color, black)
          );
          --md-sys-typescale-body-large-font: inherit;
          --md-menu-item-hover-state-layer-color: var(
            --selection-background-color
          );
          --md-menu-item-hover-state-layer-opacity: 1;
          --md-menu-item-selected-container-color: var(
            --selection-background-color
          );
          --md-focus-ring-color: var(--gr-dropdown-focus-ring-color);
          --md-menu-item-one-line-container-height: auto;
        }
        md-menu-item[active] .topContent {
          font-weight: bold;
        }
        .dropdown {
          position: relative;
        }
        .dropdown-menu {
          position: relative;
          z-index: 120;
        }
        .bottomContent {
          color: var(--deemphasized-text-color);
          white-space: pre-wrap;
        }
        .bottomContent,
        .topContent {
          display: flex;
          justify-content: space-between;
          flex-direction: row;
          width: 100%;
        }
        gr-button {
          font-family: var(--trigger-style-font-family);
          --gr-button-text-color: var(--trigger-style-text-color);
        }
        gr-vote-chip {
          margin-right: var(--spacing-s);
        }
        gr-date-formatter {
          color: var(--deemphasized-text-color);
          margin-left: var(--spacing-xxl);
          white-space: nowrap;
        }
        .topContent.deemphasized {
          color: var(--deemphasized-text-color);
          font-style: italic;
        }
        gr-comments-summary {
          padding-left: var(--spacing-s);
        }
        .copyClipboard {
          display: inline-flex;
          vertical-align: top;
        }
        .mobileText {
          display: none;
        }
        .desktopText {
          display: inline-block;
        }
        gr-file-status {
          margin-left: var(--spacing-xxl);
        }
        @media only screen and (max-width: 50em) {
          .mobileText {
            display: inline-block;
          }
          .desktopText {
            display: none;
          }
        }
      `,
    ];
  }

  protected override willUpdate(changedProperties: PropertyValues): void {
    if (changedProperties.has('value') || changedProperties.has('items')) {
      this.updateText();
    }
    if (changedProperties.has('value')) {
      fireNoBubble(this, 'value-change', {value: this.value});
    }
  }

  override updated(changedProperties: PropertyValues) {
    if (changedProperties.has('items')) {
      this.resetCursorStops();
    }

    if (changedProperties.has('opened')) {
      if (this.opened) {
        this.resetCursorStops();
        this.cursor.setCursorAtIndex(this.selectedIndex);
        if (this.cursor.target !== null) {
          this.cursor.target.focus();
          if (isSafari() && !this.hadKeyboardEvent) {
            const mdFocusRing = this.cursor.target?.shadowRoot
              ?.querySelector('md-item')
              ?.querySelector('md-focus-ring');
            if (mdFocusRing) mdFocusRing.visible = false;
          }
        }
        this.setUpGlobalEventListeners();
      } else {
        this.cleanUpGlobalEventListeners();
      }
    }
  }

  private setUpGlobalEventListeners() {
    const passiveOptions: AddEventListenerOptions = {passive: true};

    window.addEventListener('resize', this.onWindowResize, passiveOptions);
    window.addEventListener('scroll', this.onWindowResize, passiveOptions);
  }

  private cleanUpGlobalEventListeners() {
    const passiveOptions: AddEventListenerOptions = {passive: true};

    window.removeEventListener('resize', this.onWindowResize, passiveOptions);
    window.removeEventListener('scroll', this.onWindowResize, passiveOptions);
  }

  private readonly onWindowResize = () => {
    this.dropdown?.reposition();
  };

  override render() {
    return html`<div class="dropdown">
      <gr-button
        id="trigger"
        ?disabled=${!!this.disabled}
        down-arrow
        link
        class="dropdown-trigger"
        slot="dropdown-trigger"
        @click=${this.showDropdownTapHandler}
        @keydown=${(e: KeyboardEvent) => {
          this.hadKeyboardEvent = true;
          if (
            (e.key === Key.DOWN || e.key === Key.UP) &&
            !this.dropdown?.open
          ) {
            e.preventDefault();
            e.stopPropagation();
            this.dropdown?.show();
          }
        }}
        @mousedown=${() => {
          this.hadKeyboardEvent = false;
        }}
        @pointerdown=${() => {
          this.hadKeyboardEvent = false;
        }}
        @touchstart=${() => {
          this.hadKeyboardEvent = false;
        }}
      >
        <span id="triggerText" class="desktopText">${this.text}</span>
        <span id="triggerText" class="mobileText"
          >${computeTruncatedPath(this.text)}</span
        >
        <gr-copy-clipboard
          class="copyClipboard"
          ?hidden=${!this.showCopyForTriggerText}
          hideInput
          .text=${this.text}
        ></gr-copy-clipboard>
      </gr-button>
      <div class="dropdown-menu">
        <md-menu
          id="dropdown"
          anchor="trigger"
          default-focus="none"
          tabindex="-1"
          .menuCorner=${'start-start'}
          ?quick=${true}
          .skipRestoreFocus=${true}
          positioning="fixed"
          @click=${this.handleDropdownClick}
          @opened=${(e: Event) => {
            this.opened = true;
            this.scrollToSelected(e);
          }}
          @closed=${() => {
            this.opened = false;
            this.hadKeyboardEvent = false;
            // This is an ugly hack but works.
            this.cursor.target?.removeAttribute('selected');
            this.cursor.target?.blur();
          }}
        >
          ${incrementalRepeat({
            values: this.items ?? [],
            initialCount: this.initialCount,
            mapFn: (item, index) =>
              this.renderMdMenuItem(item as DropdownItem, index),
          })}
        </md-menu>
      </div>
    </div> `;
  }

  private renderMdMenuItem(item: DropdownItem, index: number) {
    if (this.value === String(item.value)) {
      this.selectedIndex = index;
    }
    return html`
      <md-menu-item
        ?selected=${this.value === String(item.value)}
        ?active=${this.value === String(item.value)}
        ?disabled=${!!item.disabled}
        @click=${() => {
          this.value = String(item.value);
        }}
        @keydown=${(e: KeyboardEvent) => {
          if (e.key === Key.ENTER || e.key === Key.SPACE) {
            e.preventDefault();
            e.stopPropagation();
            this.handleEnter();
          }
          if (e.key === Key.UP) {
            e.preventDefault();
            e.stopPropagation();
            this.handleUp();
          }
          if (e.key === Key.DOWN) {
            e.preventDefault();
            e.stopPropagation();
            this.handleDown();
          }
        }}
      >
        <div
          class=${classMap({
            topContent: true,
            deemphasized: !!item.deemphasizeReason,
          })}
        >
          <div>
            <span class="desktopText">${item.text}</span>
            <span class="mobileText">${this.computeMobileText(item)}</span>
            ${when(
              !!item.deemphasizeReason,
              () => html`<span>| ${item.deemphasizeReason}</span>`
            )}
            ${when(
              item.commentThreads,
              () => html`<gr-comments-summary
                .commentThreads=${item.commentThreads}
                emptyWhenNoComments
                showAvatarForResolved
              ></gr-comments-summary>`
            )}
          </div>
          ${when(
            item.vote,
            () =>
              html` <div>
                <gr-vote-chip
                  .vote=${item.vote}
                  .label=${item.label}
                ></gr-vote-chip>
              </div>`
          )}
          ${when(
            item.date,
            () => html`
              <gr-date-formatter .dateStr=${item.date}></gr-date-formatter>
            `
          )}
          ${when(
            item.file?.status && !isMagicPath(item.file?.__path),
            () => html`
              <gr-file-status .status=${item.file?.status}></gr-file-status>
            `
          )}
        </div>
        ${when(
          item.bottomText,
          () => html`
            <div class="bottomContent">
              <div>${item.bottomText}</div>
            </div>
          `
        )}
      </md-menu-item>
      ${index < this.items!.length - 1
        ? html`<md-divider role="separator" tabindex="-1"></md-divider>`
        : nothing}
    `;
  }

  /**
   * Handle the up key.
   */
  private handleUp() {
    this.cursor.previous();
  }

  /**
   * Handle the down key.
   */
  private handleDown() {
    this.cursor.next();
  }

  /**
   * Handle the enter key.
   */
  private handleEnter() {
    if (this.cursor.target !== null) {
      const el = this.cursor.target.shadowRoot?.querySelector(':not([hidden])');
      if (el) {
        (el as HTMLElement).click();
      }
    }
  }

  /**
   * Handle a click on the md-menu element.
   */
  private handleDropdownClick(e?: MouseEvent) {
    assertIsDefined(this.dropdown);
    if (e) {
      e.preventDefault();
      e.stopPropagation();
    }

    this.dropdown.close();

    // For some reason this is needed, otherwise a console warning is thrown,
    // with something about aria-hidden can't be set because md-menu is focused already.
    e && e.currentTarget && (e.currentTarget as HTMLElement).blur();
  }

  private updateText() {
    if (this.value === undefined || this.items === undefined) {
      return;
    }
    const selectedObj = this.items.find(item => `${item.value}` === this.value);
    if (!selectedObj) {
      return;
    }
    this.text = selectedObj.triggerText
      ? selectedObj.triggerText
      : selectedObj.text;
  }

  /**
   * Handle a click on the button to open the dropdown.
   */
  private showDropdownTapHandler(e: Event) {
    e.preventDefault();
    e.stopPropagation();
    this.open();
  }

  /**
   * Open the dropdown.
   */
  open() {
    assertIsDefined(this.dropdown);
    this.dropdown.open = !this.dropdown.open;
    this.dropdown.focus();
  }

  // Private but used in tests.
  computeMobileText(item: DropdownItem) {
    return item.mobileText ? item.mobileText : item.text;
  }

  private scrollToSelected(e: Event) {
    const target = e.target as HTMLElement;
    const selected = target.querySelector<MdMenu>('md-menu-item[selected]');
    selected?.scrollIntoView({block: 'nearest'});
  }

  /**
   * Recompute the stops for the dropdown item cursor.
   */
  private resetCursorStops() {
    assertIsDefined(this.dropdown);
    if (this.items && this.items.length > 0 && this.dropdown.open) {
      this.cursor.stops = Array.from(
        this.shadowRoot?.querySelectorAll('md-menu-item') ?? []
      );
    }
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-dropdown-list': GrDropdownList;
  }
}
