import { html, LitElement, type TemplateResult } from 'lit'
import { property } from 'lit/decorators.js'
import { live } from 'lit/directives/live.js'

/**
 * A simple input element for rendering a search input.
 *
 * @fires {CustomEvent} search - Fired when a search is initiated.
 * @fires {CustomEvent} clear - Fired when the search input is cleared.
 */
export default class SearchInput extends LitElement {
  static override shadowRootOptions: ShadowRootInit = {
    delegatesFocus: true,
    mode: 'open',
  }

  /**
   * The placeholder text for the search input.
   * @attribute
   */
  @property({ type: String }) accessor placeholder = 'Find'

  /**
   * The last value dispatched with the `search` event.
   */
  @property({ type: String }) accessor value: string | undefined

  protected handleKeyDown(e: KeyboardEvent): void {
    if (e.key === 'Enter') {
      e.preventDefault()
      const input = this.shadowRoot?.querySelector('.search-input') as HTMLInputElement
      this.notifySearch(input.value.trim())
    } else if (e.key === 'Escape') {
      e.preventDefault()
      this.value = ''
      this.dispatchEvent(new CustomEvent('clear', { bubbles: false, composed: false }))
    }
  }

  /**
   * Notifies the parent component that a search has been initiated.
   * @param input - The search input value.
   */
  protected notifySearch(input?: string): void {
    if (!input || input === this.value) {
      return
    }
    this.value = input
    this.dispatchEvent(
      new CustomEvent('search', {
        bubbles: false,
        composed: false,
        detail: { input },
      })
    )
  }

  protected override render(): TemplateResult {
    const icon = this.value ? 'arrow_back' : 'search'
    return html`
      <ui-focus-ring part="focus-ring" for="search-input"></ui-focus-ring>
      <ui-icon class="search-icon">${icon}</ui-icon>
      <input
        class="search-input body-large"
        id="search-input"
        type="text"
        placeholder="${this.placeholder}"
        autocomplete="off"
        @keydown="${this.handleKeyDown}"
        .value="${live(this.value || '')}"
      />
    `
  }
}
