/**
 * @license
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import '../../../styles/shared-styles';
import {PolymerElement} from '@polymer/polymer/polymer-element';
import {htmlTemplate} from './gr-overlay_html';
import {IronOverlayMixin} from '../../../mixins/iron-overlay-mixin/iron-overlay-mixin';
import {customElement} from '@polymer/decorators';
import {IronOverlayBehavior} from '@polymer/iron-overlay-behavior/iron-overlay-behavior';
import {findActiveElement} from '../../../utils/dom-util';
import {fireEvent} from '../../../utils/event-util';
import {getHovercardContainer} from '../gr-hovercard/gr-hovercard-behavior';

const AWAIT_MAX_ITERS = 10;
const AWAIT_STEP = 5;
const BREAKPOINT_FULLSCREEN_OVERLAY = '50em';

declare global {
  interface HTMLElementTagNameMap {
    'gr-overlay': GrOverlay;
  }
}

@customElement('gr-overlay')
export class GrOverlay extends IronOverlayMixin(
  PolymerElement,
  IronOverlayBehavior as IronOverlayBehavior
) {
  static get template() {
    return htmlTemplate;
  }

  /**
   * Fired when a fullscreen overlay is closed
   *
   * @event fullscreen-overlay-closed
   */

  /**
   * Fired when an overlay is opened in full screen mode
   *
   * @event fullscreen-overlay-opened
   */

  private fullScreenOpen = false;

  private _boundHandleClose: () => void = () => super.close();

  private focusableNodes?: Node[];

  private returnFocusTo?: HTMLElement;

  get _focusableNodes() {
    if (this.focusableNodes) {
      return this.focusableNodes;
    }
    // TODO(TS): to avoid ts error for:
    // Only public and protected methods of the base class are accessible
    // via the 'super' keyword.
    // we call IronFocsablesHelper directly here
    // Currently IronFocsablesHelper is not exported from iron-focusables-helper
    // as it should so we use Polymer.IronFocsablesHelper here instead
    // (can not use the IronFocsablesHelperClass
    // in case different behavior due to singleton)
    // once the type contains the exported member,
    // should replace with:
    // import {IronFocusablesHelper} from '@polymer/iron-overlay-behavior/iron-focusables-helper';
    return window.Polymer.IronFocusablesHelper.getTabbableNodes(this);
  }

  constructor() {
    super();
    this.addEventListener('iron-overlay-closed', () => this._overlayClosed());
    this.addEventListener('iron-overlay-cancelled', () =>
      this._overlayClosed()
    );
  }

  open() {
    this.returnFocusTo = findActiveElement(document, true) ?? undefined;
    window.addEventListener('popstate', this._boundHandleClose);
    return new Promise<void>((resolve, reject) => {
      super.open.apply(this);
      if (this._isMobile()) {
        fireEvent(this, 'fullscreen-overlay-opened');
        this.fullScreenOpen = true;
      }
      this._awaitOpen(resolve, reject);
    });
  }

  _isMobile() {
    return window.matchMedia(`(max-width: ${BREAKPOINT_FULLSCREEN_OVERLAY})`);
  }

  // called after iron-overlay is closed. Does not actually close the overlay
  _overlayClosed() {
    window.removeEventListener('popstate', this._boundHandleClose);
    if (this.fullScreenOpen) {
      fireEvent(this, 'fullscreen-overlay-closed');
      this.fullScreenOpen = false;
    }
    if (this.returnFocusTo) {
      this.returnFocusTo.focus();
      this.returnFocusTo = undefined;
    }
  }

  _onCaptureFocus(e: Event) {
    const hovercardContainer = getHovercardContainer();
    if (hovercardContainer) {
      // Hovercard container is not a child of an overlay.
      // When an overlay is opened and a user clicks inside hovercard,
      // the IronOverlayBehavior doesn't allow to set focus inside a hovercard.
      // As a result, user can't select a text (username) in the hovercard
      // in a dialog. We should skip default _onCaptureFocus for hovercards.
      const path = e.composedPath();
      if (path.indexOf(hovercardContainer) >= 0) return;
    }
    super._onCaptureFocus(e);
  }

  /**
   * Override the focus stops that iron-overlay-behavior tries to find.
   */
  setFocusStops(stops: GrOverlayStops) {
    this.focusableNodes = [stops.start, stops.end];
  }

  /**
   * NOTE: (wyatta) Slightly hacky way to listen to the overlay actually
   * opening. Eventually replace with a direct way to listen to the overlay.
   */
  _awaitOpen(fn: (this: GrOverlay) => void, reject: (error: Error) => void) {
    let iters = 0;
    const step = () => {
      setTimeout(() => {
        if (this.style.display !== 'none') {
          fn.call(this);
        } else if (iters++ < AWAIT_MAX_ITERS) {
          step.call(this);
        } else {
          reject(new Error('gr-overlay _awaitOpen failed to resolve'));
        }
      }, AWAIT_STEP);
    };
    step.call(this);
  }

  _id() {
    return this.getAttribute('id') || 'global';
  }
}

export interface GrOverlayStops {
  start: Node;
  end: Node;
}
