import onFind from './dom/onFind'
import storage from './util/storage'

type PageNavToggleState = 'OFF' | 'ON' | null
const ToggleStorageKey = 'BSP.v5.Page.nav.toggle'

const setToggle = (val: PageNavToggleState) => {
  if (val !== null) storage.set(ToggleStorageKey, val)
}

export const getToggle = () => {
  return storage.get(ToggleStorageKey) as PageNavToggleState
}

export const toggle = (forcedVal?: PageNavToggleState) => {
  if (forcedVal !== undefined) {
    setToggle(forcedVal)
  } else {
    setToggle(getToggle() === 'ON' ? 'OFF' : 'ON')
  }
  update()

  window.document.body.dispatchEvent(
    new CustomEvent('page-nav-rail-toggled', {
      bubbles: true,
      detail: { toggleState: getToggle() },
    }),
  )
}

const update = () => {
  const lastToggleState = getToggle()
  // Update with last state if it exists.
  if (lastToggleState !== null) {
    document.documentElement.style.setProperty(
      '--pageNav-expanded',
      getComputedStyle(document.documentElement).getPropertyValue(
        `--pageNav-expanded-${lastToggleState}`,
      ),
    )
    document.body.classList.toggle(
      'has-navrail-expanded',
      lastToggleState === 'ON',
    )
  }
}

onFind('.Page-main > btu-nav-rail', (nav: HTMLElement) => {
  if (document.querySelector('.Page-header.mobile')) {
    toggle('OFF')
  } else {
    update()
  }

  /*
    When the page nav is small, it should become large when a nav item is clicked.
    It should also expand the group and scroll to it if necessary.
  */
  nav.addEventListener(
    'click',
    (evt) => {
      const target = evt.target

      if (!(target instanceof HTMLElement) && !(target instanceof SVGElement))
        return

      const item = target.closest<HTMLElement>('li.isNested')
      if (!item) return

      // If the clicked item is one within the first group of the nav,
      // treat those like sub-item clicks. No need to expand the nav.
      if (item && item.parentNode?.firstElementChild === item) {
        return
      }

      // Can nav be expanded?
      const expandState = getComputedStyle(
        document.documentElement,
      ).getPropertyValue('--pageNav-expanded')
      if (expandState !== '') return

      // We just want to make the nav larger.
      // Don't allow the link to redirect and don't run any v4 click callbacks.
      evt.preventDefault()
      evt.stopImmediatePropagation()

      // Make the nav larger.
      const toggle = document.querySelector<HTMLElement>('.Page-navToggle')
      if (toggle) toggle.click()

      // Expand the group if it's collapsed.
      const collapsedParentItem = target.closest<HTMLElement>(
        'li.isNested:not(.is-expanded)',
      )
      if (collapsedParentItem) {
        if (target instanceof SVGElement) {
          target.closest('a')?.click()
        } else {
          target.click()
        }
      }

      // Scroll to the group parent when necessary.
      setTimeout(() => target.scrollIntoView({ behavior: 'smooth' }), 250)
    },
    true,
  )
})
