'use client'

import { startTransition, useActionState, useEffect, useMemo, useRef, useState } from 'react'
import { saveProduct } from '@/app/actions/panel'
import { ICON_PREFIX, suggestIcon } from '@/lib/icons'
import ProductIcon from '@/components/ProductIcon'
import IconPicker from './IconPicker'

export type EditableProduct = {
  id: string; name: string; description: string | null; price: string; stock: number | null
  categoryId: string | null; routeTag: string; isAlcoholic: boolean; icon: string | null; imageUrl: string | null
}

/** Achica la foto en el navegador (lado mayor 640 px, WebP) para que suba rápido aun con mala señal. */
async function shrink(file: File): Promise<Blob> {
  const bmp = await createImageBitmap(file)
  const scale = Math.min(1, 640 / Math.max(bmp.width, bmp.height))
  const canvas = document.createElement('canvas')
  canvas.width = Math.round(bmp.width * scale); canvas.height = Math.round(bmp.height * scale)
  canvas.getContext('2d')!.drawImage(bmp, 0, 0, canvas.width, canvas.height)
  for (const q of [0.82, 0.7, 0.55]) {
    const blob = await new Promise<Blob | null>(r => canvas.toBlob(r, 'image/webp', q))
    if (blob && blob.size < 240 * 1024) return blob
  }
  throw new Error('La foto es demasiado pesada')
}

export default function ProductSheet({ eventId, product, categories, defaultCategory, minors, onClose }: {
  eventId: string; product: EditableProduct | null; categories: { id: string; name: string }[]
  defaultCategory: string | null; minors: boolean; onClose: () => void
}) {
  const [state, action, pending] = useActionState(saveProduct.bind(null, eventId, product?.id ?? null), undefined)
  const [icon, setIcon] = useState(product?.icon ?? '')
  const [preview, setPreview] = useState<string | null>(product?.imageUrl ?? null)
  const [blob, setBlob] = useState<Blob | null>(null)
  const [removeImage, setRemoveImage] = useState(false)
  const [photoError, setPhotoError] = useState<string | null>(null)
  const [alcoholic, setAlcoholic] = useState(product?.isAlcoholic ?? false)
  const nameRef = useRef<HTMLInputElement>(null)
  const [name, setName] = useState(product?.name ?? '')
  const suggested = useMemo(() => { const s = suggestIcon(name); return s ? ICON_PREFIX + s.key : null }, [name])

  useEffect(() => { nameRef.current?.focus() }, [])
  useEffect(() => { if (state?.ok) onClose() }, [state, onClose])
  useEffect(() => {
    const esc = (e: KeyboardEvent) => e.key === 'Escape' && onClose()
    window.addEventListener('keydown', esc); return () => window.removeEventListener('keydown', esc)
  }, [onClose])

  const pickPhoto = async (f?: File) => {
    if (!f) return
    setPhotoError(null)
    try {
      const b = await shrink(f)
      setBlob(b); setPreview(URL.createObjectURL(b)); setRemoveImage(false)
    } catch { setPhotoError('No pudimos leer esa foto. Probá con otra (JPG o PNG).') }
  }

  const submit = (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault()
    const fd = new FormData(e.currentTarget)
    fd.delete('imageFile')
    if (blob) fd.set('image', blob, 'foto.webp')
    if (removeImage) fd.set('removeImage', 'on')
    fd.set('icon', icon)
    startTransition(() => action(fd))
  }

  return (
    <div className="fixed inset-0 z-50 flex items-end justify-center md:items-stretch md:justify-end" role="dialog" aria-modal="true" aria-label={product ? 'Editar producto' : 'Nuevo producto'}>
      <button className="absolute inset-0 animate-[fade-up_.2s_ease-out] bg-ink-950/40 backdrop-blur-[2px]" onClick={onClose} aria-label="Cerrar" />
      <form onSubmit={submit}
        className="relative flex max-h-[92dvh] w-full animate-fade-up flex-col overflow-hidden rounded-t-[1.5rem] bg-white shadow-2xl md:h-full md:max-h-none md:w-[440px] md:rounded-none">
        <header className="flex items-center justify-between border-b border-gray-100 px-5 py-4">
          <h2 className="text-lg font-bold">{product ? 'Editar producto' : 'Nuevo producto'}</h2>
          <button type="button" onClick={onClose} className="btn-ghost h-9 w-9 p-0" aria-label="Cerrar">✕</button>
        </header>

        <div className="flex-1 space-y-4 overflow-y-auto px-5 py-5">
          {/* Foto o ícono */}
          <div className="flex items-center gap-4">
            <label className="group relative flex h-24 w-24 shrink-0 cursor-pointer items-center justify-center overflow-hidden rounded-card bg-gray-100 text-5xl ring-brand-500/40 transition hover:ring-4">
              {preview && !removeImage
                // eslint-disable-next-line @next/next/no-img-element
                ? <img src={preview} alt="" className="h-full w-full object-cover" />
                : (icon || suggested) ? <ProductIcon icon={icon || suggested} size="78%" /> : <span>📷</span>}
              <span className="absolute inset-x-0 bottom-0 bg-ink-950/60 py-1 text-center text-[10px] font-medium text-white opacity-0 transition group-hover:opacity-100">Cambiar foto</span>
              <input name="imageFile" type="file" accept="image/*" capture="environment" className="sr-only" onChange={e => pickPhoto(e.target.files?.[0])} />
            </label>
            <div className="min-w-0 text-sm text-gray-500">
              <p className="font-medium text-gray-900">Foto del producto</p>
              <p>Tocá el cuadro para sacar o elegir una foto. Si no hay foto, se muestra el ícono.</p>
              {preview && !removeImage && <button type="button" onClick={() => { setRemoveImage(true); setBlob(null) }} className="mt-1 text-xs text-red-600">Quitar foto</button>}
              {photoError && <p className="mt-1 text-xs text-red-600">{photoError}</p>}
            </div>
          </div>

          <div>
            <label className="label" htmlFor="p-name">Nombre</label>
            <input ref={nameRef} id="p-name" name="name" required maxLength={80} value={name} onChange={e => setName(e.target.value)} className="input" placeholder="Fernet con coca" />
          </div>
          <div>
            <label className="label" htmlFor="p-desc">Descripción <span className="font-normal text-gray-400">(opcional)</span></label>
            <input id="p-desc" name="description" maxLength={200} defaultValue={product?.description ?? ''} className="input" placeholder="Vaso de 500 ml" />
          </div>
          <div>
            <span className="label">Ícono</span>
            <IconPicker value={icon} suggested={suggested} onChange={setIcon} />
          </div>
          <div className="grid grid-cols-2 gap-3">
            <div>
              <label className="label" htmlFor="p-price">Precio</label>
              <div className="relative">
                <span className="pointer-events-none absolute left-4 top-1/2 -translate-y-1/2 text-sm text-gray-400">$</span>
                <input id="p-price" name="price" required inputMode="decimal" defaultValue={product?.price} className="input pl-8 tabular-nums" placeholder="5000" />
              </div>
            </div>
            <div>
              <label className="label" htmlFor="p-stock">Stock</label>
              <input id="p-stock" name="stock" inputMode="numeric" defaultValue={product?.stock ?? ''} className="input tabular-nums" placeholder="Sin límite" />
            </div>
          </div>
          <div className="grid grid-cols-2 gap-3">
            <div>
              <label className="label" htmlFor="p-cat">Categoría</label>
              <select id="p-cat" name="categoryId" className="input" defaultValue={product ? product.categoryId ?? '' : defaultCategory ?? ''}>
                <option value="">Sin categoría</option>
                {categories.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
              </select>
            </div>
            <div>
              <label className="label" htmlFor="p-route">Lo prepara</label>
              <input id="p-route" name="routeTag" list="routes" defaultValue={product?.routeTag ?? 'bar'} className="input" />
              <datalist id="routes"><option value="bar" /><option value="comida" /><option value="merch" /></datalist>
            </div>
          </div>
          <label className={`flex items-start gap-3 rounded-control border p-3 text-sm ${alcoholic ? 'border-amber-300 bg-amber-50' : 'border-gray-200'}`}>
            <input type="checkbox" name="isAlcoholic" checked={alcoholic} onChange={e => setAlcoholic(e.target.checked)} className="mt-0.5 h-4 w-4 accent-brand-500" />
            <span><b className="font-medium">Tiene alcohol (+18)</b>
              <span className="block text-gray-500">{minors ? 'Este evento es con menores: no se va a mostrar ni vender.' : 'El público confirma que es mayor de edad antes de pagar.'}</span></span>
          </label>
          {state?.error && <p className="rounded-control bg-red-50 px-4 py-3 text-sm text-red-700">{state.error}</p>}
        </div>

        <footer className="safe-bottom border-t border-gray-100 p-4">
          <button className="btn-primary w-full py-3.5" disabled={pending}>{pending ? 'Guardando…' : product ? 'Guardar cambios' : 'Agregar al menú'}</button>
        </footer>
      </form>
    </div>
  )
}
