// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import {assert} from 'chrome://resources/js/assert_ts.js';
import {CustomElement} from 'chrome://resources/js/custom_element.js';
import {listenOnce} from 'chrome://resources/js/util_ts.js';

import {getTemplate} from './snackbar.html.js';

/**
 * Javascript for Snackbar controls, served from chrome://bluetooth-internals/.
 */

/**
 * @typedef {{
 *    message: string,
 *    type: string,
 *    actionText: (string|undefined),
 *    action: (function()|undefined)
 *  }}
 */
let SnackbarOptions;

/** @type {number} */ const SHOW_DURATION = 5000;
/** @type {number} */ const TRANSITION_DURATION = 225;

/**
 * Enum of Snackbar types. Used by Snackbar to determine the styling for the
 * Snackbar.
 * @enum {string}
 */
export const SnackbarType = {
  INFO: 'info',
  SUCCESS: 'success',
  WARNING: 'warning',
  ERROR: 'error',
};

/**
 * Notification bar for displaying a simple message with an action link.
 * This element should not be instantiated directly. Instead, users should
 * use the showSnackbar and dismissSnackbar functions to ensure proper
 * queuing of messages.
 */
class BluetoothSnackbarElement extends CustomElement {
  static get template() {
    return getTemplate();
  }

  static get is() {
    return 'bluetooth-snackbar';
  }

  constructor() {
    super();

    /** @type {?Function} */
    this.boundStartTimeout_ = null;

    /** @type {?Function} */
    this.boundStopTimeout_ = null;

    /** @type {?number} */
    this.timeoutId_ = null;

    /** @type {?SnackbarOptions} */
    this.options_ = null;
  }

  connectedCallback() {
    assert(this.options_);

    this.shadowRoot.querySelector('#message').textContent =
        this.options_.message;
    this.classList.add(this.options_.type);
    const actionLink = this.shadowRoot.querySelector('a');
    actionLink.textContent = this.options_.actionText || 'Dismiss';

    actionLink.addEventListener('click', () => {
      if (this.options_.action) {
        this.options_.action();
      }
      this.dismiss();
    });

    this.boundStartTimeout_ = this.startTimeout_.bind(this);
    this.boundStopTimeout_ = this.stopTimeout_.bind(this);
    this.addEventListener('mouseleave', this.boundStartTimeout_);
    this.addEventListener('mouseenter', this.boundStopTimeout_);

    this.timeoutId_ = null;
  }

  /**
   * Initializes the content of the Snackbar with the given |options|
   * including the message, action link text, and click action of the link.
   * This must be called before the element is added to the DOM.
   * @param {!SnackbarOptions} options
   */
  initialize(options) {
    this.options_ = options;
  }

  /**
   * Shows the Snackbar and dispatches the 'showed' event.
   */
  show() {
    this.classList.add('open');
    if (hasContentFocus) {
      this.startTimeout_();
    } else {
      this.stopTimeout_();
    }

    document.addEventListener('contentfocus', this.boundStartTimeout_);
    document.addEventListener('contentblur', this.boundStopTimeout_);
    this.dispatchEvent(
        new CustomEvent('showed', {bubbles: true, composed: true}));
  }
  /**
   * transitionend does not always fire (e.g. when animation is aborted
   * or when no paint happens during the animation). This function sets up
   * a timer and emulate the event if it is not fired when the timer expires.
   * @private
   */
  ensureTransitionEndEvent_() {
    let fired = false;
    this.addEventListener('transitionend', function f(e) {
      this.removeEventListener('transitionend', f);
      fired = true;
    }.bind(this));
    window.setTimeout(() => {
      if (!fired) {
        this.dispatchEvent(new CustomEvent('transitionend',
              {bubbles: true, composed: true}));
      }
    }, TRANSITION_DURATION);
  }

  /**
   * Dismisses the Snackbar. Once the Snackbar is completely hidden, the
   * 'dismissed' event is fired and the returned Promise is resolved. If the
   * snackbar is already hidden, a resolved Promise is returned.
   * @return {!Promise}
   */
  dismiss() {
    this.stopTimeout_();

    if (!this.classList.contains('open')) {
      return Promise.resolve();
    }

    return new Promise(function(resolve) {
      listenOnce(this, 'transitionend', function() {
        this.dispatchEvent(new CustomEvent('dismissed'));
        resolve();
      }.bind(this));

      this.ensureTransitionEndEvent_();
      this.classList.remove('open');

      document.removeEventListener('contentfocus', this.boundStartTimeout_);
      document.removeEventListener('contentblur', this.boundStopTimeout_);
    }.bind(this));
  }

  /**
   * Starts the timeout for dismissing the Snackbar.
   * @private
   */
  startTimeout_() {
    this.timeoutId_ = setTimeout(function() {
      this.dismiss();
    }.bind(this), SHOW_DURATION);
  }

  /**
   * Stops the timeout for dismissing the Snackbar. Only clears the timeout
   * when the Snackbar is open.
   * @private
   */
  stopTimeout_() {
    if (this.classList.contains('open')) {
      clearTimeout(this.timeoutId_);
      this.timeoutId_ = null;
    }
  }
}

customElements.define('bluetooth-snackbar', BluetoothSnackbarElement);

/** @type {?BluetoothSnackbarElement} */
let current = null;

/** @type {!Array<!BluetoothSnackbarElement>} */
let queue = [];

/** @type {boolean} */
let hasContentFocus = true;

// There is a chance where the snackbar is shown but the content doesn't have
// focus. In this case, the current focus state must be tracked so the
// snackbar can pause the dismiss timeout.
document.addEventListener('contentfocus', function() {
  hasContentFocus = true;
});
document.addEventListener('contentblur', function() {
  hasContentFocus = false;
});

/**
 * @return {{current: ?BluetoothSnackbarElement, numPending: number}}
 */
export function getSnackbarStateForTest() {
  return {
    current: current,
    numPending: queue.length,
  };
}

/**
 * TODO(crbug.com/675299): Add ability to specify parent element to Snackbar.
 * Creates a Snackbar and shows it if one is not showing already. If a
 * Snackbar is already active, the next Snackbar is queued.
 * @param {string} message The message to display in the Snackbar.
 * @param {string=} opt_type A string determining the Snackbar type: info,
 *     success, warning, error. If not provided, info type is used.
 * @param {string=} opt_actionText The text to display for the action link.
 * @param {function()=} opt_action A function to be called when the user
 *     presses the action link.
 * @return {!BluetoothSnackbarElement}
 */
export function showSnackbar(message, opt_type, opt_actionText, opt_action) {
  const options = {
    message: message,
    type: opt_type || SnackbarType.INFO,
    actionText: opt_actionText,
    action: opt_action,
  };
  const newSnackbar = document.createElement('bluetooth-snackbar');
  newSnackbar.initialize(options);

  if (current) {
    queue.push(newSnackbar);
  } else {
    show(newSnackbar);
  }

  return newSnackbar;
}

window.showSnackbar = showSnackbar;

/**
 * TODO(crbug.com/675299): Add ability to specify parent element to Snackbar.
 * Creates a Snackbar and sets events for queuing the next Snackbar to show.
 * @param {!BluetoothSnackbarElement} snackbar
 */
function show(snackbar) {
  document.body.querySelector('#snackbar-container').appendChild(snackbar);

  snackbar.addEventListener('dismissed', function() {
    document.body.querySelector('#snackbar-container').removeChild(current);

    const newSnackbar = queue.shift();
    if (newSnackbar) {
      show(newSnackbar);
      return;
    }

    current = null;
  });

  current = snackbar;

  // Show the Snackbar after a slight delay to allow for a layout reflow.
  setTimeout(function() {
    snackbar.show();
  }, 10);
}

/**
 * Dismisses the Snackbar currently showing.
 * @param {boolean} clearQueue If true, clears the Snackbar queue before
 *     dismissing.
 * @return {!Promise}
 */
export function dismissSnackbar(clearQueue) {
  if (clearQueue) {
    queue = [];
  }
  if (current) {
    return current.dismiss();
  }
  return Promise.resolve();
}
