import { html, type TemplateResult, nothing } from 'lit'
import { property, state } from 'lit/decorators.js'
import { ApiEditor } from './ApiEditor.js'
import { apiActionKindToIcon } from '../lib/ui_mapping.js'
import type { ReadAction, ApiModel, DomainEntity, ExposedEntity } from '@api-client/core/browser.js'
import type { TabSelectionDetail } from '../../md/tabs/ui-tabs.js'

export default class ApiReadActionEditor extends ApiEditor {
  /**
   * Computed exposed entity being edited.
   */
  @state() accessor exposed: ExposedEntity | undefined
  /**
   * Computed domain entity that corresponds to the exposed entity being edited.
   */
  @state() accessor entity: DomainEntity | undefined
  /**
   * Computed read action definition being edited.
   */
  @state() accessor action: ReadAction | undefined
  /**
   * When true, shows a close button in the editor header.
   * @attribute
   */
  @property({ type: Boolean }) accessor showCloseButton = false
  /**
   * The currently active tab index.
   */
  @state() accessor activeTab = 0

  protected override setupModel(model?: ApiModel, domainKey?: string): void | Promise<void> {
    this.exposed = undefined
    this.entity = undefined
    this.action = undefined
    if (!model || !domainKey) {
      return
    }
    const exposed = model.exposes.find((exposed) => exposed.key === domainKey)
    this.exposed = exposed
    if (!exposed) {
      return
    }
    const domain = model.domain
    if (!domain) {
      return
    }
    const entity = domain.findEntity(exposed.entity.key, exposed.entity.domain)
    if (!entity) {
      return
    }
    this.entity = entity
    const action = exposed.actions.find((action) => action.kind === 'read')
    this.action = action
  }

  protected handleCloseButtonClick(): void {
    this.dispatchEvent(new Event('close'))
  }

  /**
   * Handles tab change events.
   */
  protected handleTabChange(e: CustomEvent<TabSelectionDetail>): void {
    this.activeTab = e.detail.index
  }

  protected handleConfigurationChange(): void {
    this.notifyChange()
  }

  protected override render(): TemplateResult | typeof nothing {
    if (!this.exposed || !this.entity || !this.action) {
      return nothing
    }
    return html`<div class="container">${this.renderHeader()} ${this.renderTabs()} ${this.renderTabContent()}</div>`
  }

  /**
   * Renders a template of the editor header.
   */
  protected renderHeader(): TemplateResult {
    const { entity } = this
    let label = 'Read action'
    if (entity) {
      label = entity.info.getLabel() + ': Read action'
    }
    return html`<div class="intro">
      <div class="header">
        <ui-icon>${apiActionKindToIcon('read')}</ui-icon>
        <span class="headline-medium">${label}</span>
        ${this.renderCloseButton()}
      </div>
      <div class="body-medium description">Read action allows reading a single resource schema.</div>
    </div>`
  }

  /**
   * Renders the tabs navigation.
   */
  protected renderTabs(): TemplateResult {
    return html`<ui-tabs
      class="tabs"
      .activeTabIndex="${this.activeTab}"
      @change="${this.handleTabChange}"
      priority="secondary"
    >
      <ui-tab>Access</ui-tab>
      <ui-tab>Limits</ui-tab>
    </ui-tabs>`
  }

  /**
   * Renders the content for the currently active tab.
   */
  protected renderTabContent(): TemplateResult | typeof nothing {
    if (!this.action) {
      return nothing
    }
    switch (this.activeTab) {
      case 0:
        return this.renderAccessTab()
      case 1:
        return this.renderLimitsTab()
      default:
        return nothing
    }
  }

  /**
   * Renders the Access tab content.
   */
  protected renderAccessTab(): TemplateResult {
    return html`<div class="config-section">
      <api-modeling-access-configuration
        .model="${this.model}"
        domainKey="${this.exposed?.key || ''}"
        operation="read"
        target="action"
        class="access-configuration"
        @change="${this.handleConfigurationChange}"
      ></api-modeling-access-configuration>
    </div>`
  }

  /**
   * Renders the Limits tab content.
   */
  protected renderLimitsTab(): TemplateResult {
    return html`<div class="config-section">
      <api-modeling-rate-limiting
        .model="${this.model}"
        domainKey="${this.exposed?.key || ''}"
        operation="read"
        target="action"
        class="rate-limiting-configuration"
        @change="${this.handleConfigurationChange}"
      ></api-modeling-rate-limiting>
    </div>`
  }

  /**
   * Renders the close button if the `showCloseButton` flag is set.
   */
  protected renderCloseButton(): TemplateResult | typeof nothing {
    if (!this.showCloseButton) {
      return nothing
    }
    return html`<ui-icon-button
      color="outlined"
      class="close-button"
      aria-label="Close editor"
      @click="${this.handleCloseButtonClick}"
    >
      <ui-icon icon="close"></ui-icon>
    </ui-icon-button>`
  }
}
