/**
 * Copyright Aquera Inc 2026
 *
 * This source code is licensed under the BSD-3-Clause license found in the
 * LICENSE file in the root directory of this source tree.
 */

import { html, CSSResultArray, TemplateResult, nothing } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { styles } from './nile-context-menu-item.css';
import NileElement from '../internal/nile-element';

//Data passed to an item's `onSelect` callback. Matches the `nile-context-menu:select` event detail.
export interface NileContextMenuItemSelectDetail {
  id: string;
  value: string;
  name: string;
  target: Element | null;
  originalEvent: Event | null;
}

export type NileContextMenuItemSelectHandler = (
  detail: NileContextMenuItemSelectDetail
) => void;

/**
 * Nile context-menu item. A clickable entry inside `nile-context-menu`.
 *
 * @tag nile-context-menu-item
 *
 * @slot - Default slot for the visible label.
 * @slot icon - Optional leading icon (e.g. a `<nile-glyph slot="icon">`).
 */
@customElement('nile-context-menu-item')
export class NileContextMenuItem extends NileElement {
  public static get styles(): CSSResultArray {
    return [styles];
  }

  @property({ attribute: true, type: String, reflect: true }) value = '';

  @property({ attribute: true, type: Boolean, reflect: true }) disabled = false;

  public onSelect?: NileContextMenuItemSelectHandler;

  @state() private _hasSubmenu = false;

  @state() private _hasIcon = false;

  @state() private _submenuExpanded = false;

  public setSubmenuExpanded(expanded: boolean): void {
    this._submenuExpanded = expanded;
  }

  public override focus(options?: FocusOptions): void {
    const inner = this.shadowRoot?.querySelector('.item') as HTMLElement | null;
    inner?.focus(options);
  }

  public get hasSubmenu(): boolean {
    return this._hasSubmenu;
  }

  private _onSlotChange = (e: Event): void => {
    const slot = e.target as HTMLSlotElement;
    const nodes = slot.assignedElements({ flatten: true });
    this._hasSubmenu = nodes.some(
      n => n.tagName.toLowerCase() === 'nile-context-submenu'
    );
  };

  private _onIconSlotChange = (e: Event): void => {
    const slot = e.target as HTMLSlotElement;
    this._hasIcon = slot.assignedNodes({ flatten: true }).some(
      n => n.nodeType === Node.ELEMENT_NODE || (n.textContent ?? '').trim() !== ''
    );
  };

  public render(): TemplateResult {
    return html`
      <div
        part="item"
        class="item"
        role="menuitem"
        tabindex="-1"
        aria-disabled=${this.disabled ? 'true' : 'false'}
        aria-haspopup=${this._hasSubmenu ? 'menu' : nothing}
        aria-expanded=${this._hasSubmenu ? String(this._submenuExpanded) : nothing}
        data-has-submenu=${this._hasSubmenu ? 'true' : 'false'}
      >
        <span part="icon" class="icon" data-empty=${this._hasIcon ? 'false' : 'true'}>
          <slot name="icon" @slotchange=${this._onIconSlotChange}></slot>
        </span>
        <span part="label" class="label"><slot @slotchange=${this._onSlotChange}></slot></span>
        ${this._hasSubmenu
          ? html`<span part="chevron" class="chevron" aria-hidden="true">
              <nile-glyph name="ng-chevron-right" size="16"></nile-glyph>
            </span>`
          : ''}
      </div>
    `;
  }
}

export default NileContextMenuItem;

declare global {
  interface HTMLElementTagNameMap {
    'nile-context-menu-item': NileContextMenuItem;
  }
}
