'use client'

import { useEffect, useState, memo, useRef, useMemo, type RefObject } from 'react'
import Image from 'next/image'
import { motion, AnimatePresence } from 'framer-motion'
import { useCatalogStore } from '@/lib/store'
import type { Product } from '@/lib/types'
import { Check, Plus, Minus, X, MapPin, Eye } from 'lucide-react'
import { formatPrice, getEffectivePrice } from '@/lib/catalog-utils'
import { getDefaultPinPosition, getPinScale } from '@/lib/pin-layout'
import { useIsMobile } from '@/hooks/use-mobile'

// Movement threshold (px) to distinguish a click from a drag
const DRAG_THRESHOLD = 5
// How long the "NEW" pulse shows on a freshly-added manual pin
const NEW_PIN_TTL = 3000

// =========================================================================
// PageProductPins — the pins layer rendered ON TOP of a catalog page image.
//
// One pin per product on the page (auto pins) plus any manually-added pins.
// Pins are draggable and their position persists (keyed by `${page}:${code}`).
//
// Data comes from the global in-memory product cache (preloaded at startup)
// so page navigation is instant — no per-page API calls in the normal path.
// =========================================================================
export const PageProductPins = memo(function PageProductPins({ page }: { page: number }) {
  const manualPins = useCatalogStore(s => s.manualPins)
  const allCachedProducts = useCatalogStore(s => s.products)
  const hiddenPins = useCatalogStore(s => s.hiddenPins)
  const managePinsMode = useCatalogStore(s => s.managePinsMode)
  const initPinPosition = useCatalogStore(s => s.initPinPosition)

  // Layer ref — shared with every ProductPin so drag coordinates are computed
  // against this element's bounding rect (no fragile parentElement traversal).
  const layerRef = useRef<HTMLDivElement | null>(null)

  // manualPins for this page, with createdAt timestamps for the "NEW" pulse.
  const manualForPage = useMemo(
    () => manualPins.filter(m => m.page === page),
    [manualPins, page],
  )
  const manualCreatedAt = useMemo(() => {
    const map = new Map<string, number>()
    manualForPage.forEach(m => map.set(m.code, m.createdAt))
    return map
  }, [manualForPage])

  // Derive products from the in-memory cache: auto (matched by page) + manual.
  const { autoProducts, manualProducts } = useMemo(() => {
    if (!allCachedProducts || allCachedProducts.length === 0) {
      return { autoProducts: [] as Product[], manualProducts: [] as Product[] }
    }
    const auto = allCachedProducts.filter(p => p.page === page)
    const manual = manualForPage
      .map(m => allCachedProducts.find(p => p.code === m.code))
      .filter((p): p is Product => Boolean(p))
    return { autoProducts: auto, manualProducts: manual }
  }, [allCachedProducts, page, manualForPage])

  // Fallback: if the cache is empty (preload failed), fetch this page's
  // products directly so pins still show up. Safety net only.
  const [fallbackAuto, setFallbackAuto] = useState<Product[]>([])
  useEffect(() => {
    if (allCachedProducts.length > 0) return
    let cancelled = false
    fetch(`/api/products?catalogPage=${page}&limit=100`)
      .then(r => r.json())
      .then(res => { if (!cancelled) setFallbackAuto(res.data || []) })
      .catch(() => {})
    return () => { cancelled = true }
  }, [allCachedProducts.length, page])

  const autoResolved = autoProducts.length > 0 ? autoProducts : fallbackAuto

  // Combine auto + manual pins into a single list, DEDUPLICATED by product
  // code. A product can appear on a page both as an auto-pin (because its
  // `page` field matches) AND as a manual pin (user added it via "+"). In
  // that case we keep the MANUAL entry — it carries `isManual` + `createdAt`
  // for the purple "NOVO" styling — and drop the auto duplicate so React
  // keys stay unique (`${code}-${page}`).
  const seen = new Set<string>()
  const allPins: Array<{ product: Product; isManual: boolean; createdAt?: number }> = []
  // Manual pins first (they win on conflict)
  for (const product of manualProducts) {
    if (seen.has(product.code)) continue
    seen.add(product.code)
    allPins.push({ product, isManual: true, createdAt: manualCreatedAt.get(product.code) })
  }
  for (const product of autoResolved) {
    if (seen.has(product.code)) continue
    seen.add(product.code)
    allPins.push({ product, isManual: false })
  }

  // In manage mode, show ALL pins (even hidden ones) so the user can un-hide
  // them. In normal mode, filter out hidden AUTO-pins.
  //
  // IMPORTANT: Manual pins are explicit admin additions (added via "+") — they
  // must NEVER be hidden by the auto-pin hide state. A product can appear both
  // as an auto-pin on its natural catalog page AND as a manual pin on an
  // index/summary page. When the admin hides the auto-pin (to avoid
  // duplication on the original page), the manual pin on the index page must
  // stay visible. Otherwise hiding a code would silently wipe out every
  // manual pin for that code across all pages.
  const visiblePins = managePinsMode
    ? allPins
    : allPins.filter(({ product, isManual }) => isManual || !hiddenPins.includes(product.code))

  // Persist a FIXED default position for every visible pin on this page.
  // Each pin gets its spot saved (keyed by `page:code`) the first time it
  // appears, so it never shifts when other pins are added/removed.
  const codesKey = visiblePins.map(p => p.product.code).join(',')
  useEffect(() => {
    if (!codesKey) return
    const codes = codesKey.split(',')
    const total = codes.length
    codes.forEach((code, i) => {
      const pos = getDefaultPinPosition(i, total)
      initPinPosition(page, code, pos.x, pos.y)
    })
  }, [page, codesKey, initPinPosition])

  return (
    <>
      {/* Pins layer — covers the whole page image.
          pointer-events-none so only the pins themselves are interactive. */}
      <div
        ref={layerRef}
        className="absolute inset-0 pointer-events-none z-20"
        aria-label="Botões de compra dos produtos"
      >
        {visiblePins.map(({ product, isManual, createdAt }, i) => (
          <ProductPin
            key={`${product.code}-${page}`}
            product={product}
            page={page}
            isManual={isManual}
            // Manual pins can't be "hidden" — they're either present or
            // deleted. Only auto-pins carry the hidden state, so the ManagePin
            // × button renders as red "delete" for manual pins (not green
            // "un-hide"). This keeps the manage-mode UI honest: clicking × on
            // a manual pin removes it; clicking × on a hidden auto-pin
            // un-hides it.
            isHidden={!isManual && hiddenPins.includes(product.code)}
            defaultIndex={i}
            total={visiblePins.length}
            createdAt={createdAt}
            layerRef={layerRef}
          />
        ))}
      </div>

      {/* Floating "+" button to add a manual pin by product code.
          Só aparece no modo de edição de pins — que está desativado
          (o botão "Editar pins" foi removido do control bar), então
          este FAB nunca renderiza na prática. Mantido no código para
          reativação fácil. */}
      {managePinsMode && <AddPinButton page={page} />}
    </>
  )
})

// =========================================================================
// usePinDrag — pointer-based drag hook with click/drag discrimination.
//
// Returns pointer handlers to spread onto the pin's outer div, plus a
// `dragging` flag for visual feedback. `onMove(x, y)` receives relative
// coordinates (0..1) clamped to [0.02, 0.98] so the pin stays on screen.
// `onClick` fires only when the pointer went down AND up without moving past
// DRAG_THRESHOLD — i.e. a genuine click, not a drag.
//
// `enabled` (default true): when false, the drag is fully disabled — pins
// can't be moved — but click detection still works (onClick fires on
// pointerUp). Used to lock pins in their fixed positions.
// =========================================================================
function usePinDrag(
  layerRef: RefObject<HTMLDivElement | null>,
  onMove: (x: number, y: number) => void,
  onClick: () => void,
  enabled: boolean = true,
) {
  const [dragging, setDragging] = useState(false)
  const startRef = useRef<{ x: number; y: number; moved: boolean } | null>(null)

  const onPointerDown = (e: React.PointerEvent) => {
    if (e.button !== 0 && e.pointerType === 'mouse') return
    startRef.current = { x: e.clientX, y: e.clientY, moved: false }
    if (enabled) {
      setDragging(true)
      ;(e.target as HTMLElement).setPointerCapture?.(e.pointerId)
    }
  }

  const onPointerMove = (e: React.PointerEvent) => {
    if (!enabled) return
    const start = startRef.current
    if (!start) return
    const dx = e.clientX - start.x
    const dy = e.clientY - start.y
    if (!start.moved && (Math.abs(dx) > DRAG_THRESHOLD || Math.abs(dy) > DRAG_THRESHOLD)) {
      start.moved = true
    }
    if (!start.moved) return
    const rect = layerRef.current?.getBoundingClientRect()
    if (!rect) return
    const x = Math.max(0.02, Math.min(0.98, (e.clientX - rect.left) / rect.width))
    const y = Math.max(0.02, Math.min(0.98, (e.clientY - rect.top) / rect.height))
    onMove(x, y)
  }

  const onPointerUp = (e: React.PointerEvent) => {
    const start = startRef.current
    if (!start) return
    startRef.current = null
    if (enabled) {
      setDragging(false)
      ;(e.target as HTMLElement).releasePointerCapture?.(e.pointerId)
    }
    if (!start.moved) onClick()
  }

  return {
    dragging,
    handlers: {
      onPointerDown,
      onPointerMove,
      onPointerUp,
      onPointerCancel: onPointerUp,
    },
  }
}

// =========================================================================
// ProductPin — a single draggable buy button.
//
// Visual states:
//   • manage mode  → pin + red × (delete manual / hide auto)
//   • justAdded    → green checkmark (1.1s after adding to cart)
//   • qty > 0      → amber stepper (− qty +)
//   • default      → amber circle with pin icon (purple for manual)
//   • isNew        → pulsing green ring + "NOVO" badge (manual pin < 3s old)
// =========================================================================
const ProductPin = memo(function ProductPin({
  product, page, isManual, isHidden, defaultIndex, total, createdAt, layerRef,
}: {
  product: Product
  page: number
  isManual: boolean
  isHidden: boolean
  defaultIndex: number
  total: number
  createdAt?: number
  layerRef: RefObject<HTMLDivElement | null>
}) {
  // --- Store bindings ---
  const cart = useCatalogStore(s => s.cart)
  const addToCart = useCatalogStore(s => s.addToCart)
  const incrementCart = useCatalogStore(s => s.incrementCart)
  const decrementCart = useCatalogStore(s => s.decrementCart)
  const setCartOpen = useCatalogStore(s => s.setCartOpen)
  const setSelectedProduct = useCatalogStore(s => s.setSelectedProduct)
  const pinPositions = useCatalogStore(s => s.pinPositions)
  const setPinPosition = useCatalogStore(s => s.setPinPosition)
  const clearPinPosition = useCatalogStore(s => s.clearPinPosition)
  const removeManualPin = useCatalogStore(s => s.removeManualPin)
  const toggleHiddenPin = useCatalogStore(s => s.toggleHiddenPin)
  const managePinsMode = useCatalogStore(s => s.managePinsMode)
  const swipeAnimationToken = useCatalogStore(s => s.swipeAnimationToken)

  // --- Local UI state ---
  const [hovered, setHovered] = useState(false)
  const [justAdded, setJustAdded] = useState(false)
  // Re-evaluate "isNew" once after the TTL elapses (no per-render setState).
  const [now, setNow] = useState(() => Date.now())
  useEffect(() => {
    if (!isManual || !createdAt) return
    const age = Date.now() - createdAt
    if (age >= NEW_PIN_TTL) return
    const t = setTimeout(() => setNow(Date.now()), NEW_PIN_TTL - age)
    return () => clearTimeout(t)
  }, [isManual, createdAt])

  const isNew = isManual && !!createdAt && (now - createdAt) < NEW_PIN_TTL

  // --- Derived product info ---
  const item = cart.find(i => i.code === product.code)
  const qty = item?.qty || 0
  const effectivePrice = getEffectivePrice(product)
  const hasPromo = product.promotionalPrice !== null && product.promotionalPrice < product.price

  // --- Position ---
  const customPos = pinPositions[`${page}:${product.code}`]
  const fallback = getDefaultPinPosition(defaultIndex, total)
  const posX = customPos?.x ?? fallback.x
  const posY = customPos?.y ?? fallback.y
  const pinScale = getPinScale(total)

  // --- Mobile detection ---
  // On mobile, tapping a pin that's already in the cart (qty > 0) must NOT
  // open the cart drawer — that was disruptive (felt like the cart kept
  // popping open on every tap). Instead, mobile users adjust qty via the
  // +/− stepper buttons and open the cart via the header cart icon or the
  // floating "Finalizar" button. Desktop keeps the "tap to open cart"
  // behavior (precise mouse, less accidental).
  const isMobile = useIsMobile()

  // Key for the swipe animation — when this changes, the animation re-runs.
  const [localAnimKey, setLocalAnimKey] = useState(0)
  useEffect(() => {
    if (isMobile && swipeAnimationToken > 0) {
      setLocalAnimKey(swipeAnimationToken)
    }
  }, [swipeAnimationToken, isMobile])

  // --- Drag / click handling ---
  const handleAdd = () => {
    if (qty === 0) {
      addToCart(product.code, 1)
      setJustAdded(true)
      setTimeout(() => setJustAdded(false), 1100)
    } else if (!isMobile) {
      setCartOpen(true)
    }
    // On mobile when qty > 0: do nothing — use +/− buttons or header cart.
  }

  const { dragging, handlers } = usePinDrag(
    layerRef,
    (x, y) => setPinPosition(page, product.code, x, y),
    handleAdd,
    managePinsMode, // drag habilitado apenas em modo de edição
  )

  // Shared delete action (used by manage mode + hover flyout + hover pin)
  const handleDelete = (e: React.SyntheticEvent) => {
    e.stopPropagation()
    if (isManual) {
      removeManualPin(product.code, page)
      clearPinPosition(page, product.code)
    } else {
      toggleHiddenPin(product.code)
    }
  }

  return (
    <div
      className="absolute pointer-events-auto"
      style={{
        left: `${posX * 100}%`,
        top: `${posY * 100}%`,
        transform: `translate(-50%, -50%) scale(${dragging ? 1 : pinScale})`,
        cursor: dragging ? 'grabbing' : 'pointer',
        touchAction: 'none',
        zIndex: dragging ? 40 : 20,
      }}
      onMouseEnter={() => setHovered(true)}
      onMouseLeave={() => setHovered(false)}
      {...handlers}
    >
      {/* Inner motion wrapper handles entrance + state-change animations.
          The outer div keeps position + drag transform separate so the
          spring animations don't fight the drag scale. */}
      <motion.div
        key={localAnimKey || 'static'}
        initial={{ scale: 0, opacity: 0 }}
        animate={{ scale: 1, opacity: 1 }}
        transition={{
          type: 'spring',
          damping: 18,
          stiffness: 380,
          // Stagger by index so pins cascade in (capped at 0.4s so big
          // pages don't make the last pin wait too long).
          delay: Math.min(defaultIndex * 0.025, 0.4),
        }}
        className={`relative ${isMobile && localAnimKey > 0 ? 'animate-pin-swipe' : ''}`}
      >
      {managePinsMode ? (
        <ManagePin
          product={product}
          qty={qty}
          isHidden={isHidden}
          isManual={isManual}
          onDelete={handleDelete}
        />
      ) : (
        <ActivePin
          product={product}
          qty={qty}
          isManual={isManual}
          isNew={isNew}
          justAdded={justAdded}
          hovered={hovered}
          dragging={dragging}
          effectivePrice={effectivePrice}
          hasPromo={hasPromo}
          isMobile={isMobile}
          onSelect={() => setSelectedProduct(product)}
          onDec={() => decrementCart(product.code)}
          onInc={() => incrementCart(product.code)}
          onOpenCart={() => setCartOpen(true)}
        />
      )}
      </motion.div>
    </div>
  )
})

// =========================================================================
// ManagePin — the pin as it appears in manage/edit mode (with red × button)
// =========================================================================
function ManagePin({
  product, qty, isHidden, isManual, onDelete,
}: {
  product: Product
  qty: number
  isHidden: boolean
  isManual: boolean
  onDelete: (e: React.SyntheticEvent) => void
}) {
  return (
    <div className="relative">
      <div
        className={`w-10 h-10 sm:w-12 sm:h-12 rounded-full flex items-center justify-center ring-2 ring-white shadow-xl select-none overflow-hidden ${
          isHidden
            ? 'bg-neutral-300 text-neutral-400'
            : qty > 0
              ? 'bg-amber-50 border border-amber-300 text-amber-900'
              : 'bg-amber-400 text-black'
        }`}
        title={isHidden ? `${product.code} (oculto)` : product.code}
      >
        {qty > 0 ? (
          <span className="text-base font-bold">{qty}</span>
        ) : isHidden ? (
          <Eye className="w-5 h-5" />
        ) : (
          <Image
            src="/pin-icon.png"
            alt=""
            width={40}
            height={40}
            className="w-full h-full object-cover"
            draggable={false}
          />
        )}
      </div>
      {/* Red × removal button — top-right corner */}
      <button
        onPointerDown={(e) => e.stopPropagation()}
        onPointerUp={(e) => e.stopPropagation()}
        onClick={onDelete}
        className={`absolute -top-1.5 -right-1.5 w-5 h-5 rounded-full shadow-lg flex items-center justify-center transition-colors pointer-events-auto ${
          isHidden ? 'bg-green-500 hover:bg-green-600 text-white' : 'bg-red-500 hover:bg-red-600 text-white'
        }`}
        aria-label={isHidden ? `Mostrar ${product.name}` : `Remover ${product.name}`}
        title={isManual ? `Remover pin manual ${product.code}` : isHidden ? `Mostrar ${product.code}` : `Ocultar ${product.code}`}
      >
        {isHidden ? <Plus className="w-3 h-3" /> : <X className="w-3 h-3" />}
      </button>
      {/* Code label below pin */}
      <div className="absolute top-full left-1/2 -translate-x-1/2 mt-1 text-[9px] font-mono font-bold text-white bg-black/70 px-1 py-0.5 rounded whitespace-nowrap pointer-events-none">
        {product.code}
      </div>
    </div>
  )
}

// =========================================================================
// ActivePin — the pin in normal (non-manage) mode.
// Renders hover flyout + one of: justAdded check, qty stepper, or buy circle.
// =========================================================================
function ActivePin({
  product, qty, isManual, isNew, justAdded, hovered, dragging,
  effectivePrice, hasPromo, isMobile,
  onSelect, onDec, onInc, onOpenCart,
}: {
  product: Product
  qty: number
  isManual: boolean
  isNew: boolean
  justAdded: boolean
  hovered: boolean
  dragging: boolean
  effectivePrice: number
  hasPromo: boolean
  isMobile: boolean
  onSelect: () => void
  onDec: () => void
  onInc: () => void
  onOpenCart: () => void
}) {
  return (
    <>
      {/* Hover flyout (product details + actions) */}
      {hovered && !dragging && (
        <div
          className="absolute bottom-full left-1/2 -translate-x-1/2 mb-3 z-50 w-52 bg-white rounded-xl shadow-2xl border border-neutral-200 p-3 pointer-events-auto"
          style={{ animation: 'fadeIn 0.12s ease-out' }}
          onPointerDown={(e) => e.stopPropagation()}
        >
          <button onClick={onSelect} className="block w-full text-left">
            <div className="flex items-center gap-1 mb-0.5">
              <span className="text-[10px] font-mono text-neutral-400">#{product.code}</span>
              {isManual && (
                <span className="text-[9px] bg-purple-100 text-purple-700 px-1.5 py-0.5 rounded-full font-semibold">
                  MANUAL
                </span>
              )}
            </div>
            <div className="text-xs font-semibold text-neutral-900 leading-tight line-clamp-2 hover:text-amber-700 transition-colors">
              {product.name}
            </div>
            {product.volume && (
              <div className="text-[10px] text-neutral-500 mt-0.5">{product.volume}</div>
            )}
          </button>
          <div className="flex items-baseline gap-1.5 mt-2 pt-2 border-t border-neutral-100">
            {hasPromo && (
              <span className="text-[10px] text-neutral-400 line-through">{formatPrice(product.price)}</span>
            )}
            <span className={`text-base font-bold ${hasPromo ? 'text-red-600' : 'text-neutral-900'}`}>
              {formatPrice(effectivePrice)}
            </span>
          </div>
          {/* Arrow pointing down (toward the pin) */}
          <div className="absolute left-1/2 -translate-x-1/2 top-full -mt-px w-0 h-0 border-x-[7px] border-x-transparent border-t-[7px] border-t-white" />
        </div>
      )}

      {/* Pin body — three visual states, crossfaded via AnimatePresence.
          Each state gets a `key` so framer-motion animates the swap
          (spring pop-out / pop-in) instead of an instant cut. */}
      <AnimatePresence mode="wait" initial={false}>
      {justAdded && qty === 0 ? (
        <motion.div
          key="justAdded"
          initial={{ scale: 0, rotate: -90, opacity: 0 }}
          animate={{ scale: 1, rotate: 0, opacity: 1 }}
          exit={{ scale: 0, opacity: 0 }}
          transition={{ type: 'spring', damping: 14, stiffness: 320 }}
          className="w-10 h-10 sm:w-12 sm:h-12 rounded-full bg-green-500 text-white shadow-xl flex items-center justify-center ring-2 ring-white select-none"
          aria-label={`${product.name} adicionado ao carrinho`}
        >
          <Check className="w-6 h-6" strokeWidth={3} />
        </motion.div>
      ) : qty === 0 ? (
        <motion.div
          key="buy"
          initial={{ scale: 0.7, opacity: 0 }}
          animate={{ scale: 1, opacity: 1 }}
          exit={{ scale: 0.7, opacity: 0 }}
          transition={{ type: 'spring', damping: 16, stiffness: 300 }}
          className="relative"
        >
          {/* Pulsing ring + "NOVO" badge for freshly-added manual pins */}
          {isNew && (
            <>
              <span
                className="absolute inset-0 rounded-full ring-4 ring-green-400 pointer-events-none pin-pulse-ring"
                style={{ animation: 'pinPulse 1s ease-out infinite' }}
              />
              <span
                className="absolute -top-2 left-1/2 -translate-x-1/2 -translate-y-full bg-green-500 text-white text-[9px] font-bold px-1.5 py-0.5 rounded-full whitespace-nowrap shadow-lg pointer-events-none flex items-center gap-0.5"
                style={{ animation: 'fadeIn 0.2s ease-out' }}
              >
                NOVO
              </span>
            </>
          )}
          <div
            className={`pin-breathe w-12 h-12 sm:w-12 sm:h-12 rounded-full shadow-xl hover:scale-110 active:scale-95 flex items-center justify-center ring-2 ring-white transition-transform select-none overflow-hidden ${
              isManual
                ? 'bg-gradient-to-br from-purple-400 to-purple-600 text-white'
                : 'bg-amber-400 text-black hover:bg-amber-500'
            }`}
            style={{ animation: 'pinBreathe 2.4s ease-in-out infinite' }}
            role="button"
            tabIndex={0}
            aria-label={`Adicionar ${product.name} ao carrinho. Arraste para reposicionar.`}
            title={`${product.code} — ${formatPrice(effectivePrice)}${isManual ? ' (manual)' : ''}\nClique: adicionar • Arraste: mover`}
          >
            <Image
              src="/pin-icon.png"
              alt=""
              width={48}
              height={48}
              className="w-full h-full object-cover"
              draggable={false}
            />
          </div>
        </motion.div>
      ) : (
        // In cart — mini stepper
        <motion.div
          key="stepper"
          initial={{ scale: 0.7, opacity: 0 }}
          animate={{ scale: 1, opacity: 1 }}
          exit={{ scale: 0.7, opacity: 0 }}
          transition={{ type: 'spring', damping: 16, stiffness: 300 }}
          className="relative"
        >
          <div
            className="inline-flex items-center rounded-full bg-amber-50 border border-amber-300 overflow-hidden ring-2 ring-white shadow-xl select-none"
            role="button"
            tabIndex={0}
            title={`${product.code} — qty ${qty}\nClique no nº: ver carrinho • Arraste: mover`}
          >
            <button
              onPointerDown={(e) => e.stopPropagation()}
              onClick={(e) => { e.stopPropagation(); onDec() }}
              className="w-10 h-12 sm:w-9 sm:h-12 flex items-center justify-center text-amber-700 hover:bg-amber-100 transition-colors active:scale-90"
              aria-label="Diminuir"
            >
              <Minus className="w-5 h-5" />
            </button>
            <button
              onPointerDown={(e) => e.stopPropagation()}
              onClick={(e) => { e.stopPropagation(); if (!isMobile) onOpenCart() }}
              className="min-w-[32px] sm:min-w-[28px] h-12 sm:h-12 px-1 text-base font-bold text-amber-900 hover:underline flex items-center justify-center"
              title={isMobile ? `${qty} no carrinho` : 'Ver carrinho'}
            >
              <AnimatePresence mode="popLayout" initial={false}>
                <motion.span
                  key={qty}
                  initial={{ y: -10, opacity: 0, scale: 0.7 }}
                  animate={{ y: 0, opacity: 1, scale: 1 }}
                  exit={{ y: 10, opacity: 0, scale: 0.7 }}
                  transition={{ type: 'spring', damping: 16, stiffness: 400 }}
                  className="inline-block"
                >
                  {qty}
                </motion.span>
              </AnimatePresence>
            </button>
            <button
              onPointerDown={(e) => e.stopPropagation()}
              onClick={(e) => { e.stopPropagation(); onInc() }}
              className="w-10 h-12 sm:w-9 sm:h-12 flex items-center justify-center text-amber-700 hover:bg-amber-100 transition-colors active:scale-90"
              aria-label="Aumentar"
            >
              <Plus className="w-5 h-5" />
            </button>
          </div>
        </motion.div>
      )}
      </AnimatePresence>
    </>
  )
}

// =========================================================================
// AddPinButton — floating "+" button that opens a small popover to add a
// manual pin by product code. The new pin appears on the current page.
// =========================================================================
function AddPinButton({ page }: { page: number }) {
  const [open, setOpen] = useState(false)
  const [code, setCode] = useState('')
  const [status, setStatus] = useState<'idle' | 'searching' | 'ok' | 'notfound'>('idle')
  const [foundName, setFoundName] = useState('')
  const addManualPin = useCatalogStore(s => s.addManualPin)

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault()
    const trimmed = code.trim()
    if (!trimmed) return
    setStatus('searching')
    try {
      const res = await fetch(`/api/products?codes=${encodeURIComponent(trimmed)}&limit=1`)
      const json = await res.json()
      const prod = json.data?.[0]
      if (!prod) {
        setStatus('notfound')
        return
      }
      addManualPin(prod.code, page)
      setFoundName(prod.name)
      setStatus('ok')
      setCode('')
      setTimeout(() => {
        setStatus('idle')
        setFoundName('')
        setOpen(false)
      }, 1500)
    } catch {
      setStatus('notfound')
    }
  }

  return (
    <div className="absolute bottom-2 left-2 z-30 pointer-events-auto">
      {open ? (
        <div
          className="bg-white rounded-xl shadow-2xl border border-neutral-200 p-3 w-56"
          style={{ animation: 'fadeIn 0.15s ease-out' }}
        >
          <div className="flex items-center justify-between mb-2">
            <span className="text-[11px] font-bold text-neutral-700 flex items-center gap-1">
              <Plus className="w-3 h-3 text-amber-500" /> Adicionar botão de compra
            </span>
            <button
              onClick={() => { setOpen(false); setStatus('idle'); setCode('') }}
              className="text-neutral-400 hover:text-neutral-600"
              aria-label="Fechar"
            >
              <X className="w-3.5 h-3.5" />
            </button>
          </div>
          <form onSubmit={handleSubmit} className="space-y-2">
            <input
              type="text"
              value={code}
              onChange={(e) => { setCode(e.target.value); setStatus('idle') }}
              placeholder="Código do produto (ex: 3504)"
              inputMode="numeric"
              autoFocus
              className="w-full px-2.5 py-1.5 text-xs border border-neutral-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-amber-400 font-mono"
            />
            {status === 'ok' && (
              <div className="text-[10px] text-green-600 font-medium flex items-center gap-1">
                <Check className="w-3 h-3" /> {foundName.slice(0, 40)}
              </div>
            )}
            {status === 'notfound' && (
              <div className="text-[10px] text-red-500 font-medium">
                Produto não encontrado. Verifique o código.
              </div>
            )}
            <button
              type="submit"
              disabled={status === 'searching' || !code.trim()}
              className="w-full py-1.5 rounded-lg bg-amber-400 text-black text-xs font-bold hover:bg-amber-500 disabled:opacity-50 transition-colors flex items-center justify-center gap-1"
            >
              {status === 'searching' ? 'Buscando...' : (
                <><MapPin className="w-3 h-3" /> Posicionar na página {page}</>
              )}
            </button>
          </form>
          <p className="text-[9px] text-neutral-400 mt-1.5 leading-tight">
            O botão aparecerá nesta página. Depois arraste para posicionar onde quiser.
          </p>
        </div>
      ) : (
        <button
          onClick={() => setOpen(true)}
          className="w-9 h-9 sm:w-10 sm:h-10 rounded-full bg-neutral-900 text-white shadow-xl hover:bg-neutral-800 hover:scale-105 active:scale-95 flex items-center justify-center transition-all"
          aria-label="Adicionar botão de compra manualmente"
          title="Adicionar botão de compra por código de produto"
        >
          <Plus className="w-5 h-5" />
        </button>
      )}
    </div>
  )
}
