import { html, TemplateResult } from 'lit'
import { DemoPage } from '../../../src/demo/DemoPage.js'
import reactive from '../../../src/decorators/reactive.js'
import type { Currency, CurrencyPickerError } from '../../../src/elements/currency/internals/Picker.js'

import '../../../src/elements/currency/currency-picker.js'
import '../../../src/md/button/ui-button.js'
import '../../../src/md/checkbox/ui-checkbox.js'

class CurrencyPickerDemoPage extends DemoPage {
  override accessor componentName = 'Currency Picker'

  @reactive() accessor singleSelected: string[] = []
  @reactive() accessor multiSelected: string[] = ['USD', 'EUR']
  @reactive() accessor limitedSelected: string[] = []
  @reactive() accessor formSelected: string[] = []
  @reactive() accessor disabledSelected: string[] = ['GBP']

  @reactive() accessor lastChangeEvent = 'No changes yet'
  @reactive() accessor lastErrorEvent = 'No errors yet'

  private readonly allowedCurrencies = ['USD', 'EUR', 'GBP', 'JPY', 'CAD']

  handleSingleChange(event: CustomEvent<{ currencies: Currency[]; codes: string[] }>): void {
    this.singleSelected = event.detail.codes
    this.lastChangeEvent = `Single Select: ${JSON.stringify(event.detail, null, 2)}`
  }

  handleMultiChange(event: CustomEvent<{ currencies: Currency[]; codes: string[] }>): void {
    this.multiSelected = event.detail.codes
    this.lastChangeEvent = `Multi Select: ${JSON.stringify(event.detail, null, 2)}`
  }

  handleLimitedChange(event: CustomEvent<{ currencies: Currency[]; codes: string[] }>): void {
    this.limitedSelected = event.detail.codes
    this.lastChangeEvent = `Limited Currencies: ${JSON.stringify(event.detail, null, 2)}`
  }

  handleFormChange(event: CustomEvent<{ currencies: Currency[]; codes: string[] }>): void {
    this.formSelected = event.detail.codes
    this.lastChangeEvent = `Form Element: ${JSON.stringify(event.detail, null, 2)}`
  }

  handleError(event: CustomEvent<{ error: CurrencyPickerError }>): void {
    this.lastErrorEvent = `Error: ${JSON.stringify(event.detail, null, 2)}`
  }

  handleClearSingle(): void {
    const picker = document.querySelector('#single-picker') as HTMLElement & { clearSelection(): void }
    picker?.clearSelection()
  }

  handleClearMulti(): void {
    const picker = document.querySelector('#multi-picker') as HTMLElement & { clearSelection(): void }
    picker?.clearSelection()
  }

  handleClearLimited(): void {
    const picker = document.querySelector('#limited-picker') as HTMLElement & { clearSelection(): void }
    picker?.clearSelection()
  }

  handleTriggerValidationError(): void {
    const picker = document.querySelector('#error-demo-picker') as HTMLElement & { selected: string[] }
    if (picker) {
      // Try to set invalid currency codes
      picker.selected = ['INVALID', 'FAKE', 'USD']
    }
  }

  handleTriggerSelectionError(): void {
    const picker = document.querySelector('#single-error-picker') as HTMLElement & { selected: string[] }
    if (picker) {
      // Try to set multiple currencies on single-select picker
      picker.selected = ['USD', 'EUR', 'GBP']
    }
  }

  override contentTemplate(): TemplateResult {
    return html`
      <section class="demo-section">
        <h3>Single Currency Selection</h3>
        <p>Select one currency at a time. When a new currency is selected, it replaces the previous selection.</p>

        <div class="demo-controls">
          <currency-picker
            id="single-picker"
            label="Select Currency"
            .selected="${this.singleSelected}"
            @change="${this.handleSingleChange}"
            @error="${this.handleError}"
          ></currency-picker>
        </div>

        <ui-button @click="${this.handleClearSingle}">Clear Selection</ui-button>

        <div class="output-section">
          <h4>Selected Currency</h4>
          <div class="output-content">${this.singleSelected.join(', ') || 'None'}</div>
        </div>
      </section>

      <section class="demo-section">
        <h3>Multiple Currency Selection</h3>
        <p>Select multiple currencies. Selected currencies appear as chips that can be removed individually.</p>

        <div class="demo-controls">
          <currency-picker
            id="multi-picker"
            label="Add Currency"
            multi
            .selected="${this.multiSelected}"
            @change="${this.handleMultiChange}"
            @error="${this.handleError}"
          ></currency-picker>
        </div>

        <ui-button @click="${this.handleClearMulti}">Clear All</ui-button>

        <div class="output-section">
          <h4>Selected Currencies</h4>
          <div class="output-content">${this.multiSelected.join(', ') || 'None'}</div>
        </div>
      </section>

      <section class="demo-section">
        <h3>Limited Currency Options</h3>
        <p>Restrict available currencies to a specific subset using the allowedCurrencies property.</p>

        <div class="demo-controls">
          <currency-picker
            id="limited-picker"
            label="Select from Limited Options"
            multi
            .selected="${this.limitedSelected}"
            .allowedCurrencies="${this.allowedCurrencies}"
            supportingText="Only major currencies available"
            @change="${this.handleLimitedChange}"
            @error="${this.handleError}"
          ></currency-picker>
        </div>

        <ui-button @click="${this.handleClearLimited}">Clear Selection</ui-button>

        <div class="output-section">
          <h4>Available Currencies</h4>
          <div class="output-content">${this.allowedCurrencies.join(', ')}</div>
          <h4>Selected Currencies</h4>
          <div class="output-content">${this.limitedSelected.join(', ') || 'None'}</div>
        </div>
      </section>

      <section class="demo-section">
        <h3>Form Integration</h3>
        <p>Use the currency picker in forms with proper name and required attributes.</p>

        <form @submit="${this.handleFormSubmit}">
          <div class="demo-controls">
            <currency-picker
              label="Required Currency"
              name="currency"
              required
              .selected="${this.formSelected}"
              supportingText="This field is required"
              @change="${this.handleFormChange}"
              @error="${this.handleError}"
            ></currency-picker>
          </div>

          <ui-button type="submit">Submit Form</ui-button>
          <ui-button color="text" type="reset">Reset Form</ui-button>
        </form>

        <div class="output-section">
          <h4>Form Value</h4>
          <div class="output-content">${this.formSelected.join(', ') || 'None'}</div>
        </div>
      </section>

      <section class="demo-section">
        <h3>Disabled State</h3>
        <p>Currency picker in disabled state with pre-selected currencies.</p>

        <div class="demo-controls">
          <currency-picker
            label="Disabled Picker"
            disabled
            .selected="${this.disabledSelected}"
            supportingText="This picker is disabled"
          ></currency-picker>
        </div>

        <div class="output-section">
          <h4>Disabled Selection</h4>
          <div class="output-content">${this.disabledSelected.join(', ')}</div>
        </div>
      </section>

      <section class="demo-section">
        <h3>Error Handling Demonstration</h3>
        <p>Test various error scenarios to see how the component handles and displays errors.</p>

        <h4>Validation Errors</h4>
        <p>This picker demonstrates validation errors when invalid currency codes are set programmatically.</p>

        <div class="demo-controls">
          <currency-picker
            id="error-demo-picker"
            label="Validation Error Demo"
            multi
            @error="${this.handleError}"
          ></currency-picker>
        </div>

        <ui-button @click="${this.handleTriggerValidationError}">Trigger Validation Error</ui-button>

        <h4>Selection Constraint Errors</h4>
        <p>This single-select picker demonstrates selection constraint errors.</p>

        <div class="demo-controls">
          <currency-picker
            id="single-error-picker"
            label="Single Select Error Demo"
            @error="${this.handleError}"
          ></currency-picker>
        </div>

        <ui-button @click="${this.handleTriggerSelectionError}">Trigger Selection Error</ui-button>

        <div class="output-section">
          <h4>Error Event Output</h4>
          <div class="output-content">${this.lastErrorEvent}</div>
        </div>
      </section>

      <section class="demo-section">
        <h3>Event Output</h3>
        <p>View the latest change event data in real-time.</p>

        <div class="output-section">
          <h4>Last Change Event</h4>
          <div class="output-content">${this.lastChangeEvent}</div>
        </div>
      </section>

      <section class="demo-section">
        <h3>Error Handling</h3>
        <p>View the latest error event data in real-time.</p>

        <div class="output-section">
          <h4>Last Error Event</h4>
          <div class="output-content">${this.lastErrorEvent}</div>
        </div>
      </section>
    `
  }

  private handleFormSubmit(event: Event): void {
    event.preventDefault()
    const formData = new FormData(event.target as HTMLFormElement)
    console.log('Form submitted:', Object.fromEntries(formData.entries()))

    if (this.formSelected.length === 0) {
      alert('Please select a currency before submitting the form.')
    } else {
      alert(`Form submitted with currency: ${this.formSelected.join(', ')}`)
    }
  }
}

const instance = new CurrencyPickerDemoPage()
instance.render()
