import { LitElement, html, type TemplateResult } from 'lit'
import { customElement, property, state } from 'lit/decorators.js'
import { bound } from '../decorators/bound.js'
import type { HelpServiceController } from './help_service_controller.js'
import type { HelpTopic } from './help_topic.js'
import './help_panel.js'

export interface HelpRequestDetail {
  /**
   * The category of the help request, which determines where to look for help content.
   */
  category: string
  /**
   * The ID of the help request, which identifies the specific help topic.
   */
  id: string
  /**
   * The target element that triggered the help request.
   * This can be used to position the help panel relative to the element.
   */
  target: HTMLElement
}

/**
 * The main coordinator for the help system.
 * This element should be placed once in your application root and will:
 * - Listen for help requests from anywhere in the DOM
 * - Show/hide the help panel
 * - Coordinate between the help service and UI components
 *
 * It relies on the `HelpServiceController` to fetch and manage help topics.
 * Make sure to configure the `helpService` property with an instance of `HelpServiceController`.
 *
 * Usage:
 * ```ts
 * const helpServiceInstance = new HelpServiceController({
 *   categories: {
 *     property: '/help/property.yaml',
 *     entity: '/help/entity.yaml',
 *   },
 *   version: '1.0.0',
 * })
 * ```
 * ```html
 * <help-coordinator .helpService="${helpServiceInstance}"></help-coordinator>
 * ```
 */
@customElement('help-coordinator')
export class HelpCoordinator extends LitElement {
  /**
   * The help category of the current help request.
   * @attribute
   */
  @property({ type: String }) accessor category: string | undefined
  /**
   * The help ID of the current help request.
   * @attribute
   */
  @property({ type: String }) accessor helpId: string | undefined

  @property({ type: Object }) accessor topic: HelpTopic | undefined

  @state() private accessor opened = false
  /**
   * The element that triggered the help request.
   * This is used to position the help panel relative to the triggering element.
   * Might not always be set, depending on how the help request is triggered.
   */
  @state() private accessor trigger: HTMLElement | undefined

  /**
   * The help service controller instance.
   * This should be configured with the appropriate categories and version.
   */
  @property({ type: Object }) accessor helpService: HelpServiceController | undefined

  override connectedCallback(): void {
    super.connectedCallback()
    // Listen for help requests from anywhere in the application
    document.addEventListener('request-help', this.handleHelpRequest)
    // Note: Escape key handling is now automatic with popover API
  }

  override disconnectedCallback(): void {
    super.disconnectedCallback()
    document.removeEventListener('request-help', this.handleHelpRequest)
  }

  @bound
  private async handleHelpRequest(event: Event): Promise<void> {
    if (event.defaultPrevented) {
      return
    }
    const service = this.helpService
    if (!service) {
      // eslint-disable-next-line no-console
      console.warn('Help service not configured')
      return
    }
    const customEvent = event as CustomEvent<HelpRequestDetail>
    const { category, id, target } = customEvent.detail
    this.requestTopic(category, id, target)
    // Prevent further propagation to avoid multiple handlers
    event.stopPropagation()
  }

  async requestTopic(category: string, id: string, trigger: HTMLElement): Promise<void> {
    const service = this.helpService
    if (!service) {
      // eslint-disable-next-line no-console
      console.warn('Help service not configured')
      return
    }
    if (!service.initialized) {
      await service.untilReady
    }
    const topic = await service.getTopic(category, id)
    if (topic) {
      this.topic = topic
      this.opened = true
      this.trigger = trigger
    } else {
      this.showHelpNotAvailable(category, id)
    }
    this.trackHelpUsage(category, id)
  }

  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  private trackHelpUsage(category: string, id: string): void {
    // TODO: Implement analytics tracking here
  }

  private showHelpNotAvailable(category: string, id: string): void {
    this.topic = {
      id: 'not-found',
      category: 'general',
      title: 'Help Not Available',
      body: `Sorry, help content for **${category}::${id}** is not available yet.

Please check back later or contact support if you need assistance with this feature.`,
      links: [
        { text: 'Contact Support', url: '/support' },
        { text: 'Documentation', url: '/docs' },
      ],
    }
    this.opened = true
  }

  protected handleClose(): void {
    this.opened = false
  }

  override render(): TemplateResult {
    return html`<help-panel
      class="panel"
      .opened="${this.opened}"
      .topic="${this.topic}"
      .trigger="${this.trigger}"
      @close="${this.handleClose}"
    ></help-panel>`
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'help-coordinator': HelpCoordinator
  }
}
