import { useRef, useState } from 'react'
import { useCoverUrl } from '../hooks/useCoverUrl'

export type QueueItem = {
  slug: string
  title: string
  artist: string
  album_slug: string | null
  duration: number | null
}

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

function pad(n: number) {
  return String(n).padStart(2, '0')
}

function fmt(secs: number) {
  if (!secs || Number.isNaN(secs)) return '0:00'
  const s = Math.floor(secs)
  const m = Math.floor(s / 60)
  const h = Math.floor(m / 60)
  if (h > 0) return `${h}:${pad(m % 60)}:${pad(s % 60)}`
  return `${m}:${pad(s % 60)}`
}

function Cover({ slug }: { slug: string }) {
  const [errored, setErrored] = useState(false)
  const src = useCoverUrl(slug)

  if (!src || errored) return <>&#127925;</>
  return <img src={src} alt="" onError={() => setErrored(true)} />
}

export function QueueList({
  queue,
  order,
  playingOrigIdx,
  scrollSignal,
  onPlay,
  onRemove,
  onMove,
}: QueueListProps) {
  const playingRef = useRef<HTMLDivElement | null>(null)
  const [draggingPos, setDraggingPos] = useState<number | null>(null)
  const [dragOverPos, setDragOverPos] = useState<number | null>(null)

  useEffect(() => {
    if (playingRef.current) {
      playingRef.current.scrollIntoView({ behavior: 'smooth', block: 'nearest' })
    }
  }, [playingOrigIdx, scrollSignal])

  if (!queue.length) {
    return (
      <div className="queue-empty">
        <div className="empty-icon">&#127925;</div>
        <div>Select an album to start</div>
      </div>
    )
  }

  return (
    <>
      {order.map((origIdx, pos) => {
        const t = queue[origIdx]
        if (!t) return null

        const isPlaying = origIdx === playingOrigIdx
        const hasAlbum = !!t.album_slug
        const dur = t.duration ? fmt(t.duration) : ''
        const isDragging = draggingPos === pos
        const isDragOver = dragOverPos === pos

        return (
          <div
            key={`${t.slug}:${pos}`}
            ref={isPlaying ? playingRef : null}
            className={`queue-item${isPlaying ? ' playing' : ''}${isDragging ? ' dragging' : ''}${
              isDragOver ? ' drag-over' : ''
            }`}
            draggable
            onClick={() => onPlay(origIdx)}
            onDragStart={(e) => {
              setDraggingPos(pos)
              e.dataTransfer?.setData('text/plain', String(pos))
            }}
            onDragEnd={() => {
              setDraggingPos(null)
              setDragOverPos(null)
            }}
            onDragOver={(e) => {
              e.preventDefault()
            }}
            onDragEnter={() => {
              setDragOverPos(pos)
            }}
            onDragLeave={() => {
              setDragOverPos((cur) => (cur === pos ? null : cur))
            }}
            onDrop={(e) => {
              e.preventDefault()
              setDragOverPos(null)
              const from = parseInt(e.dataTransfer?.getData('text/plain') ?? '', 10)
              if (!Number.isNaN(from)) onMove(from, pos)
              setDraggingPos(null)
            }}
          >
            <span className="qi-index">{isPlaying ? '' : pos + 1}</span>
            <div className="qi-cover">
              {hasAlbum ? <Cover slug={t.slug} /> : <>&#127925;</>}
            </div>
            <div className="qi-info">
              <div className="qi-title">{t.title}</div>
              <div className="qi-artist">{t.artist || ''}</div>
            </div>
            <span className="qi-dur">{dur}</span>
            <button
              className="qi-remove"
              onClick={(e) => {
                e.stopPropagation()
                onRemove(origIdx)
              }}
            >
              &#10005;
            </button>
          </div>
        )
      })}
    </>
  )
}

