import { html, LitElement, nothing, type TemplateResult } from 'lit'
import { icon } from '../utils/icon.ts'
import {
  isEditMode,
  LIST_EDIT_MODE_EVENT,
  toggleEditMode,
} from '../utils/list-edit-mode.ts'

/** Fired when "New List" is chosen from the menu. */
export const BOOKMARKS_NEW_LIST_EVENT = 'bookmarks-new-list'
/** Fired when "New Bookmark" is chosen from the menu. */
export const BOOKMARKS_NEW_BOOKMARK_EVENT = 'bookmarks-new-bookmark'
/** Fired when "Import Bookmarks" is chosen from the menu. */
export const BOOKMARKS_IMPORT_EVENT = 'bookmarks-import'

/**
 * Title bar for `/bookmarks`: the list/bookmark/import actions that used to
 * open a row of buttons above the list now live behind a single menu, so the
 * page itself starts with content. The page owns the forms and file input
 * these open — this only announces which one was picked.
 */
export class MBookmarksHeader extends LitElement {
  #menuOpen = false

  protected override createRenderRoot() {
    return this
  }

  #onEditModeChange = () => this.requestUpdate()

  override connectedCallback() {
    super.connectedCallback()
    document.addEventListener('click', this.#onDocumentClick)
    globalThis.addEventListener(LIST_EDIT_MODE_EVENT, this.#onEditModeChange)
  }

  override disconnectedCallback() {
    super.disconnectedCallback()
    document.removeEventListener('click', this.#onDocumentClick)
    globalThis.removeEventListener(
      LIST_EDIT_MODE_EVENT,
      this.#onEditModeChange,
    )
  }

  #toggleSelectMode = () => {
    toggleEditMode()
    this.#menuOpen = false
    this.requestUpdate()
  }

  // Any click that isn't inside the menu dismisses it.
  #onDocumentClick = (e: Event) => {
    if (!this.#menuOpen) return
    const menu = this.querySelector('.header-menu')
    if (menu && !e.composedPath().includes(menu)) {
      this.#menuOpen = false
      this.requestUpdate()
    }
  }

  #toggleMenu = (e: Event) => {
    e.stopPropagation()
    this.#menuOpen = !this.#menuOpen
    this.requestUpdate()
  }

  #choose(name: string) {
    globalThis.dispatchEvent(new CustomEvent(name))
    this.#menuOpen = false
    this.requestUpdate()
  }

  override render(): TemplateResult {
    return html`
      <h1>Bookmarks</h1>
      <div class="header-actions">
        <div class="header-menu">
          <button
            class="bm-icon-btn"
            aria-label="Bookmark actions"
            aria-expanded="${this.#menuOpen}"
            @click="${this.#toggleMenu}"
          >
            ${icon('more-vertical', '18px')}
          </button>
          ${this.#menuOpen
            ? html`
              <div class="header-menu-panel" role="menu">
                <button
                  class="header-menu-item"
                  role="menuitem"
                  @click="${() => this.#choose(BOOKMARKS_NEW_LIST_EVENT)}"
                >
                  New List
                </button>
                <button
                  class="header-menu-item"
                  role="menuitem"
                  @click="${() => this.#choose(BOOKMARKS_NEW_BOOKMARK_EVENT)}"
                >
                  New Bookmark
                </button>
                <button
                  class="header-menu-item"
                  role="menuitem"
                  @click="${() => this.#choose(BOOKMARKS_IMPORT_EVENT)}"
                >
                  Import Bookmarks
                </button>
                <button
                  class="header-menu-item"
                  role="menuitem"
                  @click="${this.#toggleSelectMode}"
                >
                  ${isEditMode() ? 'Cancel selection' : 'Select Bookmarks'}
                </button>
              </div>
            `
            : nothing}
        </div>
      </div>
    `
  }
}

customElements.define('m-bookmarks-header', MBookmarksHeader)
