import { html, PropertyValues } from 'lit'
import { ifDefined } from 'lit/directives/if-defined.js'
import { customElement, property, state } from 'lit/decorators.js'
import { Ref, createRef, ref } from 'lit/directives/ref.js'
import { classMap } from 'lit/directives/class-map.js'
import { live } from 'lit/directives/live.js'
import { PktInputElement } from '@/base-elements/input-element'
import { PktSlotController } from '@/controllers/pkt-slot-controller'

import '@/components/input-wrapper'
import '@/components/icon'

@customElement('pkt-textarea')
export class PktTextarea extends PktInputElement {
  private inputRef: Ref<HTMLTextAreaElement> = createRef()
  private helptextSlot: Ref<HTMLElement> = createRef()

  @property({ type: String, reflect: true }) value: string = ''
  @property({ type: String }) autocomplete: string = 'off'
  @property({ type: Number }) rows: number | null = null

  @state() counterCurrent = 0

  constructor() {
    super()
    this.slotController = new PktSlotController(this, this.helptextSlot)
  }

  attributeChangedCallback(name: string, _old: string | null, value: string | null): void {
    if (name === 'value' && this.value !== _old) {
      this.counterCurrent = value ? value.length : 0
      this.valueChanged(value, _old)
    }
    super.attributeChangedCallback(name, _old, value)
  }

  updated(changedProperties: PropertyValues) {
    super.updated(changedProperties)
    if (changedProperties.has('value')) {
      this.counterCurrent = this.value?.length || 0
      this.valueChanged(this.value, changedProperties.get('value'))
    }
    if (changedProperties.has('id')) {
      !this.name && this.id && (this.name = this.id)
    }
  }

  render() {
    const inputClasses = classMap({
      'pkt-input': true,
      'pkt-input--fullwidth': this.fullwidth,
      'pkt-input--counter-error':
        this.counter &&
        this.counterMaxLength &&
        this.value.length &&
        this.value.length > this.counterMaxLength,
    })
    const labelledBy = this.ariaLabelledby || `${this.id}-input-label`

    return html`<pkt-input-wrapper
      label=${this.label}
      ?counter=${this.counter}
      ?disabled=${this.disabled}
      ?hasError=${this.hasError}
      ?inline=${this.inline}
      ?optionalTag=${this.optionalTag}
      ?required=${this.required}
      ?requiredTag=${this.requiredTag}
      ?useWrapper=${this.useWrapper}
      .ariaDescribedBy=${this.ariaDescribedBy}
      .counterCurrent=${this.counterCurrent}
      .counterMaxLength=${this.counterMaxLength}
      .errorMessage=${this.errorMessage}
      .forId="${this.id + '-input'}"
      .helptext=${this.helptext}
      .helptextDropdown=${this.helptextDropdown}
      .helptextDropdownButton=${this.helptextDropdownButton}
      .optionalText=${this.optionalText}
      .requiredText=${this.requiredText}
      .tagText=${this.tagText}
      class="pkt-textarea"
    >
      <div class="pkt-contents" ${ref(this.helptextSlot)} name="helptext" slot="helptext"></div>
      <textarea
        ${ref(this.inputRef)}
        class=${inputClasses}
        id=${this.id + '-input'}
        name=${(this.name || this.id) + '-input'}
        placeholder=${ifDefined(this.placeholder)}
        .value=${live(this.value)}
        minlength=${ifDefined(this.minlength)}
        maxlength=${ifDefined(this.maxlength)}
        ?readonly=${this.readonly}
        autocomplete=${this.autocomplete}
        aria-labelledby=${labelledBy}
        aria-invalid=${this.hasError}
        aria-errormessage=${`${this.id}-error`}
        rows=${this.rows}
        ?disabled=${this.disabled}
        @input=${(e: InputEvent) => {
          this.value = (e.target as HTMLInputElement).value
          this.onInput()
          e.stopImmediatePropagation()
        }}
        @change=${(e: Event) => {
          e.stopImmediatePropagation()
        }}
        @focus=${(e: FocusEvent) => {
          this.onFocus()
          e.stopImmediatePropagation()
        }}
        @blur=${(e: FocusEvent) => {
          this.value = (e.target as HTMLInputElement).value
          this.onBlur()
          e.stopImmediatePropagation()
        }}
      ></textarea>
    </pkt-input-wrapper>`
  }
}
