import { _ as _applyDecoratedDescriptor, a as _initializerDefineProperty, b as _defineProperty } from '../_rollupPluginBabelHelpers-9wjJaosZ.js';
import { setComponentTemplate } from '@ember/component';
import { precompileTemplate } from '@ember/template-compilation';
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { get, fn } from '@ember/helper';
import { on } from '@ember/modifier';
import { action } from '@ember/object';
import didInsert from '@ember/render-modifiers/modifiers/did-insert';
import { inject } from '@ember/service';
import optional from 'ember-composable-helpers/helpers/optional';
import queue from 'ember-composable-helpers/helpers/queue';
import argOrDefault from '../helpers/arg-or-default.js';
import classNames from '../helpers/class-names.js';
import Timer from '../utils/timer.js';
import EuiToast from './eui-toast.js';

var _class, _descriptor, _descriptor2;
const TOAST_FADE_OUT_MS = 250;
let EuiGlobalToastList = setComponentTemplate(precompileTemplate(`
    <div
      aria-live="polite"
      role="region"
      class={{classNames
        componentName="EuiGlobalToastList"
        side=(argOrDefault @side "right")
      }}
      style={{unless this.euiToaster.toasts.length "padding:0px;"}}
      {{didInsert this.didInsert}}
      {{on "scroll" this.onScroll}}
      {{on "mouseenter" this.onMouseEnter}}
      {{on "mouseleave" this.onMouseLeave}}
      ...attributes
    >
      {{#each this.euiToaster.toasts as |toast|}}
        <EuiToast
          class={{classNames
            "euiGlobalToastListItem"
            (if
              (get this.toastIdToDismissedMap toast.id)
              "euiGlobalToastListItem-isDismissed"
            )
          }}
          @title={{toast.title}}
          @useMarkdownFormat={{toast.useMarkdownFormat}}
          @body={{toast.body}}
          @color={{toast.color}}
          @iconType={{toast.iconType}}
          @onClose={{queue
            (fn this.dismissToast toast)
            (optional toast.onClose)
          }}
          {{didInsert (fn this.didInsertToast toast)}}
          {{on "focus" this.onMouseEnter}}
          {{on "blur" this.onMouseLeave}}
        />
      {{/each}}
    </div>
  `, {
  strictMode: true,
  scope: () => ({
    classNames,
    argOrDefault,
    didInsert,
    on,
    EuiToast,
    get,
    queue,
    fn,
    optional
  })
}), (_class = class EuiGlobalToastList extends Component {
  startScrollingToBottom() {
    this.isScrollingToBottom = true;
    const scrollToBottom = () => {
      // Although we cancel the requestAnimationFrame in componentWillUnmount,
      // it's possible for this.listElement to become null in the meantime
      if (!this.listElement) {
        return;
      }
      const position = this.listElement.scrollTop;
      const destination = this.listElement.scrollHeight - this.listElement.clientHeight;
      const distanceToDestination = destination - position;
      if (distanceToDestination < 5) {
        this.listElement.scrollTop = destination;
        this.isScrollingToBottom = false;
        this.isScrolledToBottom = true;
        return;
      }
      this.listElement.scrollTop = position + distanceToDestination * 0.25;
      if (this.isScrollingToBottom) {
        this.isScrollingAnimationFrame = window.requestAnimationFrame(scrollToBottom);
      }
    };
    this.startScrollingAnimationFrame = window.requestAnimationFrame(scrollToBottom);
  }
  didInsertToast(toast) {
    this.scheduleToastForDismissal(toast);
    if (!this.isUserInteracting) {
      // If the user has scrolled up the toast list then we don't want to annoy them by scrolling
      // all the way back to the bottom.
      if (this.isScrolledToBottom) {
        this.startScrollingToBottom();
      }
    }
  }
  onMouseEnter() {
    // Stop scrolling to bottom if we're in mid-scroll, because the user wants to interact with
    // the list.
    this.isScrollingToBottom = false;
    this.isUserInteracting = true;

    // Don't let toasts dismiss themselves while the user is interacting with them.
    for (const toastId in this.toastIdToTimerMap) {
      if (this.toastIdToTimerMap.hasOwnProperty(toastId)) {
        const timer = this.toastIdToTimerMap[toastId];
        timer?.pause();
      }
    }
  }
  onMouseLeave() {
    this.isUserInteracting = false;
    for (const toastId in this.toastIdToTimerMap) {
      if (this.toastIdToTimerMap.hasOwnProperty(toastId)) {
        const timer = this.toastIdToTimerMap[toastId];
        timer?.resume();
      }
    }
  }
  onScroll() {
    if (this.listElement) {
      this.isScrolledToBottom = this.listElement.scrollHeight - this.listElement.scrollTop === this.listElement.clientHeight;
    }
  }
  scheduleAllToastsForDismissal() {
    this.euiToaster.toasts.forEach(toast => {
      if (!this.toastIdToTimerMap[toast.id]) {
        this.scheduleToastForDismissal(toast);
      }
    });
  }
  scheduleToastForDismissal(toast) {
    // Start fading the toast out once its lifetime elapses.
    this.toastIdToTimerMap[toast.id] = new Timer(this.dismissToast.bind(this, toast), toast.toastLifeTimeMs != null ? toast.toastLifeTimeMs : this.args.toastLifeTimeMs);
  }
  dismissToast(toast) {
    // Remove the toast after it's done fading out.
    this.dismissTimeoutIds.push(window.setTimeout(() => {
      // Because this is wrapped in a setTimeout, and because React does not guarantee when
      // state updates happen, it is possible to double-dismiss a toast
      // including by double-clicking the "x" button on the toast
      // so, first check to make sure we haven't already dismissed this toast
      if (this.toastIdToTimerMap.hasOwnProperty(toast.id)) {
        if (this.args.dismissToast) {
          this.args.dismissToast.apply(this, [toast]);
        }
        this.toastIdToTimerMap[toast.id].clear();
        delete this.toastIdToTimerMap[toast.id];
        delete this.toastIdToDismissedMap[toast.id];
        this.toastIdToDismissedMap = {
          ...this.toastIdToDismissedMap
        };
        this.euiToaster.remove(toast);
      }
    }, TOAST_FADE_OUT_MS));
    this.toastIdToDismissedMap = {
      ...this.toastIdToDismissedMap,
      [toast.id]: true
    };
  }
  constructor(owner, args) {
    super(owner, args);
    _initializerDefineProperty(this, "euiToaster", _descriptor, this);
    _defineProperty(this, "dismissTimeoutIds", []);
    _defineProperty(this, "toastIdToTimerMap", {});
    _defineProperty(this, "isScrollingToBottom", false);
    _defineProperty(this, "isScrolledToBottom", true);
    _defineProperty(this, "isUserInteracting", false);
    // See [Return Value](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestAnimationFrame#Return_value)
    // for information on initial value of 0
    _defineProperty(this, "isScrollingAnimationFrame", 0);
    _defineProperty(this, "startScrollingAnimationFrame", 0);
    _defineProperty(this, "listElement", null);
    _initializerDefineProperty(this, "toastIdToDismissedMap", _descriptor2, this);
    this.scheduleAllToastsForDismissal();
  }
  didInsert(element) {
    this.listElement = element;
  }
  willDestroy() {
    super.willDestroy();
    if (this.isScrollingAnimationFrame !== 0) {
      window.cancelAnimationFrame(this.isScrollingAnimationFrame);
    }
    if (this.startScrollingAnimationFrame !== 0) {
      window.cancelAnimationFrame(this.startScrollingAnimationFrame);
    }
    this.dismissTimeoutIds.forEach(clearTimeout);
    for (const toastId in this.toastIdToTimerMap) {
      if (this.toastIdToTimerMap.hasOwnProperty(toastId)) {
        const timer = this.toastIdToTimerMap[toastId];
        timer?.clear();
      }
    }
  }
}, (_descriptor = _applyDecoratedDescriptor(_class.prototype, "euiToaster", [inject], {
  configurable: true,
  enumerable: true,
  writable: true,
  initializer: null
}), _descriptor2 = _applyDecoratedDescriptor(_class.prototype, "toastIdToDismissedMap", [tracked], {
  configurable: true,
  enumerable: true,
  writable: true,
  initializer: function () {
    return {};
  }
}), _applyDecoratedDescriptor(_class.prototype, "didInsertToast", [action], Object.getOwnPropertyDescriptor(_class.prototype, "didInsertToast"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "onMouseEnter", [action], Object.getOwnPropertyDescriptor(_class.prototype, "onMouseEnter"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "onMouseLeave", [action], Object.getOwnPropertyDescriptor(_class.prototype, "onMouseLeave"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "onScroll", [action], Object.getOwnPropertyDescriptor(_class.prototype, "onScroll"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "scheduleToastForDismissal", [action], Object.getOwnPropertyDescriptor(_class.prototype, "scheduleToastForDismissal"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "dismissToast", [action], Object.getOwnPropertyDescriptor(_class.prototype, "dismissToast"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "didInsert", [action], Object.getOwnPropertyDescriptor(_class.prototype, "didInsert"), _class.prototype)), _class));

export { EuiGlobalToastList as default };
//# sourceMappingURL=eui-global-toast-list.js.map
