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 { createDynamicSlimmer, InjectVegaSlimmer, MapToComponentField, MapToComponentMethod, methodPlaceholder, } from 'vega-slimmer/core';
import { ElementAppenderSlimmer } from '../../../../helpers/slimmers/element-appender/element-appender-slimmer';
import { getDeepActiveElementInShadow } from '../../../../utils/ui';
import { AriaDialogFocusableTrapSlimmer } from '../../../../helpers/slimmers/aria-dialog-focusable-trap-slimmer';
/**
 * The `VegaDropdownAppenderController` class is responsible for managing the visibility and
 * behavior of a dropdown component.
 */
export class VegaDropdownAppenderController extends ElementAppenderSlimmer {
  //TODO: make watchIsDropdownShow as a callback param to skip dropdown re-render.
  /**
   * This constructor initializes a dropdown component with various configuration options.
   */
  constructor() {
    super(() => this.generateShowConfigFactory(), () => this.trigger);
    this.ariaDialogFocusableTrapSlimmer = createDynamicSlimmer(VegaDropdownAppenderController, AriaDialogFocusableTrapSlimmer, [], [
      { mapFrom: 'show', mapTo: 'show' },
      { mapFrom: 'hide', mapTo: 'hide' },
      { mapFrom: 'ariaComponentDidLoad', mapTo: 'componentDidLoad' },
    ], [
      {
        // eslint-disable-next-line jsdoc/require-jsdoc
        triggerEl: () => this.host,
        // eslint-disable-next-line jsdoc/require-jsdoc
        dialogEl: () => this.renderer.getDropdownContentBoxRef(),
      },
    ]);
    this.lastFocusedElement = null;
  }
  /**
   * Component lifecycle - [componentDidLoad]{@link VegaPopover.connectedCallback}
   */
  connectedCallback() {
    methodPlaceholder();
  }
  /**
   * Component lifecycle - [componentDidLoad]{@link VegaPopover.disconnectedCallback}
   */
  disconnectedCallback() {
    methodPlaceholder();
  }
  /**
   * Component lifecycle - [componentDidRender]{@link VegaPopover.componentDidRender}
   */
  componentDidRender() {
    methodPlaceholder();
  }
  /**
   * This controller extends `ElementAppenderSlimmer`, which already uses `componentDidLoad`.
   * To avoid overriding the parent lifecycle mapping, we expose `ariaComponentDidLoad`
   * here and map it to `componentDidLoad` for the ARIA slimmer.
   */
  ariaComponentDidLoad() {
    methodPlaceholder();
  }
  /**
   * The function `watchIsDropdownShow` checks if the dropdown is shown and performs certain actions
   * based on the result.
   */
  async watchIsDropdownShow() {
    if (this.isDropdownShow) {
      this.showEventEmitter.emit();
      this.updateLastFocusedElement();
    }
    else {
      this.searchRenderer.clear();
      this.hideEventEmitter.emit();
      this.focusTriggerForAria();
    }
  }
  /**
   * The function `userShow` checks if a dropdown is not already shown and then calls the `show`
   * function.
   */
  userShow() {
    if (!this.isDropdownShow) {
      this.show();
    }
  }
  /**
   * The function `userHide` hides a dropdown if it is currently being shown.
   */
  userHide() {
    if (this.isDropdownShow) {
      this.hide();
    }
  }
  /**
   * Restores focus to the dropdown trigger element.
   * Should be called after programmatic hide actions (item selection, Escape, reset)
   * to maintain proper screen reader context per WAI-ARIA menu button pattern.
   */
  focusTriggerForAria() {
    const activeEl = getDeepActiveElementInShadow();
    if ((activeEl === null || activeEl === void 0 ? void 0 : activeEl.matches) && activeEl.matches(':focus-visible')) {
      const triggerEl = this.lastFocusedElement;
      if (triggerEl && typeof triggerEl.focus === 'function') {
        triggerEl.focus();
        this.lastFocusedElement = null;
      }
    }
  }
  /**
   * Updates the last focused element by getting the currently active element in the shadow DOM.
   */
  updateLastFocusedElement() {
    this.lastFocusedElement = getDeepActiveElementInShadow();
  }
  /**
   * Generate the show configuration for the dropdown.
   *
   * @returns {ElementAppenderShowConfig} The show configuration for the dropdown.
   */
  generateShowConfigFactory() {
    return {
      target: this.target || this.host,
      appendableElement: this.renderer.getDropdownContentBoxRef(),
      positionRelativeTo: this.positionRelativeTo,
      matchTargetWidth: this.matchTargetWidth,
      matchContainerHeight: this.matchContainerHeight,
      size: this.size,
      minWidth: this.minWidth,
      maxWidth: this.maxWidth,
      translocation: this.translocation,
      maxHeight: this.maxHeight,
      placement: this.placement,
      alignment: this.alignment,
      isScreenPosition: this.isScreenPosition,
    };
  }
}
__decorate([
  MapToComponentField()
], VegaDropdownAppenderController.prototype, "host", void 0);
__decorate([
  MapToComponentField()
], VegaDropdownAppenderController.prototype, "trigger", void 0);
__decorate([
  MapToComponentField({ writable: true })
], VegaDropdownAppenderController.prototype, "isDropdownShow", void 0);
__decorate([
  MapToComponentField()
], VegaDropdownAppenderController.prototype, "positionRelativeTo", void 0);
__decorate([
  MapToComponentField()
], VegaDropdownAppenderController.prototype, "matchTargetWidth", void 0);
__decorate([
  MapToComponentField()
], VegaDropdownAppenderController.prototype, "matchContainerHeight", void 0);
__decorate([
  MapToComponentField()
], VegaDropdownAppenderController.prototype, "size", void 0);
__decorate([
  MapToComponentField()
], VegaDropdownAppenderController.prototype, "minWidth", void 0);
__decorate([
  MapToComponentField()
], VegaDropdownAppenderController.prototype, "maxWidth", void 0);
__decorate([
  MapToComponentField()
], VegaDropdownAppenderController.prototype, "translocation", void 0);
__decorate([
  MapToComponentField()
], VegaDropdownAppenderController.prototype, "maxHeight", void 0);
__decorate([
  MapToComponentField()
], VegaDropdownAppenderController.prototype, "placement", void 0);
__decorate([
  MapToComponentField()
], VegaDropdownAppenderController.prototype, "alignment", void 0);
__decorate([
  MapToComponentField()
], VegaDropdownAppenderController.prototype, "renderer", void 0);
__decorate([
  MapToComponentField()
], VegaDropdownAppenderController.prototype, "searchRenderer", void 0);
__decorate([
  MapToComponentField()
], VegaDropdownAppenderController.prototype, "showEventEmitter", void 0);
__decorate([
  MapToComponentField()
], VegaDropdownAppenderController.prototype, "hideEventEmitter", void 0);
__decorate([
  MapToComponentField()
], VegaDropdownAppenderController.prototype, "isScreenPosition", void 0);
__decorate([
  InjectVegaSlimmer()
], VegaDropdownAppenderController.prototype, "ariaDialogFocusableTrapSlimmer", void 0);
__decorate([
  MapToComponentMethod('connectedCallback')
], VegaDropdownAppenderController.prototype, "connectedCallback", null);
__decorate([
  MapToComponentMethod('disconnectedCallback')
], VegaDropdownAppenderController.prototype, "disconnectedCallback", null);
__decorate([
  MapToComponentMethod('componentDidRender')
], VegaDropdownAppenderController.prototype, "componentDidRender", null);
__decorate([
  MapToComponentMethod('componentDidLoad')
], VegaDropdownAppenderController.prototype, "ariaComponentDidLoad", null);
__decorate([
  MapToComponentMethod('watchIsDropdownShow')
], VegaDropdownAppenderController.prototype, "watchIsDropdownShow", null);
__decorate([
  MapToComponentMethod('show')
], VegaDropdownAppenderController.prototype, "userShow", null);
__decorate([
  MapToComponentMethod('hide')
], VegaDropdownAppenderController.prototype, "userHide", null);
