import { useEffect, useId, useRef, useState } from 'react'
import { QueueList, type QueueItem } from '../QueueList'
import styles from './queue-popover.module.css'

export type QueuePopoverProps = {
  queue: QueueItem[]
  order: number[]
  playingOrigIdx: number
  scrollSignal: number
  onPlay: (origIdx: number) => void
  onRemove: (origIdx: number) => void
  onMove: (fromPos: number, toPos: number) => void
}

export function QueuePopover({
  queue,
  order,
  playingOrigIdx,
  scrollSignal,
  onPlay,
  onRemove,
  onMove,
}: QueuePopoverProps) {
  const [open, setOpen] = useState(false)
  const rootRef = useRef<HTMLDivElement>(null)
  const titleId = useId()
  const panelId = useId()

  useEffect(() => {
    if (!open) return
    function onDocMouseDown(e: MouseEvent) {
      const el = rootRef.current
      if (el && !el.contains(e.target as Node)) setOpen(false)
    }
    function onKey(e: KeyboardEvent) {
      if (e.key === 'Escape') setOpen(false)
    }
    document.addEventListener('mousedown', onDocMouseDown)
    document.addEventListener('keydown', onKey)
    return () => {
      document.removeEventListener('mousedown', onDocMouseDown)
      document.removeEventListener('keydown', onKey)
    }
  }, [open])

  return (
    <div className={styles.root} ref={rootRef}>
      <button
        type="button"
        className={styles.trigger}
        title="Playback queue"
        aria-expanded={open}
        aria-haspopup="dialog"
        aria-controls={open ? panelId : undefined}
        onClick={() => setOpen((v) => !v)}
      >
        <span className={styles.triggerIcon} aria-hidden>
          &#9776;
        </span>
      </button>
      {open && (
        <div
          id={panelId}
          className={styles.popover}
          role="dialog"
          aria-labelledby={titleId}
        >
          <div className={styles.header} id={titleId}>
            Queue
          </div>
          <div className={styles.body}>
            <QueueList
              queue={queue}
              order={order}
              playingOrigIdx={playingOrigIdx}
              scrollSignal={scrollSignal}
              onPlay={onPlay}
              onRemove={onRemove}
              onMove={onMove}
            />
          </div>
        </div>
      )}
    </div>
  )
}
