import { html, TemplateResult, LitElement } from 'lit'
import { property } from 'lit/decorators.js'
import { repeat } from 'lit/directives/repeat.js'
import { consume } from '@lit/context'
import type { UiMenuItemElement } from '../../../md/menu/ui-menu-item.js'
import { type IOrganization, organizationContext } from '../../../providers/organization.js'
import { organizationsContext } from '../../../providers/organizations.js'

/**
 * An element that allows selecting an organization from a list.
 * It renders a button with the current organization name that triggers a dropdown menu with available organizations.
 *
 * The component supports creating a new organization via a dedicated menu item.
 *
 * @example
 * ```html
 * <organization-selector
 *   .organization="${this.selectedOrg}"
 *   .organizations="${this.availableOrgs}"
 *   @select="${this.handleSelection}"
 *   @create="${this.handleCreate}"
 * ></organization-selector>
 * ```
 *
 * @fires select - Dispatched when the user selects an organization. The detail object contains the `organization` key.
 * @fires create - Dispatched when the user clicks on the "New Organization" menu item.
 */
export default class OrganizationSelector extends LitElement {
  /**
   * The currently selected organization, if any.
   * When set, the button label will show this organization's name.
   *
   * This property consumes the `organizationContext`.
   */
  @property({ type: Object, attribute: false })
  @consume({ context: organizationContext, subscribe: true })
  accessor organization: IOrganization | undefined

  /**
   * The list of available organizations to display in the dropdown menu.
   *
   * This property consumes the `organizationsContext`.
   */
  @property({ type: Array, attribute: false })
  @consume({ context: organizationsContext, subscribe: true })
  accessor organizations: IOrganization[] | undefined

  /**
   * A handler for organization selection from the menu.
   */
  protected handleOrgSelect(e: CustomEvent<{ item: UiMenuItemElement }>): void {
    const { item } = e.detail
    const { action = '' } = item.dataset
    if (action === 'select' && item.value) {
      this.notifySelect(item.value)
    } else if (action === 'new') {
      this.notifyCreate()
    }
  }

  /**
   * Notifies about organization selection.
   * @param organizationKey The key of the organization that was selected by the user.
   */
  protected notifySelect(organizationKey: string): void {
    this.dispatchEvent(
      new CustomEvent('select', {
        detail: { organization: organizationKey },
        bubbles: false,
        composed: false,
      })
    )
  }

  /**
   * Notifies about the request to create a new organization.
   */
  protected notifyCreate(): void {
    this.dispatchEvent(
      new CustomEvent('create', {
        bubbles: false,
        composed: false,
      })
    )
  }

  protected override render(): unknown {
    return html`${this.renderTrigger()} ${this.renderMenu()}`
  }

  protected renderTrigger(): TemplateResult {
    const { organization } = this
    const orgName = organization ? organization.name : 'Select Organization'
    return html`
      <ui-button
        id="org-selector-anchor"
        aria-label="Current organization: ${orgName}"
        trailingicon
        color="tonal"
        popovertarget="org-selector-menu"
      >
        ${orgName}
        <ui-icon slot="icon">arrow_drop_down</ui-icon>
      </ui-button>
    `
  }

  protected renderMenu(): TemplateResult {
    const { organization, organizations = [] } = this
    const orgKey = organization ? organization.key : ''
    return html`
      <ui-menu id="org-selector-menu" popover="auto" @select="${this.handleOrgSelect}">
        ${repeat(
          organizations,
          (org) => org.key,
          (org) =>
            html`<ui-menu-item
              showSelectionIcon
              data-action="select"
              value="${org.key}"
              ?selected="${org.key === orgKey}"
              ><div>${org.name}</div>
            </ui-menu-item>`
        )}
        <ui-divider role="separator"></ui-divider>
        <ui-menu-item data-action="new">
          <div>New Organization</div>
          <ui-icon slot="start">add</ui-icon>
        </ui-menu-item>
      </ui-menu>
    `
  }
}
