/**
 * --------------------------------------------------------------------------
 * mobile-toggles.js
 * Toggle and mobile responsive functionality
 * --------------------------------------------------------------------------
 */

import { uoeUID } from './utils'
import {
  defineJQueryPlugin,
  onDOMContentLoaded
} from 'bootstrap/js/src/util'
import SelectorEngine from 'bootstrap/js/src/dom/selector-engine'

/**
 * ------------------------------------------------------------------------
 * Constants
 * ------------------------------------------------------------------------
 */

const NAME = 'mobileToggles'
const CLASS_NAME_JS = 'edgel-js'
const SELECTOR_JS_CLASS = 'html'
const SELECTOR_UOE_NAV = '.uoe-nav ul'
const SELECTOR_SEARCH = '.masthead-search'
const SELECTOR_MASTHEAD = '.masthead'
const SELECTOR_ROW = '.row'
const ICON_SEARCH = '<svg xmlns="http://www.w3.org/2000/svg" height="1rem" width="1rem" viewBox="0 0 8 8" aria-hidden="true"><path class="masthead-search-icon-path" d="M3.5 0c-1.93 0-3.5 1.57-3.5 3.5s1.57 3.5 3.5 3.5c.59 0 1.17-.14 1.66-.41a1 1 0 0 0 .13.13l1 1a1.02 1.02 0 1 0 1.44-1.44l-1-1a1 1 0 0 0-.16-.13c.27-.49.44-1.06.44-1.66 0-1.93-1.57-3.5-3.5-3.5zm0 1c1.39 0 2.5 1.11 2.5 2.5 0 .66-.24 1.27-.66 1.72-.01.01-.02.02-.03.03a1 1 0 0 0-.13.13c-.44.4-1.04.63-1.69.63-1.39 0-2.5-1.11-2.5-2.5s1.11-2.5 2.5-2.5z"/></svg>'
const TEXT_SEARCH_TOGGLE = '<span class="visually-hidden">Show/hide site search</span>'
const TEXT_MENU_TOGGLE = '<span class="visually-hidden">Toggle Navigation</span> Menu'

/**
 * ------------------------------------------------------------------------
 * Public methods
 * ------------------------------------------------------------------------
 */

const MobileToggles = {
  addIcons(selector, icon, iconSelector) {
    const _addIcons = function () {
      const selectorElements = SelectorEngine.find(this.selector)

      for (const [i, element] of selectorElements.entries()) {
        if (!SelectorEngine.findOne(this.iconSelector, element)) {
          element.prepend(this.icon)
          if (i !== selectorElements.length - 1) {
            this.icon = this.icon.cloneNode(true)
          }
        }
      }
    }.bind({ selector, icon, iconSelector })

    onDOMContentLoaded(_addIcons)
  },
  addJsClass() {
    const _addJsClass = function () {
      const selectorElement = this.selector === 'html' ? document.documentElement : SelectorEngine.findOne(this.selector)

      if (selectorElement && !selectorElement.classList.contains(this.className)) {
        selectorElement.classList.add(this.className)
      }
    }.bind({
      selector: SELECTOR_JS_CLASS,
      className: CLASS_NAME_JS
    })

    onDOMContentLoaded(_addJsClass)
  },
  addNavToggle() {
    const _addNavToggle = function () {
      const toggle = document.createElement('button')
      toggle.className = 'btn btn-uoe-nav-toggler btn-hamburger'
      toggle.setAttribute('type', 'button')
      toggle.setAttribute('aria-expanded', 'false')
      toggle.dataset.uoeToggle = 'hamburger'
      toggle.innerHTML = this.TEXT_MENU_TOGGLE

      const element = SelectorEngine.findOne(this.selector)
      if (element) {
        if (!element.classList.contains('collapse')) {
          element.classList.add('collapse')
        }

        if (!element.id) {
          element.id = this.uoeUID()
        }

        toggle.dataset.bsTarget = `#${element.id}`
        toggle.setAttribute('aria-controls', element.id)
        element.before(toggle)
      }
    }.bind({
      selector: SELECTOR_UOE_NAV,
      uoeUID,
      TEXT_MENU_TOGGLE
    })

    onDOMContentLoaded(_addNavToggle)
  },
  addSearchToggle() {
    const _addSearchToggle = function () {
      const searchBlock = SelectorEngine.findOne(this.SELECTOR_SEARCH)
      if (!searchBlock) {
        return
      }

      const toggle = document.createElement('button')
      toggle.setAttribute('type', 'button')
      toggle.dataset.bsToggle = 'collapse'
      toggle.className = 'btn btn-masthead-search-toggler'
      toggle.innerHTML = this.TEXT_SEARCH_TOGGLE + this.ICON_SEARCH

      const row = searchBlock.closest(SELECTOR_ROW)
      if (!row || !row.closest(SELECTOR_MASTHEAD)) {
        throw new Error('Please use Bootstrap row and col classes in masthead')
      }

      // Make masthead-search collapsible
      const element = SelectorEngine.findOne(this.SELECTOR_SEARCH)
      if (element) {
        element.setAttribute('aria-expanded', 'false')
        if (!element.classList.contains('collapse')) {
          element.classList.add('collapse')
        }

        if (!element.id) {
          element.id = this.uoeUID()
        }

        toggle.dataset.bsTarget = `#${element.id}`
        toggle.setAttribute('aria-controls', element.id)

        // Add padding to move the logo away from the search toggle button
        const insertPoint = row.firstElementChild
        insertPoint.style.paddingRight = '45px'
        insertPoint.after(toggle)
      }
    }.bind({
      uoeUID,
      TEXT_SEARCH_TOGGLE,
      ICON_SEARCH,
      SELECTOR_SEARCH
    })

    onDOMContentLoaded(_addSearchToggle)
  }
}

/**
 * Add EdGEL toggle buttons
 */
MobileToggles.addJsClass()
MobileToggles.addNavToggle()
MobileToggles.addSearchToggle()

/**
 * ------------------------------------------------------------------------
 * jQuery
 * ------------------------------------------------------------------------
 * add .Hamburger to jQuery only if jQuery is present
 */

defineJQueryPlugin(NAME, MobileToggles)

export default MobileToggles
