import { query } from "lit/decorators.js";
import { randomString } from "../../lib/Random.js";
import UiList from "./UiList.js";
import UiListItem from "./UiListItem.js";

/**
 * The listbox is used for lists from which a user may select one or more items which are static and, 
 * unlike HTML <select> elements, may contain images.
 * 
 * Note, this will automatically set `role` to `option` and `aria-selected` to `false` on each child
 * that is a valid list item.
 * 
 * TODO:
 * - define a checkbox item, space toggle a checkbox.
 */
export default class UiListbox extends UiList {
  @query('[aria-selected=true]') protected ariaSelectedElement?: UiListItem;

  override connectedCallback(): void {
    super.connectedCallback();
    this.setAttribute('role', 'listbox');
  }

  protected override updateItems(): void {
    super.updateItems();
    this.items.forEach(i => {
      if (!this.isListItem(i)) {
        return;
      }
      if (i.getAttribute('role') !== 'option') {
        i.setAttribute('role', 'option');
      }
      if (i.hasAttribute('aria-selected')) {
        i.setAttribute('aria-selected', 'false');
      }
    });
  }

  protected beforeActivation(): void {
    this.removeAttribute('aria-activedescendant');
    const active = this.ariaSelectedElement;
    if (active) {
      active.setAttribute('aria-selected', 'false');
    }
  }

  protected afterActivation(item?: UiListItem | null): void {
    if (!item) {
      return;
    }
    item.setAttribute('aria-selected', 'true');
    if (!item.id) {
      // eslint-disable-next-line no-param-reassign
      item.id = `option-${randomString(4)}`;
    }
    this.setAttribute('aria-activedescendant', item.id);
  }

  protected override highlightItem(item?: UiListItem): void {
    this.beforeActivation();
    super.highlightItem(item);
    this.afterActivation(this.highlightListItem);
  }

  protected override activateListItem(item: UiListItem): void {
    this.beforeActivation();
    super.activateListItem(item);
    this.afterActivation(this.activeListItem);
  }
}
