/**
 * EdGEL collapsible element base.
 *
 * Add in Bootstrap Collapse functionality to our custom element.
 */

import { html } from 'lit'
import Collapse from 'bootstrap/js/src/collapse'
import { EdGELElement } from './base.js'

const CLASS_NAME_SHOW = 'show'
const CLASS_NAME_COLLAPSE = 'collapse'

export class EdGELCollapse extends EdGELElement {
  static properties = {
    expanded: { type: Boolean, reflect: true, attribute: 'expanded' },
    controls: { type: String, attribute: false }
  }

  constructor() {
    super()

    this.collapseInternal = true
    this.collapseDisabled = false
  }

  disconnectedCallback() {
    super.disconnectedCallback()

    if (this.collapseElement) {
      this.collapseElement.dispose()
    }
  }

  updated(changedProperties) {
    if ((changedProperties.has('controls') || this.collapseDisabled) && this.collapseElement) {
      this.collapseElement.dispose()
    }

    if (this.collapseDisabled) {
      return
    }

    if (changedProperties.has('controls') || !this.collapseElement) {
      // Here getRootNode() could return an Element (<html>) or a DocumentFragment (shadowRoot from a parent custom
      // element) so we can't use Bootstrap's SelectorEngine.findOne which will only work for Elements
      const collapseRoot = this.collapseInternal ?
        this.shadowRoot.getRootNode() :
        this.shadowRoot.host.getRootNode()
      const collapsible = collapseRoot.querySelector(`#${this.controls}`)
      if (!collapsible) {
        throw new Error(`EdGEL Collapse cannot find element #${this.controls} to control`)
      }

      collapsible.classList.add(CLASS_NAME_COLLAPSE)

      if (this.expanded) {
        collapsible.classList.add(CLASS_NAME_SHOW)
      } else {
        collapsible.classList.remove(CLASS_NAME_SHOW)
      }

      const config = {
        toggle: false
      }
      if (this.parent) {
        config.parent = this.parent
      }

      this.collapseElement = Collapse.getOrCreateInstance(collapsible, config)
    }
  }

  toggleCollapse(e) {
    e.stopPropagation()

    this.expanded = !this.expanded
    if (this.collapseElement) {
      if (this.expanded) {
        this.collapseElement.show()
      } else {
        this.collapseElement.hide()
      }
    }
  }

  buttonHtml(content, extraClass) {
    let classes = 'btn btn-hamburger'
    if (extraClass) {
      classes = `${classes} ${extraClass}`
    }

    return html`
      <button
        type="button"
        class=${classes}
        aria-expanded=${this.expanded}
        aria-controls=${this.controls}
        @click=${this.toggleCollapse}
      >
        ${content}
      </button>
    `
  }
}
