'use client'

import { createContext, useCallback, useContext, useRef, useState, type ReactNode, type RefObject } from 'react'
import { createPortal } from 'react-dom'
import FlyingImage from './FlyingImage'

interface Flight {
  id: number
  imageUrl: string
  startRect: DOMRect
  endRect: DOMRect
}

interface CartUIContextValue {
  cartIconRef: RefObject<HTMLElement | null>
  // Triggers the grab-and-throw animation from `sourceEl` to the registered
  // cart icon. No-ops (calling onLand immediately) if the cart icon hasn't
  // registered yet, sourceEl is missing, or prefers-reduced-motion is set.
  fly: (sourceEl: HTMLElement | null, imageUrl: string, onLand?: () => void) => void
}

const CartUIContext = createContext<CartUIContextValue | null>(null)

// Single global "flight slot" — only one clone flies at a time, which is a
// deliberate simplification (rapid repeated clicks just restart the flight
// rather than queuing multiple clones). Portalled to document.body so it's
// never clipped by a card's own overflow:hidden.
export function CartUIProvider({ children }: { children: ReactNode }) {
  const cartIconRef = useRef<HTMLElement | null>(null)
  const [flight, setFlight] = useState<Flight | null>(null)
  const onLandRef = useRef<(() => void) | null>(null)

  const fly = useCallback((sourceEl: HTMLElement | null, imageUrl: string, onLand?: () => void) => {
    const cartEl = cartIconRef.current
    const prefersReducedMotion =
      typeof window !== 'undefined' && window.matchMedia('(prefers-reduced-motion: reduce)').matches

    if (!sourceEl || !cartEl || prefersReducedMotion) {
      onLand?.()
      return
    }

    onLandRef.current = onLand ?? null
    setFlight({
      id: Date.now(),
      imageUrl,
      startRect: sourceEl.getBoundingClientRect(),
      endRect: cartEl.getBoundingClientRect(),
    })
  }, [])

  const handleComplete = useCallback(() => {
    setFlight(null)
    onLandRef.current?.()
    onLandRef.current = null
  }, [])

  return (
    <CartUIContext.Provider value={{ cartIconRef, fly }}>
      {children}
      {flight && typeof document !== 'undefined'
        ? createPortal(
            <FlyingImage key={flight.id} imageUrl={flight.imageUrl} startRect={flight.startRect} endRect={flight.endRect} onComplete={handleComplete} />,
            document.body,
          )
        : null}
    </CartUIContext.Provider>
  )
}

export function useCartUI(): CartUIContextValue {
  const ctx = useContext(CartUIContext)
  if (!ctx) {
    throw new Error('useCartUI must be used within CartUIProvider (see (root)/[locale]/layout.tsx)')
  }
  return ctx
}
