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, nothing, TemplateResult } from 'lit'
import { renderHelp } from '../../help/render.js'
import { DEFAULT_PHONE_CONFIG, type PhoneConfig } from '@api-client/core/modeling/definitions/Phone.js'

export class PhoneTaxonomy extends TaxonomyDialog<PhoneConfig> {
  static override title = `Configure Phone Taxonomy`

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

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

  @bound
  handleAllowedCountriesChange(event: Event): void {
    const input = event.target as HTMLInputElement
    const value = input.value.trim()
    if (value) {
      const countries = this.config?.allowedCountries ?? DEFAULT_PHONE_CONFIG.allowedCountries ?? []
      if (!countries.includes(value)) {
        countries.push(value)
        this.config = { ...this.config, allowedCountries: countries }
        this.requestUpdate()
      }
      input.value = '' // Clear the input after adding
    }
  }

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

  @bound
  render(): TemplateResult {
    return html`
      <div class="checkbox-group">
        ${this.renderRequireCountryCode()} ${this.renderAllowExtension()} ${this.renderRequireVerification()}
      </div>
      <div class="input-group">
        ${this.renderVerificationMethodSelect()} ${this.renderFormatSelect()} ${this.renderCustomFormatInput()}
        ${this.renderAllowedCountriesInput()}
      </div>
    `
  }

  protected renderRequireCountryCode(): TemplateResult {
    const enabled = this.config?.requireCountryCode ?? DEFAULT_PHONE_CONFIG.requireCountryCode
    return html`
      <div class="row">
        <div class="input checkbox metadata">
          <ui-checkbox
            id="require-country-code"
            .checked="${enabled}"
            name="requireCountryCode"
            @change="${this.handleBooleanChange}"
          ></ui-checkbox>
          <div class="label">
            <label for="require-country-code" class="body-medium">Require Country Code</label>
            <span class="body-small meta">Users must include a country code in their phone numbers.</span>
          </div>
        </div>
        ${renderHelp('taxonomy', 'phone:requireCountryCode')}
      </div>
    `
  }

  protected renderAllowExtension(): TemplateResult {
    const enabled = this.config?.allowExtension ?? DEFAULT_PHONE_CONFIG.allowExtension
    return html`
      <div class="row">
        <div class="input checkbox metadata">
          <ui-checkbox
            id="allow-extension"
            .checked="${enabled}"
            name="allowExtension"
            @change="${this.handleBooleanChange}"
          ></ui-checkbox>
          <div class="label">
            <label for="allow-extension" class="body-medium">Allow Extension</label>
            <span class="body-small meta">Users can add an extension to their phone numbers.</span>
          </div>
        </div>
        ${renderHelp('taxonomy', 'phone:allowExtension')}
      </div>
    `
  }

  protected renderRequireVerification(): TemplateResult {
    const enabled = this.config?.requireVerification ?? DEFAULT_PHONE_CONFIG.requireVerification
    return html`
      <div class="row">
        <div class="input checkbox metadata">
          <ui-checkbox
            id="require-verification"
            .checked="${enabled}"
            name="requireVerification"
            @change="${this.handleBooleanChange}"
          ></ui-checkbox>
          <div class="label">
            <label for="require-verification" class="body-medium">Require Verification</label>
            <span class="body-small meta">Users must verify their phone numbers.</span>
          </div>
        </div>
        ${renderHelp('taxonomy', 'phone:requireVerification')}
      </div>
    `
  }

  protected renderFormatSelect(): TemplateResult {
    const value = this.config?.format ?? DEFAULT_PHONE_CONFIG.format
    return html`
      <div class="row input-row select">
        <ui-select
          label="Phone Number Format"
          class="input"
          name="format"
          .value="${value as string}"
          @change="${this.handleSelectChange}"
        >
          <ui-option value="international" lines="two">
            <div>International</div>
            <div slot="supporting-text">E.164 format with country code (e.g., +1234567890).</div>
          </ui-option>
          <ui-option value="national" lines="two">
            <div>National</div>
            <div slot="supporting-text">Local format without country code (e.g., 0123456789).</div>
          </ui-option>
          <ui-option value="custom" lines="two">
            <div>Custom</div>
            <div slot="supporting-text">User-defined format.</div>
          </ui-option>
        </ui-select>
        ${renderHelp('taxonomy', 'phone:format')}
      </div>
    `
  }

  protected renderVerificationMethodSelect(): TemplateResult | typeof nothing {
    const enabled = this.config?.requireVerification ?? DEFAULT_PHONE_CONFIG.requireVerification
    if (!enabled) {
      return nothing // Skip rendering if verification is not required
    }
    // Render verification method select only if verification is required
    const value = this.config?.verificationMethod ?? DEFAULT_PHONE_CONFIG.verificationMethod
    return html`
      <div class="row input-row select">
        <ui-select
          label="Verification method"
          class="input"
          name="verificationMethod"
          .value="${value as string}"
          @change="${this.handleSelectChange}"
        >
          <ui-option value="sms">SMS</ui-option>
          <ui-option value="call">Call</ui-option>
        </ui-select>
        ${renderHelp('taxonomy', 'phone:verificationMethod')}
      </div>
    `
  }

  protected renderAllowedCountriesInput(): TemplateResult {
    const value = this.config?.allowedCountries ?? DEFAULT_PHONE_CONFIG.allowedCountries
    const chips = (value || []).map(
      (country, index) =>
        html`<ui-chip type="input" removable data-index="${index}" @remove="${this.handleRemoveCountry}"
          >${country}</ui-chip
        >`
    )
    return html`
      <div class="row input-row">
        <div class="input chips-input">
          <ui-outlined-text-field
            class="input"
            name="allowedCountries"
            label="Allowed Countries"
            @change="${this.handleAllowedCountriesChange}"
            supportingText="Add a country code and press Enter to add it to the list."
          ></ui-outlined-text-field>
          <ui-chip-set>${chips}</ui-chip-set>
        </div>
        ${renderHelp('taxonomy', 'phone:allowedCountries')}
      </div>
    `
  }

  protected renderCustomFormatInput(): TemplateResult | typeof nothing {
    const format = this.config?.format ?? DEFAULT_PHONE_CONFIG.format
    if (format !== 'custom') {
      return nothing // Skip rendering if format is not custom
    }
    // Render custom format input only if the format is set to 'custom'
    // Examples: '###-###-####', '(###) ###-####'
    const value = this.config?.customFormat ?? DEFAULT_PHONE_CONFIG.customFormat
    return html`
      <div class="row input-row">
        <ui-outlined-text-field
          class="input"
          name="customFormat"
          label="Custom Format"
          .value="${value || ''}"
          @change="${this.handleTextChange}"
          supportingText="Examples: '###-###-####', '(###) ###-####'"
        ></ui-outlined-text-field>
        ${renderHelp('taxonomy', 'phone:customFormat')}
      </div>
    `
  }
}
