import { useEffect, useRef, useState } from 'react'
import { createPortal } from 'react-dom'
import { Eraser, MoreHorizontal, Trash2, Users } from 'lucide-react'
import styles from './BusinessActionsOverflowMenu.module.css'

type PopoverPosition = {
  top: number
  left: number
}

interface BusinessActionsOverflowMenuProps {
  businessName: string
  onAllUsers: () => void
  onWipeData: () => void
  onRemove: () => void
}

export function BusinessActionsOverflowMenu({
  businessName,
  onAllUsers,
  onWipeData,
  onRemove,
}: BusinessActionsOverflowMenuProps) {
  const [open, setOpen] = useState(false)
  const [popoverPos, setPopoverPos] = useState<PopoverPosition | null>(null)
  const wrapRef = useRef<HTMLDivElement>(null)
  const popoverRef = useRef<HTMLDivElement>(null)
  const triggerRef = useRef<HTMLButtonElement>(null)

  function updatePopoverPosition() {
    const rect = triggerRef.current?.getBoundingClientRect()
    if (!rect) return

    setPopoverPos({
      top: rect.bottom + 8,
      left: rect.right,
    })
  }

  function toggleOpen() {
    if (open) {
      setOpen(false)
      return
    }

    updatePopoverPosition()
    setOpen(true)
  }

  useEffect(() => {
    if (!open) return

    function handleClickOutside(e: MouseEvent) {
      const target = e.target as Node
      if (wrapRef.current?.contains(target)) return
      if (popoverRef.current?.contains(target)) return
      setOpen(false)
    }

    function handleEscape(e: KeyboardEvent) {
      if (e.key === 'Escape') setOpen(false)
    }

    function handleReposition() {
      updatePopoverPosition()
    }

    document.addEventListener('mousedown', handleClickOutside)
    document.addEventListener('keydown', handleEscape)
    window.addEventListener('resize', handleReposition)
    window.addEventListener('scroll', handleReposition, true)

    return () => {
      document.removeEventListener('mousedown', handleClickOutside)
      document.removeEventListener('keydown', handleEscape)
      window.removeEventListener('resize', handleReposition)
      window.removeEventListener('scroll', handleReposition, true)
    }
  }, [open])

  return (
    <div className={styles.wrap} ref={wrapRef}>
      <button
        ref={triggerRef}
        type="button"
        className={`${styles.trigger} ${open ? styles.triggerOpen : ''}`}
        onClick={(e) => {
          e.preventDefault()
          e.stopPropagation()
          toggleOpen()
        }}
        title="More actions"
        aria-label={`More actions for ${businessName}`}
        aria-haspopup="menu"
        aria-expanded={open}
      >
        <MoreHorizontal size={16} />
      </button>

      {open &&
        popoverPos &&
        createPortal(
          <div
            ref={popoverRef}
            className={styles.menu}
            role="menu"
            aria-label={`More actions for ${businessName}`}
            style={{
              top: popoverPos.top,
              left: popoverPos.left,
            }}
          >
            <button
              type="button"
              className={styles.item}
              role="menuitem"
              onClick={() => {
                setOpen(false)
                onAllUsers()
              }}
            >
              <Users size={16} />
              <span>All users</span>
            </button>
            <button
              type="button"
              className={`${styles.item} ${styles.itemDanger}`}
              role="menuitem"
              onClick={(e) => {
                e.preventDefault()
                e.stopPropagation()
                setOpen(false)
                onWipeData()
              }}
            >
              <Eraser size={16} />
              <span>Wipe data</span>
            </button>
            <button
              type="button"
              className={`${styles.item} ${styles.itemDanger}`}
              role="menuitem"
              onClick={() => {
                setOpen(false)
                onRemove()
              }}
            >
              <Trash2 size={16} />
              <span>Remove</span>
            </button>
          </div>,
          document.body,
        )}
    </div>
  )
}
