/**
 * @license
 * Copyright 2022 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */

import '../../shared/gr-copy-clipboard/gr-copy-clipboard';
import {css, html, LitElement, nothing, PropertyValues} from 'lit';
import {createRef, ref, Ref} from 'lit/directives/ref.js';
import {customElement, property, query} from 'lit/decorators.js';
import {strToClassName} from '../../../utils/dom-util';
import {copyToClipboard, queryAndAssert} from '../../../utils/common-util';
import {formStyles} from '../../../styles/form-styles';
import {GrCopyClipboard} from '../../shared/gr-copy-clipboard/gr-copy-clipboard';
import '@material/web/menu/menu';
import {MdMenu} from '@material/web/menu/menu';
import {MdOutlinedTextField} from '@material/web/textfield/outlined-text-field';
import {materialStyles} from '../../../styles/gr-material-styles';

export interface CopyLink {
  label: string;
  shortcut: string;
  value: string;
  multiline?: boolean;
}

const AWAIT_MAX_ITERS = 10;
const AWAIT_STEP = 5;

@customElement('gr-copy-links')
export class GrCopyLinks extends LitElement {
  copyClipboardRef: Ref<GrCopyClipboard> = createRef();

  @property({type: Array})
  copyLinks: CopyLink[] = [];

  @property({type: String})
  horizontalAlign: 'left' | 'right' = 'left';

  @property({type: String})
  shortcutPrefix = 'l - ';

  @property({type: Number})
  verticalOffset = 10;

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

  // private but used in screenshot tests
  @query('md-menu') dropdown?: MdMenu;

  static override get styles() {
    return [
      materialStyles,
      formStyles,
      css`
        md-menu {
          white-space: nowrap;
          --md-menu-container-color: var(--dialog-background-color);
          --md-menu-top-space: 0px;
          --md-menu-bottom-space: 0px;
        }
        .dropdown-content {
          width: min(90vw, 640px);
          padding: var(--spacing-m) var(--spacing-l) var(--spacing-m);
          box-shadow: var(--elevation-level-2);
          border-radius: var(--border-radius);
        }
        .copy-link-row {
          margin-bottom: var(--spacing-m);
        }
        gr-copy-clipboard::part(text-container-wrapper-style) {
          flex: 1 1 420px;
        }
      `,
    ];
  }

  override connectedCallback() {
    super.connectedCallback();
    if (this.isDropdownOpen) {
      this.setUpGlobalEventListeners();
    }
  }

  override updated(changedProperties: PropertyValues) {
    if (changedProperties.has('isDropdownOpen')) {
      if (this.isDropdownOpen) {
        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() {
    if (!this.copyLinks) return nothing;
    return html`<md-menu
      default-focus="none"
      tabindex="-1"
      .menuCorner=${this.horizontalAlign === 'left'
        ? 'start-start'
        : 'end-start'}
      ?quick=${true}
      .yOffset=${this.verticalOffset}
      @opened=${() => {
        this.isDropdownOpen = true;
      }}
      @closed=${() => {
        this.isDropdownOpen = false;
      }}
      @keydown=${this.handleKeydown}
    >
      ${this.renderCopyLinks()}
    </md-menu> `;
  }

  private renderCopyLinks() {
    return html`<div class="dropdown-content">
      ${this.copyLinks?.map((link, index) =>
        this.renderCopyLinkRow(link, index)
      )}
    </div>`;
  }

  private renderCopyLinkRow(copyLink: CopyLink, index?: number) {
    const {label, shortcut, value, multiline} = copyLink;
    const id = `${strToClassName(label, '')}-field`;
    return html`<div class="copy-link-row">
      <gr-copy-clipboard
        text=${value}
        label=${label}
        shortcut=${`${this.shortcutPrefix}${shortcut}`}
        id=${`${id}-copy-clipboard`}
        nowrap
        ?multiline=${!!multiline}
        ${index === 0 && ref(this.copyClipboardRef)}
      ></gr-copy-clipboard>
    </div>`;
  }

  private async handleKeydown(e: KeyboardEvent) {
    const copyLink = this.copyLinks?.find(link => link.shortcut === e.key);
    if (!copyLink) return;
    await copyToClipboard(copyLink.value, copyLink.label);
    this.closeDropdown();
  }

  toggleDropdown(button?: HTMLElement) {
    if (button) {
      this.dropdown!.anchorElement = button;
    }
    this.isDropdownOpen ? this.closeDropdown() : this.openDropdown();
  }

  private closeDropdown() {
    this.dropdown?.close();
  }

  openDropdown(button?: HTMLElement) {
    if (button) {
      this.dropdown!.anchorElement = button;
    }
    this.dropdown?.show();
    this.awaitOpen(() => {
      if (!this.copyClipboardRef?.value) return;
      queryAndAssert<MdOutlinedTextField>(
        this.copyClipboardRef.value,
        'md-outlined-text-field'
      )?.select();
    });
  }

  /**
   * NOTE: (milutin) Slightly hacky way to listen to the overlay actually
   * opening. It's from gr-editable-label.
   */
  private awaitOpen(fn: () => void) {
    let iters = 0;
    const step = () => {
      setTimeout(() => {
        if (this.dropdown?.style.display !== 'none') {
          fn.call(this);
        } else if (iters++ < AWAIT_MAX_ITERS) {
          step.call(this);
        }
      }, AWAIT_STEP);
    };
    step.call(this);
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-copy-links': GrCopyLinks;
  }
}
