import onFind from './dom/onFind'
import create from './dom/create'
import {
  listenForMenuItemClick,
  setupMenuForAria,
  toggleMenu,
} from './dom/popupMenu'

onFind('.Notification-controls-toggle', (toggle: HTMLDivElement) => {
  const controls = toggle.closest('.Notification-controls-menu')
  const list = controls?.querySelector<HTMLElement>(
    '.Notification-controls-list',
  )

  if (list && controls) {
    controls.setAttribute('data-tether-anchor', '')
    toggle.addEventListener('click', (e: MouseEvent | KeyboardEvent) => {
      listenForMenuItemClick(list, toggle)
      toggleMenu(list, toggle, controls)
    })
    setupMenuForAria(list, toggle)
  }
})

// When an action link (in the context of a delivery) is clicked, wait for the popup/frame to load and then refresh
// the action bar for that delivery to ensure that all the links reflect the current state of the world post-action.
onFind(
  '.frame.loaded[name^="notification-action-popup-"]',
  (popupFrame: HTMLElement) => {
    const popupName = popupFrame.getAttribute('name')

    const actionLinkTagNames = ['a', 'form']
    const actionLink = document.querySelector(
      actionLinkTagNames
        .map((tag) => `${tag}[target="${popupName}"].Notification-action`)
        .join(', '),
    )
    const actionBar = actionLink?.closest('.Notification-actionBar')
    const refreshLink = actionBar?.querySelector<HTMLAnchorElement>(
      '.Notification-actionRefresh > a',
    )
    refreshLink?.click()
  },
)

// Powers the action result url redirect delay countdown.
onFind(
  '.Notification-actionResultUrl[data-redirect-delay]',
  (container: HTMLElement) => {
    const countdown = container.querySelector(
      '.Notification-actionResultUrl-countdown',
    )
    const link = container.querySelector<HTMLAnchorElement>(
      '.Notification-actionResultUrl-link',
    )

    if (countdown == null || link == null) {
      return
    }

    const redirectDelay = container?.getAttribute('data-redirect-delay')

    if (redirectDelay === null || redirectDelay === undefined) {
      return
    }

    let countdownMillis = parseInt(redirectDelay)

    if (isNaN(countdownMillis)) {
      return
    }

    const intervalId = setInterval(() => {
      countdownMillis -= 100

      countdown.textContent = Math.ceil(countdownMillis / 1000).toString()

      if (countdownMillis <= 0) {
        clearInterval(intervalId)
        link.click()
      }
    }, 100)

    // stop the countdown if the link is clicked
    link.addEventListener('click', () => {
      clearInterval(intervalId)
      countdown.textContent = '0'
    })
  },
)

onFind('.Notification-actionBar', (actionBar: HTMLElement) => {
  const limit: string | null = actionBar.getAttribute('actionLimit')
  const list: HTMLElement = create('ul', {
    className: 'Actions-controlsList Dropdown',
    role: 'menu',
  })
  const actions: NodeListOf<HTMLElement> = actionBar.querySelectorAll(
    '.Notification-action',
  )
  let index = 0
  let listSize = 0
  // only the limit number of actions will be displayed, while the remaining will be hidden in a dropdown
  actions.forEach((action: HTMLElement) => {
    if (!limit || index < parseInt(limit)) {
      index++
      return
    }
    const listItem: HTMLElement = create('li')
    listItem.appendChild(action)
    list.appendChild(listItem)
    index++
    listSize++
  })

  // if there are no actions, do not display the dropdown option
  if (listSize === 0) {
    return
  }
  const controls: HTMLElement = create('div', {
    className: 'Actions-controls',
  })
  const toggle: HTMLElement = create('button', {
    className: 'Additional-actionsToggle',
    type: 'button',
    id: 'Additional-actionsToggle',
    'aria-haspopup': 'menu',
    'aria-expanded': 'false',
    onclick: () => {
      listenForMenuItemClick(list, toggle)
      toggleMenu(list, toggle, controls)
    },
  })
  setupMenuForAria(list, toggle)
  controls.appendChild(toggle)
  controls.appendChild(list)
  controls.setAttribute('data-tether-anchor', '')
  actionBar.appendChild(controls)
})
