/**
 * @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 {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners';
import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin';
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, property} from '@polymer/decorators';
import {IronOverlayBehavior} from '@polymer/iron-overlay-behavior/iron-overlay-behavior';
import {findActiveElement} from '../../../utils/dom-util';

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(
  GestureEventListeners(LegacyElementMixin(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
   */

  @property({type: Boolean})
  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';
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    return (window.Polymer as any).IronFocusablesHelper.getTabbableNodes(this);
  }

  /** @override */
  created() {
    super.created();
    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((resolve, reject) => {
      super.open.apply(this);
      if (this._isMobile()) {
        this.dispatchEvent(
          new CustomEvent('fullscreen-overlay-opened', {
            composed: true,
            bubbles: true,
          })
        );
        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) {
      this.dispatchEvent(
        new CustomEvent('fullscreen-overlay-closed', {
          composed: true,
          bubbles: true,
        })
      );
      this._fullScreenOpen = false;
    }
    if (this.returnFocusTo) {
      this.returnFocusTo.focus();
      this.returnFocusTo = undefined;
    }
  }

  /**
   * 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 = () => {
      this.async(() => {
        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;
}
