import { LitElement, html } from 'lit'
import { customElement, property } from 'lit/decorators.js'
import { ComponentStatesMixin } from '../ComponentStatesMixin'
import { EventEmitterMixin } from '../EventEmitterMixin'
import ifUnmodified from '../dom/ifUnmodified'

const ls = window.localStorage
const collapseTooltip = window.BRIGHTSPOT?.ui.tooltips.collapse
const expandTooltip = window.BRIGHTSPOT?.ui.tooltips.expand

@customElement('btu-cig-cluster')
export default class CIGCluster extends ComponentStatesMixin(
  EventEmitterMixin(LitElement),
) {
  private _collapsed = true

  @property({ type: String, reflect: true, attribute: 'cluster-title' })
  clusterTitle?: string

  @property({ type: String })
  tab?: string

  @property()
  set collapsed(isCollapsed: boolean) {
    this._collapsed = isCollapsed

    const cig = this.closest<HTMLElement>('.CIG')
    const type = cig?.dataset.type
    const text = this.clusterTitle?.trim()

    const key = `BSP.ContentEdit.clusterExpanded.${type}.${text}`
    if (type && text) {
      if (isCollapsed) {
        ls.removeItem(key)
      } else {
        ls.setItem(key, '1')
      }
    }

    if (!this._collapsed) {
      this.states.add('btu-expanded')
    } else {
      this.states.delete('btu-expanded')
    }

    this.requestUpdate()
  }

  get collapsed() {
    return this._collapsed
  }

  private _toggleRowVisibility(force: boolean) {
    this.querySelectorAll<HTMLElement>(':scope > :not(.CIG-title)').forEach(
      (el) => {
        if (el.childNodes.length) {
          el.toggleAttribute('hidden', force)
          el.classList.toggle('TC-unselected', force)
        }
      },
    )
  }

  connectedCallback(): void {
    super.connectedCallback()

    const cig = this.closest<HTMLElement>('.CIG')
    const type = cig?.dataset.type
    const text = this.clusterTitle

    const key = `BSP.ContentEdit.clusterExpanded.${type}.${text}`
    this.collapsed = ls.getItem(key) ? false : true
  }

  createRenderRoot() {
    return this
  }

  firstUpdated(): void {
    this.emit('btu-cig-cluster-ready')

    const title = this.querySelector<HTMLElement>('.CIG-title')

    // Ensures that the title is always the first child of the cluster.
    const firstChild = this.firstChild
    if (
      firstChild instanceof Element &&
      !firstChild.classList.contains('CIG-title')
    ) {
      if (title) {
        this.insertBefore(title, firstChild)
      }
    }

    this.dataset.tab = this.tab

    // Hide the component if all rows are empty.
    const rows = Array.from(this.querySelectorAll('.CIG-row')).filter(
      (row) => row.childNodes.length,
    )
    this.toggleAttribute('hidden', !rows.length)

    // Hide empty rows.
    const emptyRows = Array.from(this.querySelectorAll('.CIG-row')).filter(
      (row) => !row.childNodes.length,
    )
    emptyRows.forEach((row) => row.toggleAttribute('hidden', true))

    const errorFields = this.querySelectorAll('.CIG-row > .Message.is-error')
    errorFields.length > 0
      ? this.states.add('btu-error')
      : this.states.delete('btu-error')
  }

  render() {
    this._toggleRowVisibility(this.collapsed)

    return html`<h2 class="CIG-title" data-tab=${this.tab}>
      <button
        type="button"
        title="${this.collapsed ? expandTooltip : collapseTooltip}"
        aria-expanded="${!this.collapsed}"
        @click="${() => (this.collapsed = !this.collapsed)}"
        @keydown=${ifUnmodified((e: unknown) => {
          if (e instanceof KeyboardEvent) {
            if (e.key === 'Enter' || e.key === ' ') {
              e.preventDefault()
              this.collapsed = !this.collapsed
            }
          }
        })}
      >
        <span class="CIG-titleText">${this.clusterTitle}</span>
        <span class="CIG-titleToggle" aria-hidden="true"></span>
      </button>
    </h2>`
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'btu-cig-cluster': CIGCluster
  }
}
