import { useEffect, useState } from 'react'
import {
  appendIslanderUnlockKey,
  ISLANDER_UNLOCK_EVENT,
  readIslanderUnlocked,
  toggleIslanderUnlocked,
} from '../lib/islander/unlock'

function shouldIgnoreKeydown(event: KeyboardEvent): boolean {
  if (event.isComposing) return true
  if (event.ctrlKey || event.metaKey || event.altKey) return true

  const el = event.target
  if (!(el instanceof HTMLElement)) return false
  if (el.isContentEditable) return true
  if (el instanceof HTMLInputElement && el.type === 'password') return true

  return false
}

export function useIslanderUnlock() {
  const [unlocked, setUnlocked] = useState(readIslanderUnlocked)

  useEffect(() => {
    const onUnlockChange = (event: Event) => {
      const detail = (event as CustomEvent<{ unlocked?: boolean }>).detail
      setUnlocked(typeof detail?.unlocked === 'boolean' ? detail.unlocked : readIslanderUnlocked())
    }

    window.addEventListener(ISLANDER_UNLOCK_EVENT, onUnlockChange)

    return () => window.removeEventListener(ISLANDER_UNLOCK_EVENT, onUnlockChange)
  }, [])

  useEffect(() => {
    let buffer = ''
    let toggling = false

    const onKeyDown = (event: KeyboardEvent) => {
      if (shouldIgnoreKeydown(event)) return

      const { buffer: nextBuffer, matched } = appendIslanderUnlockKey(buffer, event.key)
      buffer = nextBuffer
      if (!matched || toggling) return

      toggling = true
      const next = toggleIslanderUnlocked()
      setUnlocked(next)
      buffer = ''
      window.setTimeout(() => {
        toggling = false
      }, 200)
    }

    document.addEventListener('keydown', onKeyDown, true)
    return () => document.removeEventListener('keydown', onKeyDown, true)
  }, [])

  return unlocked
}