import React, { useCallback, useOptimistic, useState } from 'react'
import axios from 'axios'

/**
 * Reaction bar for an artwork or comment.
 *
 * Props:
 *   entityType   'artwork' | 'comment'
 *   entityId     number
 *   initialTotals  Record<slug, { emoji, label, count, mine }>
 *   isLoggedIn   boolean  — if false, clicking shows a prompt
 */
export default function ReactionBar({ entityType, entityId, initialTotals = {}, isLoggedIn = false }) {
  const [totals, setTotals] = useState(initialTotals)
  const [loading, setLoading] = useState(null) // slug being toggled

  const endpoint =
    entityType === 'artwork'
      ? `/api/artworks/${entityId}/reactions`
      : `/api/comments/${entityId}/reactions`

  const toggle = useCallback(
    async (slug) => {
      if (!isLoggedIn) {
        window.location.href = '/login'
        return
      }

      if (loading) return // prevent double-click
      setLoading(slug)

      // Optimistic update
      setTotals((prev) => {
        const entry = prev[slug] ?? { count: 0, mine: false }
        return {
          ...prev,
          [slug]: {
            ...entry,
            count: entry.mine ? entry.count - 1 : entry.count + 1,
            mine: !entry.mine,
          },
        }
      })

      try {
        const { data } = await axios.post(endpoint, { reaction: slug })
        setTotals(data.totals)
      } catch {
        // Rollback
        setTotals((prev) => {
          const entry = prev[slug] ?? { count: 0, mine: false }
          return {
            ...prev,
            [slug]: {
              ...entry,
              count: entry.mine ? entry.count - 1 : entry.count + 1,
              mine: !entry.mine,
            },
          }
        })
      } finally {
        setLoading(null)
      }
    },
    [endpoint, isLoggedIn, loading],
  )

  const entries = Object.entries(totals)

  if (entries.length === 0) return null

  return (
    <div
      role="group"
      aria-label="Reactions"
      className="flex flex-wrap items-center gap-1.5"
    >
      {entries.map(([slug, info]) => {
        const { emoji, label, count, mine } = info
        const isProcessing = loading === slug

        return (
          <button
            key={slug}
            type="button"
            disabled={isProcessing}
            onClick={() => toggle(slug)}
            aria-label={`${label} — ${count} reaction${count !== 1 ? 's' : ''}${mine ? ' (your reaction)' : ''}`}
            aria-pressed={mine}
            className={[
              'inline-flex items-center gap-1 px-2.5 py-1 rounded-full text-sm',
              'border transition-all duration-150',
              'focus:outline-none focus-visible:ring-2 focus-visible:ring-sky-500',
              'disabled:opacity-50 disabled:pointer-events-none',
              mine
                ? 'border-sky-500/60 bg-sky-500/15 text-sky-300 hover:bg-sky-500/25'
                : 'border-white/[0.1] bg-white/[0.03] text-white/60 hover:border-white/20 hover:text-white/80',
            ]
              .filter(Boolean)
              .join(' ')}
          >
            <span aria-hidden="true">{emoji}</span>
            <span className="tabular-nums font-medium">{count > 0 ? count : ''}</span>
            <span className="sr-only">{label}</span>
          </button>
        )
      })}
    </div>
  )
}
