import { LitElement, nothing } from 'lit'
import { customElement, queryAsync } from 'lit/decorators.js'
import { EventEmitterMixin } from '../EventEmitterMixin'
import create from '../dom/create'
import onFind from '../dom/onFind'
import getComponentKey from '../util/getComponentKey'

const ls = window.localStorage
const tooltips = window.BRIGHTSPOT?.ui.tooltips

@customElement('btu-eig')
export default class EmbeddedInputGroup extends EventEmitterMixin(LitElement) {
  @queryAsync('.EIG-item')
  _eigItem?: Promise<HTMLElement>

  @queryAsync('.EIG-title')
  _title?: Promise<HTMLElement>

  @queryAsync('.removeButton')
  _removeButton?: Promise<HTMLElement>

  connectedCallback(): void {
    super.connectedCallback()

    this.initializeEigItem()
  }

  disconnectedCallback(): void {
    super.disconnectedCallback()

    this._removeButton?.then((removeButton) => {
      removeButton?.removeEventListener('click', (evt) => {
        this._removeItem(evt)
      })
    })

    this._title?.then((title) => {
      title?.removeEventListener('click', () => {
        this._eigToggle()
      })

      title?.removeEventListener('keydown', ({ key }) => {
        if (key === 'Enter' || key === 'Space' || key === ' ') {
          event?.preventDefault()
          this._eigToggle()
        }
      })
    })
  }

  private _eigToggle = () => {
    this._eigItem?.then((eigItem) => {
      if (eigItem) {
        const itemClassList = eigItem.classList
        if (itemClassList.contains('is-removing')) return
        itemClassList.toggle('is-collapsed')
        eigItem.querySelector('.CIG-large')?.toggleAttribute('hidden')
        const associatedDataField = eigItem.closest<HTMLElement>('[data-field]')
        if (associatedDataField) {
          const key = getComponentKey(associatedDataField, 'data-field')

          if (key) {
            if (ls.getItem(key)) {
              ls.removeItem(key)
            } else {
              ls.setItem(key, '1')
            }
          }
        }
      }
    })
  }

  private _removeItem = (evt: Event) => {
    const target = evt.target
    this._eigItem?.then((eigItem) => {
      if (eigItem) {
        const eigLiveRegion = eigItem.querySelector('.screen-reader-only')
        if (eigItem.classList.toggle('is-removing')) {
          eigItem.querySelector('.CIG-large')?.setAttribute('hidden', '')
          eigItem
            .querySelectorAll('input, textarea, select')
            .forEach((input) => input.setAttribute('disabled', ''))

          if (target instanceof HTMLElement) {
            target.title = tooltips.restore
            target.setAttribute('aria-label', tooltips.restore)
            if (eigLiveRegion) eigLiveRegion.textContent = tooltips?.remove
          }
        } else {
          if (!eigItem.classList.contains('is-collapsed')) {
            eigItem.querySelector('.CIG-large')?.removeAttribute('hidden')
          }
          eigItem
            .querySelectorAll('input, textarea, select')
            .forEach((input) => input.removeAttribute('disabled'))

          if (target instanceof HTMLElement) {
            target.title = tooltips.remove
            target.setAttribute('aria-label', tooltips.remove)
            if (eigLiveRegion) eigLiveRegion.textContent = tooltips?.restore
          }
        }
      }
    })
  }

  firstUpdated(): void {
    this.emit('btu-eig-ready')
  }

  createRenderRoot() {
    return this
  }

  initializeEigItem() {
    this._eigItem?.then((eigItem) => {
      if (eigItem) {
        const associatedDataField = eigItem.closest<HTMLElement>('[data-field]')
        const itemClassList = eigItem.classList
        let key = null

        // Check if item is collapsed previously
        if (associatedDataField) {
          key = getComponentKey(associatedDataField, 'data-field')
          if (key && ls.getItem(key)) {
            itemClassList.add('is-collapsed')
            eigItem.querySelector('.CIG-large')?.setAttribute('hidden', '')
          }
        }
      } else {
        // No EIG item has been added yet (i.e., Add Module) so monitor for it.
        onFind(this, '.EIG-item', (eigItem: HTMLElement) => {
          const title = eigItem.querySelector<HTMLElement>('.EIG-title')
          const removeButton =
            eigItem.querySelector<HTMLElement>('.removeButton')
          this.titleAddEventListeners(title)
          this.removeButtonAddEventListeners(removeButton)
        })
      }
    })

    this._title?.then((title) => {
      this.titleAddEventListeners(title)
    })

    this._removeButton?.then((removeButton) => {
      this.removeButtonAddEventListeners(removeButton)
    })
  }

  titleAddEventListeners(title: HTMLElement | null) {
    if (!title) return
    title.addEventListener('click', () => {
      this._eigToggle()
    })

    title.addEventListener('keydown', (event) => {
      const { key } = event
      if (key === 'Enter' || key === 'Space' || key === ' ') {
        event.preventDefault()
        this._eigToggle()
      }
    })
  }

  removeButtonAddEventListeners(removeButton: HTMLElement | null) {
    if (!removeButton) return
    const eigLiveRegion = create('span', {
      class: 'screen-reader-only',
      'aria-live': 'polite',
    })
    removeButton.after(eigLiveRegion)

    removeButton.addEventListener('click', (evt) => {
      this._removeItem(evt)
    })
  }

  render() {
    return nothing
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'btu-eig': EmbeddedInputGroup
  }
}
