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

/**
 * A dialog to render and edit the Email taxonomy semantic on a domain property.
 */
export class EmailTaxonomy extends TaxonomyDialog<EmailConfig> {
  static override title = `Configure Email Taxonomy`

  constructor(public domainElement: DomainProperty) {
    let config: EmailConfig
    const semantic = domainElement.semantics.find((s) => s.id === SemanticType.Email)
    if (semantic && semantic.config) {
      config = structuredClone(semantic.config) as EmailConfig
    } else {
      config = {}
    }
    super(config)
  }

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

  handleAllowedDomainsChange(event: Event): void {
    const input = event.target as HTMLInputElement
    const value = input.value.trim()
    if (value) {
      const domains = this.config?.allowedDomains ?? DEFAULT_EMAIL_CONFIG.allowedDomains ?? []
      if (!domains.includes(value)) {
        domains.push(value)
        this.config = { ...this.config, allowedDomains: domains }
        this.requestUpdate()
      }
      input.value = '' // Clear the input after adding
    }
  }

  handleRemoveDomain(event: Event): void {
    const chip = event.target as HTMLElement
    const index = parseInt(chip.dataset.index || '0', 10)
    if (!isNaN(index) && this.config?.allowedDomains) {
      this.config.allowedDomains.splice(index, 1)
      this.requestUpdate()
    }
  }

  @bound
  render(): TemplateResult {
    return html`
      <div class="checkbox-group">
        ${this.renderAllowSubaddresses()} ${this.renderAllowInternational()} ${this.renderRequireVerification()}
      </div>
      <div class="input-group">${this.renderAllowedDomainsInput()}</div>
    `
  }

  protected renderAllowSubaddresses(): TemplateResult {
    const enabled = this.config?.allowSubaddressing ?? DEFAULT_EMAIL_CONFIG.allowSubaddressing
    return html`
      <div class="row">
        <div class="input checkbox metadata">
          <ui-checkbox
            id="allow-subaddresses"
            name="allowSubaddresses"
            .checked="${enabled}"
            @change="${this.handleBooleanChange}"
          >
          </ui-checkbox>
          <div class="label">
            <label for="allow-subaddresses" class="body-medium">Allow Subaddresses</label>
            <span class="body-small meta">Whether to allow emails like <code>user+tag@domain.com</code>.</span>
          </div>
        </div>
        ${renderHelp('taxonomy', 'email:allowSubaddressing')}
      </div>
    `
  }

  protected renderAllowInternational(): TemplateResult {
    const enabled = this.config?.allowInternational ?? DEFAULT_EMAIL_CONFIG.allowInternational
    return html`
      <div class="row">
        <div class="input checkbox metadata">
          <ui-checkbox
            id="allow-international"
            name="allowInternational"
            .checked="${enabled}"
            @change="${this.handleBooleanChange}"
          >
          </ui-checkbox>
          <div class="label">
            <label for="allow-international" class="body-medium">Allow International Characters</label>
            <span class="body-small meta">Whether to allow non-ASCII characters in email addresses.</span>
          </div>
        </div>
        ${renderHelp('taxonomy', 'email:allowInternational')}
      </div>
    `
  }

  protected renderRequireVerification(): TemplateResult {
    const enabled = this.config?.requireVerification ?? DEFAULT_EMAIL_CONFIG.requireVerification
    return html`
      <div class="row">
        <div class="input checkbox metadata">
          <ui-checkbox
            id="require-verification"
            name="requireVerification"
            .checked="${enabled}"
            @change="${this.handleBooleanChange}"
          >
          </ui-checkbox>
          <div class="label">
            <label for="require-verification" class="body-medium">Require Email Verification</label>
            <span class="body-small meta">Whether to require email verification for new users.</span>
          </div>
        </div>
        ${renderHelp('taxonomy', 'email:requireVerification')}
      </div>
    `
  }

  protected renderAllowedDomainsInput(): TemplateResult {
    const value = this.config?.allowedDomains ?? DEFAULT_EMAIL_CONFIG.allowedDomains
    const chips = (value || []).map(
      (domain, index) =>
        html`<ui-chip type="input" removable data-index="${index}" @remove="${this.handleRemoveDomain}"
          >${domain}</ui-chip
        >`
    )
    return html`
      <div class="row input-row">
        <div class="input chips-input">
          <ui-outlined-text-field
            class="input"
            name="allowedDomains"
            label="Allowed Domains (optional)"
            @change="${this.handleAllowedDomainsChange}"
            supportingText="Add a domain and press Enter to add it to the list."
          ></ui-outlined-text-field>
          <ui-chip-set>${chips}</ui-chip-set>
        </div>
        ${renderHelp('taxonomy', 'email:allowedDomains')}
      </div>
    `
  }
}
