import { useEffect, useLayoutEffect, useRef, useState } from 'react'
import { createPortal } from 'react-dom'
import { ChevronDown, X } from 'lucide-react'
import clsx from 'clsx'

interface FilterPillProps {
  /** Category label, always shown ("Date", "Type", etc.). */
  label: string
  /** Currently unused in the rendered output — the inline value display
   *  was making active pills wider than inactive ones. Kept on the
   *  interface so callers don't have to change. The value is still
   *  surfaced via the title attribute for hover discovery. */
  value?: string | null
  isActive?: boolean
  /** When provided + isActive, an X appears inside the pill that clears
   *  this filter without opening the popover. */
  onClear?: () => void
  /** Popover contents — usually the existing control for this filter. */
  children: React.ReactNode
  /** Force the popover open programmatically (rare). */
  defaultOpen?: boolean
}

/**
 * A toolbar pill that hosts a filter category. Click the pill to open a
 * small popover with the actual control; the popover closes on outside
 * click or Escape. Active filters tint the pill primary and show their
 * current value inline.
 */
export function FilterPill({
  label,
  value,
  isActive = false,
  onClear,
  children,
  defaultOpen = false,
}: FilterPillProps) {
  const [open, setOpen] = useState(defaultOpen)
  const buttonRef = useRef<HTMLButtonElement>(null)
  const popoverRef = useRef<HTMLDivElement>(null)
  const [popoverPos, setPopoverPos] = useState<{ top: number; left: number } | null>(null)

  // Compute the popover's screen position from the trigger button. Done
  // imperatively (not via CSS absolute) so the popover can live in a portal
  // and escape the FilterBar's overflow-x-auto clipping. Re-computed on
  // open, scroll, and resize.
  useLayoutEffect(() => {
    if (!open) return
    const update = () => {
      const btn = buttonRef.current
      if (!btn) return
      const rect = btn.getBoundingClientRect()
      // Default left-align under the trigger; clamp to viewport so the
      // last pill on the right doesn't overflow.
      const popWidth = popoverRef.current?.offsetWidth ?? 240
      const margin = 8
      let left = rect.left
      if (left + popWidth + margin > window.innerWidth) {
        left = Math.max(margin, window.innerWidth - popWidth - margin)
      }
      setPopoverPos({ top: rect.bottom + 4, left })
    }
    update()
    window.addEventListener('resize', update)
    window.addEventListener('scroll', update, true)
    return () => {
      window.removeEventListener('resize', update)
      window.removeEventListener('scroll', update, true)
    }
  }, [open])

  // Close on outside click + Escape. Outside means neither the trigger
  // button nor the (portaled) popover.
  useEffect(() => {
    if (!open) return
    const onDocMouseDown = (e: MouseEvent) => {
      const target = e.target as Node
      if (buttonRef.current?.contains(target)) return
      if (popoverRef.current?.contains(target)) return
      setOpen(false)
    }
    const 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 (
    <>
      <button
        ref={buttonRef}
        onClick={() => setOpen((v) => !v)}
        // Hover to see the active value as a tooltip — keeps the pill at
        // a constant width regardless of state. The popover is the
        // canonical place to read/edit the filter value.
        title={isActive && value ? `${label}: ${value}` : label}
        className={clsx(
          // Fixed height + py-0 so neither the X clear icon nor the
          // chevron can stretch the pill vertically when the active
          // state swaps them in.
          'flex h-7 items-center gap-1 rounded-full border px-2.5 py-0 text-xs transition-colors',
          isActive
            ? 'border-primary/40 bg-primary/15 text-primary'
            : 'border-border bg-surface-2 text-text-muted hover:bg-surface-offset hover:text-text'
        )}
      >
        <span className={clsx(isActive && 'font-medium')}>{label}</span>
        {isActive && onClear ? (
          <span
            role="button"
            tabIndex={0}
            onClick={(e) => {
              e.stopPropagation()
              onClear()
            }}
            onKeyDown={(e) => {
              if (e.key === 'Enter' || e.key === ' ') {
                e.preventDefault()
                e.stopPropagation()
                onClear()
              }
            }}
            className="ml-0.5 inline-flex h-3.5 w-4 cursor-pointer items-center justify-center rounded-full hover:bg-primary/30"
            title={`Clear ${label}`}
            aria-label={`Clear ${label}`}
          >
            <X className="h-3 w-3" />
          </span>
        ) : (
          <span className="inline-flex h-3.5 w-4 items-center justify-center">
            <ChevronDown className="h-3 w-3 opacity-60" />
          </span>
        )}
      </button>

      {open &&
        createPortal(
          <div
            ref={popoverRef}
            style={{
              position: 'fixed',
              top: popoverPos?.top ?? -9999,
              left: popoverPos?.left ?? -9999,
              visibility: popoverPos ? 'visible' : 'hidden',
            }}
            className="z-50 min-w-[220px] rounded-lg border border-border bg-surface p-3 shadow-xl"
          >
            {children}
          </div>,
          document.body
        )}
    </>
  )
}
