var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { MapToComponentField, MapToComponentMethod, methodPlaceholder } from 'vega-slimmer/core';
import { PageResizeObserverSlimmer } from '../../../../../helpers/slimmers/page-resize-observer-slimmer';
import { executeAfterTransition } from '../../../../../utils/effect';
import { FeatureFlag } from '../../../../../helpers/feature-control/feature-flag-controller';
import { checkIsVoiceOverClick, getFirstFocusableElement } from '../../../../../utils/ui';
export class VegaLeftNavOpenStateController extends PageResizeObserverSlimmer {
  /**
   * The below method is e2e-test covered in
   * @see{module:vega-left-nav-e2e-resize-with-desktop}
   */
  constructor() {
    /* eslint-disable jsdoc/require-jsdoc*/
    super({
      callback: /* istanbul ignore next */ () => {
        this.updateMainContentUI(this.openState);
      },
    });
    this.isVoiceOverClick = false;
    this.triggerElement = null;
    this.handleClickEvent = (e) => {
      this.isVoiceOverClick = checkIsVoiceOverClick(e);
    };
    /* eslint-enable jsdoc/require-jsdoc*/
  }
  /**
   * The below method is e2e-test covered in
   * @see{module:vega-left-nav-e2e-open-by-default}
   */
  /* istanbul ignore next */
  componentDidLoad() {
    if (this.open === true) {
      this.openState = 'open';
      if (FeatureFlag.isEnabled('VEGA_LEFT_NAV.DISABLE_ANIMATION_ON_LOAD')) {
        this.host.classList.add('disableAnimation');
      }
    }
    else {
      this.openState = 'close';
    }
    // eslint-disable-next-line no-restricted-globals
    window.addEventListener('click', this.handleClickEvent, { capture: true });
  }
  /**
   * Component lifecycle - [componentDidRender]
   */
  componentDidRender() {
    methodPlaceholder();
  }
  /** Call this method to toggle the left nav menu */
  async toggle() {
    if (this.openState === 'close') {
      // eslint-disable-next-line no-restricted-globals
      this.triggerElement = document.activeElement;
      this.openState = 'open';
    }
    else {
      this.openState = 'close';
    }
  }
  watchOpen(newOpenValue) {
    if (newOpenValue) {
      this.openState = 'open';
    }
    else {
      this.openState = 'close';
    }
  }
  watchOpenState(newState) {
    this.updateMainContentUI(newState);
    if (newState === 'open') {
      this.open = true;
    }
    else {
      this.open = false;
      if (FeatureFlag.isEnabled('VEGA_LEFT_NAV.DISABLE_ANIMATION_ON_LOAD') &&
        this.host.classList.contains('disableAnimation')) {
        this.host.classList.remove('disableAnimation');
      }
    }
    this.stateUpdateEventEmitter.emit(this.openState);
    if (newState === 'open') {
      this.focusFirstFocusableInDialog();
    }
    else {
      this.focusFirstFocusableOutsideDialog();
    }
  }
  watchShowAsOverlay() {
    this.updateMainContentUI(this.openState);
  }
  /**
   * The below method is e2e-test covered in
   * @see{module:vega-left-nav-e2e-vega-click-backdrop}
   */
  /* istanbul ignore next */
  setOpenState(openState) {
    this.openState = openState;
  }
  /**
   * Focuses the first focusable element within the left nav dialog when it is opened via VoiceOver.
   */
  focusFirstFocusableInDialog() {
    if (!this.isVoiceOverClick) {
      return;
    }
    const dialogElement = this.host;
    const focusableElement = getFirstFocusableElement(dialogElement);
    if (focusableElement) {
      executeAfterTransition(() => focusableElement.focus(), dialogElement, 300);
    }
  }
  /**
   * Focuses the triggering element when the left nav dialog is closed.
   * Falls back to the first focusable element outside the dialog if the trigger is unavailable.
   */
  focusFirstFocusableOutsideDialog() {
    var _a;
    const triggerEl = this.triggerElement;
    this.triggerElement = null;
    const dialogEl = this.host;
    if (triggerEl && triggerEl.isConnected) {
      const focusable = (_a = getFirstFocusableElement(triggerEl)) !== null && _a !== void 0 ? _a : triggerEl;
      focusable.focus();
      return;
    }
    const firstFocusable = this.findFirstFocusableOutside(dialogEl);
    firstFocusable && firstFocusable.focus();
  }
  findFirstFocusableOutside(excludeEl) {
    // eslint-disable-next-line no-restricted-globals
    const walk = (node) => {
      const children = Array.from(node.children);
      for (const child of children) {
        if (child === excludeEl || excludeEl.contains(child)) {
          continue;
        }
        if (child.contains(excludeEl)) {
          const found = walk(child);
          if (found)
            return found;
          continue;
        }
        const focusable = getFirstFocusableElement(child);
        if (focusable)
          return focusable;
      }
      return null;
    };
    // eslint-disable-next-line no-restricted-globals
    return walk(document.body);
  }
  /**
   * The below method is e2e-test covered in
   * @see{module:vega-left-nav-e2e-resize-with-desktop}
   */
  /* istanbul ignore next */
  updateMainContentUI(state) {
    // eslint-disable-next-line no-restricted-globals
    const bodyElement = document.querySelector('body');
    // eslint-disable-next-line no-restricted-globals
    const mainContent = document.querySelector('vega-left-nav + .vega-left-nav-content');
    if (state === 'open') {
      this.host.style.display = 'flex';
      setTimeout(() => {
        this.host.classList.add('open');
        if (mainContent && !this.backdropController.shouldShowBackdrop()) {
          bodyElement === null || bodyElement === void 0 ? void 0 : bodyElement.classList.remove('vega-overflow-hidden');
          mainContent.classList.add('open');
        }
        else {
          bodyElement === null || bodyElement === void 0 ? void 0 : bodyElement.classList.add('vega-overflow-hidden');
          mainContent && mainContent.classList.remove('open');
        }
      });
    }
    else {
      this.host.classList.remove('open');
      bodyElement === null || bodyElement === void 0 ? void 0 : bodyElement.classList.remove('vega-overflow-hidden');
      mainContent && mainContent.classList.remove('open');
      executeAfterTransition(() => {
        if (!this.open) {
          this.host.style.display = 'none';
        }
      }, this.host);
    }
  }
}
__decorate([
  MapToComponentField()
], VegaLeftNavOpenStateController.prototype, "host", void 0);
__decorate([
  MapToComponentField({ writable: true })
], VegaLeftNavOpenStateController.prototype, "open", void 0);
__decorate([
  MapToComponentField({ writable: true })
], VegaLeftNavOpenStateController.prototype, "openState", void 0);
__decorate([
  MapToComponentField()
], VegaLeftNavOpenStateController.prototype, "stateUpdateEventEmitter", void 0);
__decorate([
  MapToComponentField()
], VegaLeftNavOpenStateController.prototype, "backdropController", void 0);
__decorate([
  MapToComponentMethod('componentDidLoad')
], VegaLeftNavOpenStateController.prototype, "componentDidLoad", null);
__decorate([
  MapToComponentMethod('componentDidRender')
], VegaLeftNavOpenStateController.prototype, "componentDidRender", null);
__decorate([
  MapToComponentMethod('toggle')
], VegaLeftNavOpenStateController.prototype, "toggle", null);
__decorate([
  MapToComponentMethod('watchOpen')
], VegaLeftNavOpenStateController.prototype, "watchOpen", null);
__decorate([
  MapToComponentMethod('watchOpenState')
], VegaLeftNavOpenStateController.prototype, "watchOpenState", null);
__decorate([
  MapToComponentMethod('watchShowAsOverlay')
], VegaLeftNavOpenStateController.prototype, "watchShowAsOverlay", null);
