const getTbody = () => {
  const table = document.querySelector('#commits-table')
  if (!table) {
    return
  }
  const tbody = table.getElementsByTagName('tbody')[0]
  return {
    tbody,
    rowNodes: tbody && [...tbody.childNodes]
  }
}

let mutationObserver
let isFiltered = false
const allRowNodes = []

const pushNewNodes = rowNodes => {
  console.log(`pushNewNodes(${rowNodes.length} nodes) into allRowNodes (length ${allRowNodes.length})`)
  let found = true
  for (const row of rowNodes) {
    if (!allRowNodes.includes(row)) {
      found = false
    }
    if (!found) {
      allRowNodes.push(row)
    }
  }
}

const filterToAuthorName = (authorName, refreshing) => {
  console.log({ authorName, refreshing, isFiltered })
  if (!refreshing && isFiltered) {
    console.log('removeFilter redirect')
    removeFilter()
    return
  }
  isFiltered = true
  const { tbody, rowNodes } = getTbody()
  if (!tbody || !rowNodes.length) {
    return
  }
  const badRowNodes = rowNodes.filter(row => !row.innerHTML.includes(authorName))
  badRowNodes.forEach(row => {
    try {
      tbody.removeChild(row)
    } catch (e) {
      // Continue removing
    }
  })
  pushNewNodes(rowNodes)

  // Scroll-event-consuming function:
  // function(e) {
  //   return N !== undefined && N.event.triggered !== e.type ? N.event.dispatch.apply(t, arguments) : void 0
  // }
  // document.getElementsByTagName('html')[0].dispatchEvent(new Event('scroll'))

  if (!refreshing) {
    console.log('allRowNodes.pop()')
    while (allRowNodes.pop()) {}
    allRowNodes.push(...rowNodes)
    mutationObserver = new MutationObserver((mutationList, observer) => {
      addAuthorFilterClicks()
      filterToAuthorName(authorName, true)
    })
    mutationObserver.observe(tbody, { childList: true })
  }
  // console.log('allRowNodes.length', allRowNodes.length)
}

const removeFilter = () => {
  isFiltered = false
  const { tbody, rowNodes } = getTbody()
  if (!tbody) {
    return
  }
  console.log({ rowNodes, allRowNodes })
  mutationObserver.disconnect()
  rowNodes.forEach(row => tbody.removeChild(row))
  allRowNodes.forEach(row => tbody.appendChild(row))
}

let notifyClearTimeoutId
let notifyDiv = document.createElement('div')
let hasAppended = false

const notify = message => {
  if (!hasAppended) {
    document.getElementsByTagName('body')[0].appendChild(notifyDiv)
    hasAppended = true
  }
  if (notifyClearTimeoutId) {
    clearTimeout(notifyClearTimeoutId)
  }

  notifyDiv.innerText = message
  notifyDiv.style = `
    position: sticky;
    min-height: 20px;
    min-width: 100px;
    background-color: #cad4e3;
    z-index: 99;
    top: 0;
    text-align: center;
    padding: 0.5em;
    visibility: visible;
  `

  notifyClearTimeoutId = setTimeout(hideNotification, 5000)
}

const hideNotification = () => {
  if (notifyClearTimeoutId) {
    clearTimeout(notifyClearTimeoutId)
  }
  notifyDiv.style.visibility = 'hidden'
}

const addAuthorFilterClicks = () => {
  const { rowNodes } = getTbody()
  rowNodes?.forEach(row => {
    const clickable = row.getElementsByClassName('aui-avatar-inner')[0]
    const authorName = row.getElementsByClassName('name-section')[0]?.title
    const clickListener = e => {
      e.stopPropagation()
      filterToAuthorName(authorName)
    }
    const mouseOverListener = () => {
      notify(`Click to filter by the author '${authorName}'`)
    }
    clickable?.removeEventListener('click', clickListener)
    clickable?.parentNode.removeEventListener('click', clickListener)
    clickable?.removeEventListener('mouseenter', mouseOverListener)
    clickable?.parentNode.removeEventListener('mouseenter', mouseOverListener)
    clickable?.removeEventListener('mouseleave', hideNotification)
    clickable?.parentNode.removeEventListener('mouseleave', hideNotification)

    clickable?.addEventListener('click', clickListener)
    clickable?.parentNode.addEventListener('click', clickListener)
    clickable?.addEventListener('mouseenter', mouseOverListener)
    clickable?.parentNode.addEventListener('mouseenter', mouseOverListener)
    clickable?.addEventListener('mouseleave', hideNotification)
    clickable?.parentNode.addEventListener('mouseleave', hideNotification)
    clickable && (clickable.style.cursor = 'pointer')
    clickable?.parentNode && (clickable.parentNode.style.cursor = 'pointer')
    console.log('clickable.style', clickable?.style)
    console.log('clickable?.parentNode.style', clickable?.parentNode.style)
  })
}

addFix(addAuthorFilterClicks)
setInterval(addAuthorFilterClicks, 5000)