import React, { useCallback, useEffect, useRef, useState } from 'react'
import axios from 'axios'

/* ── Reaction definitions ────────────────────────────────────────────────── */
const REACTIONS = [
  { slug: 'thumbs_up', emoji: '👍', label: 'Like' },
  { slug: 'heart',     emoji: '❤️', label: 'Love' },
  { slug: 'fire',      emoji: '🔥', label: 'Fire' },
  { slug: 'laugh',     emoji: '😂', label: 'Haha' },
  { slug: 'clap',      emoji: '👏', label: 'Clap' },
  { slug: 'wow',       emoji: '😮', label: 'Wow' },
]

/* ── Small heart outline icon for the trigger ─────────────────────────────── */
function HeartOutlineIcon({ className }) {
  return (
    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className={className}>
      <path strokeLinecap="round" strokeLinejoin="round" d="M21 8.25c0-2.485-2.099-4.5-4.688-4.5-1.935 0-3.597 1.126-4.312 2.733-.715-1.607-2.377-2.733-4.313-2.733C5.1 3.75 3 5.765 3 8.25c0 7.22 9 12 9 12s9-4.78 9-12Z" />
    </svg>
  )
}

/**
 * Facebook-style reaction bar.
 *
 * - Compact trigger button (heart icon or the user's reaction)
 * - Floating picker that appears on hover/click with scale animation
 * - Summary row showing unique reaction emoji + total count
 *
 * Props:
 *   entityType    'artwork' | 'comment'
 *   entityId      number
 *   initialTotals Record<slug, { emoji, label, count, mine }>
 *   isLoggedIn    boolean
 */
export default function ReactionBar({ entityType, entityId, initialTotals = {}, isLoggedIn = false }) {
  const [totals, setTotals] = useState(initialTotals)
  const [loading, setLoading] = useState(null)
  const [pickerOpen, setPickerOpen] = useState(false)
  const containerRef = useRef(null)
  const hoverTimeout = useRef(null)

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

  // Close picker when clicking outside
  useEffect(() => {
    if (!pickerOpen) return
    const handler = (e) => {
      if (containerRef.current && !containerRef.current.contains(e.target)) {
        setPickerOpen(false)
      }
    }
    document.addEventListener('mousedown', handler)
    return () => document.removeEventListener('mousedown', handler)
  }, [pickerOpen])

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

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

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

  // Compute summary data
  const entries = Object.entries(totals)
  const activeReactions = entries.filter(([, info]) => info.count > 0)
  const totalCount = activeReactions.reduce((sum, [, info]) => sum + info.count, 0)
  const myReaction = entries.find(([, info]) => info.mine)?.[0] ?? null
  const myReactionData = myReaction ? REACTIONS.find(r => r.slug === myReaction) : null

  // Hover handlers for desktop — open on hover with a small delay
  const onMouseEnter = () => {
    clearTimeout(hoverTimeout.current)
    hoverTimeout.current = setTimeout(() => setPickerOpen(true), 200)
  }
  const onMouseLeave = () => {
    clearTimeout(hoverTimeout.current)
    hoverTimeout.current = setTimeout(() => setPickerOpen(false), 400)
  }

  const isArtworkVariant = entityType === 'artwork'

  const triggerClassName = isArtworkVariant
    ? [
        'inline-flex items-center gap-2.5 rounded-full border px-4 py-2.5 text-sm font-semibold transition-all duration-200',
        'focus:outline-none focus-visible:ring-2 focus-visible:ring-accent/50',
        myReaction
          ? 'border-accent/35 bg-accent/12 text-accent shadow-[0_12px_30px_rgba(245,158,11,0.14)] hover:bg-accent/18'
          : 'border-white/[0.12] bg-white/[0.06] text-white/75 hover:border-accent/30 hover:bg-white/[0.1] hover:text-white',
      ].join(' ')
    : [
        'inline-flex items-center gap-1.5 rounded-full px-2.5 py-1 text-xs font-medium transition-all duration-200',
        'focus:outline-none focus-visible:ring-2 focus-visible:ring-accent/50',
        myReaction
          ? 'text-accent'
          : 'text-white/40 hover:text-white/70',
      ].join(' ')

  const summaryClassName = isArtworkVariant
    ? 'inline-flex items-center gap-2 rounded-full border border-white/[0.1] bg-white/[0.05] px-3 py-1.5 transition-colors hover:border-white/[0.16] hover:bg-white/[0.08] group/summary'
    : 'inline-flex items-center gap-1.5 rounded-full px-1.5 py-0.5 transition-colors hover:bg-white/[0.06] group/summary'

  return (
    <div
      ref={containerRef}
      className={isArtworkVariant ? 'flex flex-wrap items-center gap-3' : 'flex items-center gap-2'}
      onMouseLeave={onMouseLeave}
    >
      {/* ── Trigger button ──────────────────────────────────────────── */}
      <div className="relative" onMouseEnter={onMouseEnter}>
        <button
          type="button"
          onClick={() => {
            if (isArtworkVariant) {
              setPickerOpen((value) => !value)
              return
            }

            if (myReaction) {
              toggle(myReaction)
            } else {
              toggle('thumbs_up')
            }
          }}
          className={triggerClassName}
          aria-label={isArtworkVariant
            ? (myReaction
              ? `Open reaction picker. Current reaction: ${myReactionData?.label}.`
              : 'Open reaction picker for this artwork')
            : (myReaction
              ? `You reacted with ${myReactionData?.label}. Click to remove.`
              : 'React to this comment')}
        >
          {myReaction ? (
            <span className={isArtworkVariant ? 'text-xl leading-none' : 'text-base leading-none'}>{myReactionData?.emoji}</span>
          ) : (
            <HeartOutlineIcon className={isArtworkVariant ? 'h-5 w-5' : 'h-4 w-4'} />
          )}
          <span>{myReaction ? myReactionData?.label : (isArtworkVariant ? 'React to this artwork' : 'React')}</span>
        </button>

        {/* ── Floating picker ─────────────────────────────────────── */}
        {pickerOpen && (
          <div
            className="absolute bottom-full left-0 mb-2 z-[200] animate-in fade-in slide-in-from-bottom-2 duration-200"
            onMouseEnter={() => { clearTimeout(hoverTimeout.current) }}
            onMouseLeave={onMouseLeave}
          >
            <div className="flex items-center gap-0.5 rounded-full bg-nova-800/95 border border-white/[0.1] px-2 py-1.5 shadow-xl shadow-black/40 backdrop-blur-xl">
              {REACTIONS.map((r, i) => {
                const isActive = totals[r.slug]?.mine
                return (
                  <button
                    key={r.slug}
                    type="button"
                    onClick={() => toggle(r.slug)}
                    disabled={loading === r.slug}
                    aria-label={`${r.label}${isActive ? ' (selected)' : ''}`}
                    className={[
                      'group/reaction relative flex items-center justify-center w-9 h-9 rounded-full transition-all duration-200',
                      'hover:bg-white/[0.08] hover:scale-125 hover:-translate-y-1',
                      'focus:outline-none focus-visible:ring-2 focus-visible:ring-accent/50',
                      'disabled:opacity-50',
                      isActive ? 'bg-white/[0.1] scale-110' : '',
                    ].join(' ')}
                    style={{ animationDelay: `${i * 30}ms` }}
                    title={r.label}
                  >
                    <span className="text-xl leading-none transition-transform duration-150 group-hover/reaction:scale-110">
                      {r.emoji}
                    </span>
                    {/* Tooltip */}
                    <span className="pointer-events-none absolute -top-7 left-1/2 -translate-x-1/2 rounded bg-black/80 px-1.5 py-0.5 text-[10px] font-medium text-white/90 opacity-0 transition-opacity group-hover/reaction:opacity-100 whitespace-nowrap">
                      {r.label}
                    </span>
                  </button>
                )
              })}
            </div>
          </div>
        )}
      </div>

      {/* ── Summary: stacked emoji + count ───────────────────────── */}
      {totalCount > 0 && (
        <button
          type="button"
          onClick={() => setPickerOpen(v => !v)}
          className={summaryClassName}
          aria-label={`${totalCount} reaction${totalCount !== 1 ? 's' : ''}`}
        >
          {/* Stacked emoji circles (Facebook-style, max 3) */}
          <span className="inline-flex items-center -space-x-1">
            {activeReactions.slice(0, 3).map(([slug, info], i) => (
              <span
                key={slug}
                className="relative flex items-center justify-center w-5 h-5 rounded-full bg-nova-700 border border-nova-800 text-xs leading-none"
                style={{ zIndex: 3 - i }}
                title={info.label}
              >
                {info.emoji}
              </span>
            ))}
          </span>
          <span className="text-xs font-medium tabular-nums text-white/50 group-hover/summary:text-white/70 transition-colors">
            {totalCount}
          </span>
        </button>
      )}
    </div>
  )
}
