/**
 * @license
 * Copyright 2017 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '@polymer/iron-dropdown/iron-dropdown';
import '@polymer/paper-item/paper-item';
import '@polymer/paper-listbox/paper-listbox';
import '../../../styles/shared-styles';
import '../gr-button/gr-button';
import '../gr-date-formatter/gr-date-formatter';
import '../gr-select/gr-select';
import '../gr-file-status/gr-file-status';
import {css, html, LitElement, PropertyValues} from 'lit';
import {customElement, property, query} from 'lit/decorators.js';
import {IronDropdownElement} from '@polymer/iron-dropdown/iron-dropdown';
import {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 {isMagicPath} from '../../../utils/path-list-util';

/**
 * 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;
}

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

  @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;

  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;
        }
        .dropdown-content {
          background-color: var(--dropdown-background-color);
          box-shadow: var(--elevation-level-2);
          max-height: 70vh;
          min-width: 266px;
        }
        paper-item:hover {
          background-color: var(--hover-background-color);
        }
        paper-item:not(:last-of-type) {
          border-bottom: 1px solid var(--border-color);
        }
        .bottomContent {
          color: var(--deemphasized-text-color);
        }
        .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-date-formatter {
          color: var(--deemphasized-text-color);
          margin-left: var(--spacing-xxl);
          white-space: nowrap;
        }
        gr-select {
          display: none;
        }
        /* Because the iron dropdown 'area' includes the trigger, and the entire
          width of the dropdown, we want to treat tapping the area above the
          dropdown content as if it is tapping whatever content is underneath
          it. The next two styles allow this to happen. */
        iron-dropdown {
          max-width: none;
          pointer-events: none;
        }
        paper-listbox {
          pointer-events: auto;
          --paper-listbox_-_padding: 0;
        }
        paper-item {
          cursor: pointer;
          flex-direction: column;
          font-size: inherit;
          /* This variable was introduced in Dec 2019. We keep both min-height
            * rules around, because --paper-item-min-height is not yet
            * upstreamed.
            */
          --paper-item-min-height: 0;
          --paper-item_-_min-height: 0;
          --paper-item_-_padding: 10px 16px;
          --paper-item-focused-before_-_background-color: var(
            --selection-background-color
          );
          --paper-item-focused_-_background-color: var(
            --selection-background-color
          );
        }
        @media only screen and (max-width: 50em) {
          gr-select {
            display: var(--gr-select-style-display, inline);
            width: var(--gr-select-style-width);
          }
          gr-button,
          iron-dropdown {
            display: none;
          }
          select {
            width: var(--native-select-style-width);
          }
        }
      `,
    ];
  }

  protected override willUpdate(changedProperties: PropertyValues): void {
    if (changedProperties.has('items') || changedProperties.has('value')) {
      this.handleValueChange();
    }
  }

  override render() {
    return html`
      <gr-button
        id="trigger"
        ?disabled=${this.disabled}
        down-arrow
        link
        class="dropdown-trigger"
        slot="dropdown-trigger"
        no-uppercase
        @click=${this.showDropdownTapHandler}
      >
        <span id="triggerText">${this.text}</span>
        <gr-copy-clipboard
          ?hidden=${!this.showCopyForTriggerText}
          hideInput
          .text=${this.text}
        ></gr-copy-clipboard>
      </gr-button>
      <iron-dropdown
        id="dropdown"
        .verticalAlign=${'top'}
        .horizontalAlign=${'left'}
        .dynamicAlign=${true}
        .noOverlap=${true}
        .allowOutsideScroll=${true}
        @click=${this.handleDropdownClick}
      >
        <paper-listbox
          class="dropdown-content"
          slot="dropdown-content"
          .attrForSelected=${'data-value'}
          .selected=${this.value}
          @selected-changed=${this.selectedChanged}
        >
          ${incrementalRepeat({
            values: this.items ?? [],
            initialCount: this.initialCount,
            mapFn: item => this.renderPaperItem(item as DropdownItem),
          })}
        </paper-listbox>
      </iron-dropdown>
      <gr-select
        .bindValue=${this.value}
        @bind-value-changed=${this.selectedChanged}
      >
        <select>
          ${this.items?.map(
            item => html`
              <option ?disabled=${item.disabled} value=${`${item.value}`}>
                ${this.computeMobileText(item)}
              </option>
            `
          )}
        </select>
      </gr-select>
    `;
  }

  private renderPaperItem(item: DropdownItem) {
    return html`
      <paper-item ?disabled=${item.disabled} data-value=${item.value}>
        <div class="topContent">
          <div>${item.text}</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>
          `
        )}
      </paper-item>
    `;
  }

  private selectedChanged(e: ValueChangedEvent<string>) {
    this.value = e.detail.value;
  }

  /**
   * Handle a click on the iron-dropdown element.
   */
  private handleDropdownClick() {
    // async is needed so that that the click event is fired before the
    // dropdown closes (This was a bug for touch devices).
    setTimeout(() => {
      assertIsDefined(this.dropdown);
      this.dropdown.close();
    }, 1);
  }

  private handleValueChange() {
    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;
    this.dispatchEvent(
      new CustomEvent('value-change', {
        detail: {value: this.value},
        bubbles: false,
      })
    );
  }

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

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

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

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