import Dropdown from "@home-assistant/webawesome/dist/components/dropdown/dropdown";
import { css, type CSSResultGroup } from "lit";
import { customElement, property } from "lit/decorators";
import type { HaDropdownItem } from "./ha-dropdown-item";
import type { HaIconButton } from "./ha-icon-button";

/**
 * Event type for the ha-dropdown component when an item is selected.
 * @param TValue - The type of the selected item's `value`.
 * @param TData - The type of the selected item's `data` when set on `ha-dropdown-item`.
 */
export type HaDropdownSelectEvent<TValue = string, TData = undefined> = [
  TData,
] extends [undefined]
  ? CustomEvent<{
      item: Omit<HaDropdownItem, "value"> & { value: TValue };
    }>
  : CustomEvent<{
      item: Omit<HaDropdownItem, "value"> & { value: TValue; data: TData };
    }>;

/**
 * Home Assistant dropdown component
 *
 * @element ha-dropdown
 * @extends {Dropdown}
 *
 * @summary
 * A stylable dropdown component supporting Home Assistant theming, variants, and appearances based on webawesome dropdown.
 *
 */
@customElement("ha-dropdown")
// @ts-ignore Allow to set an alternative anchor element
export class HaDropdown extends Dropdown {
  @property({ attribute: false }) dropdownTag = "ha-dropdown";

  @property({ attribute: false }) dropdownItemTag = "ha-dropdown-item";

  public get anchorElement(): HTMLButtonElement | HaIconButton | undefined {
    // @ts-ignore Allow to set an anchor element on popup
    return this.popup?.anchor as HTMLButtonElement | HaIconButton | undefined;
  }

  public set anchorElement(
    element: HTMLButtonElement | HaIconButton | undefined
  ) {
    // @ts-ignore Allow to get the current anchor element from popup
    if (!this.popup) {
      return;
    }

    // @ts-ignore
    if (this.popup.anchor && this.popup.anchor.localName === "ha-icon-button") {
      // @ts-ignore
      (this.popup.anchor as HaIconButton).selected = false;
    }

    // @ts-ignore Allow to get the current anchor element from popup
    this.popup.anchor = element;
  }

  /** Get the slotted trigger button, a <wa-button> or <button> element */
  // @ts-ignore Override parent method to be able to use alternative anchor
  // eslint-disable-next-line @typescript-eslint/naming-convention
  private override getTrigger(): HTMLButtonElement | HaIconButton | null {
    if (this.anchorElement) {
      return this.anchorElement;
    }
    // @ts-ignore fallback to default trigger slot if no anchorElement is set
    return super.getTrigger();
  }

  // @ts-ignore
  // eslint-disable-next-line @typescript-eslint/naming-convention
  private override async showMenu() {
    // @ts-ignore
    await super.showMenu();
    const triggerElement = this.getTrigger();
    if (triggerElement && triggerElement.localName === "ha-icon-button") {
      (triggerElement as HaIconButton).selected = true;
    }
  }

  // @ts-ignore
  // eslint-disable-next-line @typescript-eslint/naming-convention
  private override async hideMenu() {
    const triggerElement = this.getTrigger();
    if (triggerElement && triggerElement.localName === "ha-icon-button") {
      (triggerElement as HaIconButton).selected = false;
    }
    // @ts-ignore
    await super.hideMenu();
  }

  static get styles(): CSSResultGroup {
    return [
      Dropdown.styles,
      css`
        :host {
          font-size: var(--ha-dropdown-font-size, var(--ha-font-size-m));
          --wa-color-surface-raised: var(
            --card-background-color,
            var(--ha-dialog-surface-background, var(--mdc-theme-surface, #fff)),
          );
        }

        #menu {
          padding: var(--ha-space-1);
        }
        wa-popup::part(popup) {
          z-index: 200;
        }
      `,
    ];
  }
}

declare global {
  interface HTMLElementTagNameMap {
    "ha-dropdown": HaDropdown;
  }
}
