import { useEffect, useRef, useState } from 'react'
import { ACCEPT_GLYPH, REJECT_GLYPH } from './components/Thumbs'

// Shared culling interaction for a lightbox over a (possibly filtered) photo
// list: the keyboard table (P/X/U, stars, select), swipe gestures, the
// action toast, and the modal fade-out after voting the last photo.
export default function useCulling({
  visible,
  lightbox,
  setVerdict,
  setRating,
  toggle,
  canSelect = true,
}) {
  const [flash, setFlash] = useState(null)
  const flashSeq = useRef(0)
  const flashTimer = useRef()
  const showFlash = (text) => {
    flashSeq.current += 1
    setFlash({ text, key: flashSeq.current })
    clearTimeout(flashTimer.current)
    flashTimer.current = setTimeout(() => setFlash(null), 1400)
  }
  useEffect(() => () => clearTimeout(flashTimer.current), [])

  const [fading, setFading] = useState(false)
  useEffect(() => {
    if (lightbox.index < 0) setFading(false)
  }, [lightbox.index])

  // Keyboard votes stay on the photo (the footer controls show the result);
  // only touch gestures advance, where the fly-off animation carries the
  // context.
  const vote = (photo, verdict) => {
    setVerdict(photo, verdict)
    showFlash(
      verdict === 'accept' ? `${ACCEPT_GLYPH} ${photo.filename}` : `${REJECT_GLYPH} ${photo.filename}`,
    )
  }

  const voteAndAdvance = (photo, verdict) => {
    const next = visible[lightbox.index + 1]
    setVerdict(photo, verdict)
    showFlash(
      verdict === 'accept'
        ? `${ACCEPT_GLYPH} ${photo.filename}`
        : verdict === 'reject'
          ? `${REJECT_GLYPH} ${photo.filename}`
          : `↺ ${photo.filename} cleared`,
    )
    if (next) lightbox.show(next.id)
    else setFading(true)
  }

  const keyActions = [
    { keys: ['p'], help: ['P', 'accept'], run: (p) => vote(p, 'accept') },
    { keys: ['x'], help: ['X', 'reject'], run: (p) => vote(p, 'reject') },
    { keys: ['u'], help: ['U', 'clear accept / reject'], run: (p) => setVerdict(p, null) },
    {
      keys: ['1', '2', '3', '4', '5'],
      help: ['1–5', 'star rating'],
      run: (p, key) => setRating(p, Number(key)),
    },
    { keys: ['0'], help: ['0', 'clear star rating'], run: (p) => setRating(p, 0) },
    ...(canSelect
      ? [{ keys: ['s'], help: ['S', 'select for download'], run: (p) => toggle(p.id) }]
      : []),
  ]

  return {
    flash,
    keyActions,
    lightboxProps: {
      actions: keyActions,
      gestures: {
        up: (p) => voteAndAdvance(p, 'accept'),
        down: (p) => voteAndAdvance(p, 'reject'),
      },
      closing: fading,
      onClosed: () => {
        setFading(false)
        lightbox.close()
      },
    },
  }
}
