import type { DomainProperty } from '@api-client/core/modeling/DomainProperty.js'
import { bound } from '../../decorators/bound.js'
import { DEFAULT_STATUS_CONFIG, StatusConfig } from '@api-client/core/modeling/definitions/Status.js'
import { html, TemplateResult } from 'lit'
import { SemanticType } from '@api-client/core/modeling/Semantics.js'
import { renderHelp } from '../../help/render.js'
import { TaxonomyDialog } from './TaxonomyDialog.js'

import '../../md/chip/ui-chip-set.js'
import '../../md/chip/ui-chip.js'

/**
 * A class that generates a dialog that allows the user to configure the taxonomy of a status field.
 */
export class StatusTaxonomy extends TaxonomyDialog<StatusConfig> {
  static override title = `Configure Status Taxonomy`

  /**
   * The enum values defined for the property, if any.
   * These values take precedence over the default values defined in the StatusConfig.
   */
  propertyEnum?: string[]

  constructor(public domainElement: DomainProperty) {
    let config: StatusConfig
    const semantic = domainElement.semantics.find((s) => s.id === SemanticType.Status)
    if (semantic && semantic.config) {
      config = structuredClone(semantic.config as StatusConfig)
    } else {
      config = {} as StatusConfig
    }
    super(config)
    this.propertyEnum = domainElement.schema?.enum
  }

  protected override formCallback(event: Event): Promise<void> {
    const semantic = this.domainElement.semantics.find((s) => s.id === SemanticType.Status)
    if (semantic) {
      semantic.config = this.config
    } else {
      this.domainElement.semantics.push({
        id: SemanticType.Status,
        config: this.config,
      })
    }
    this.domainElement.domain.notifyChange()
    return super.formCallback(event)
  }

  @bound
  protected handleAllowedStatesChange(event: Event): void {
    const input = event.target as HTMLInputElement
    const value = input.value.trim()
    if (value) {
      const states = this.config?.allowedStates ?? DEFAULT_STATUS_CONFIG.allowedStates ?? []
      if (!states.includes(value)) {
        states.push(value)
        this.config = { ...this.config, allowedStates: states }
        this.requestUpdate()
      }
      input.value = ''
    }
  }

  @bound
  protected handleRemoveStatus(event: Event): void {
    const chip = event.currentTarget as HTMLElement
    const index = parseInt(chip.dataset.index || '-1', 10)
    if (index >= 0 && this.config?.allowedStates) {
      this.config.allowedStates.splice(index, 1)
      this.requestUpdate()
    }
  }

  @bound
  render(): TemplateResult {
    if (this.propertyEnum && this.propertyEnum.length > 0) {
      return html` <div class="content">${this.renderEnumSetMessage()}</div> `
    }
    return html`${this.renderIntro()}
      <div class="input-group">${this.renderAllowedStatesInput()}</div> `
  }

  protected renderIntro(): TemplateResult {
    return html`<div class="row">
        <span class="body-medium input">
          Define a list of valid states for this property (e.g., "Pending", "Active", "Completed"). This ensures data
          consistency and helps drive business workflows.
        </span>
        ${renderHelp('taxonomy', 'status:overview')}
      </div>
      <span class="body-medium">
        <strong>Note:</strong> If you define a list of "Enum Values" in the main property editor, that list will be used
        instead of the states defined here.
      </span>`
  }

  protected renderEnumSetMessage(): TemplateResult {
    return html`<div class="row">
      <span class="body-medium input">
        This property has a list of "Enum Values" defined in its main schema. Therefore, that list is being used as the
        source for allowed statuses.
      </span>
      ${renderHelp('taxonomy', 'status:enumIntegration')}
    </div>`
  }

  protected renderAllowedStatesInput(): TemplateResult {
    const value = this.config?.allowedStates ?? DEFAULT_STATUS_CONFIG.allowedStates
    const chips = (value || []).map(
      (state, index) =>
        html`<ui-chip type="input" removable data-index="${index}" @remove="${this.handleRemoveStatus}"
          >${state}</ui-chip
        >`
    )
    return html`
      <div class="row input-row">
        <div class="input chips-input">
          <ui-outlined-text-field
            class="input"
            name="allowedStates"
            label="Allowed States"
            @change="${this.handleAllowedStatesChange}"
            supportingText="Add a state and press Enter to add it to the list."
          ></ui-outlined-text-field>
          <ui-chip-set>${chips}</ui-chip-set>
        </div>
        ${renderHelp('taxonomy', 'status:allowedStates')}
      </div>
    `
  }
}
