"use client"

import { useEffect, useState, type ReactNode } from "react"
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Textarea } from "@/components/ui/textarea"
import { Loader2, ShieldCheck } from "lucide-react"
import { toast } from "@/hooks/use-toast"
import { useAuthStore } from "@/lib/auth-store"
import { hasPermission, type Permission } from "@/lib/permissions"
import { cn } from "@/lib/utils"

type Props = {
  open: boolean
  onOpenChange: (open: boolean) => void
  title: string
  description?: string
  motivos: Array<{ codigo: string; etiqueta: string }>
  /** Si quien está entrado no lo tiene, el diálogo pide el PIN de un gerente. */
  permisoRequerido?: Permission
  /** Solo pide el PIN cuando esto es true (ej.: cancelar con pedidos en cocina). */
  permisoAplica?: boolean
  /** Contenido extra entre el motivo y el PIN (ej.: el bloque de pagos previos). */
  children?: ReactNode
  /** Deshabilita confirmar mientras el bloque extra no esté resuelto. */
  bloqueado?: boolean
  textoConfirmar: string
  destructivo?: boolean
  /** Hace el trabajo; recibe el vale de gerencia si hizo falta. Lanza para mostrar el error. */
  onConfirmar: (p: { motivo: string; nota: string; autorizacion?: string }) => Promise<void>
}

/**
 * Diálogo genérico «motivo + nota (+ PIN de gerencia)» (v1.82.0). Lo usan
 * cancelar una cuenta de mesa y cancelar un pedido web; la lista de motivos
 * y quién puede la decide quien lo abre. «Otro» exige la nota. Cerrable
 * siempre: un diálogo que no cierra deja la página muerta.
 */
export function MotivoDialog({
  open,
  onOpenChange,
  title,
  description,
  motivos,
  permisoRequerido,
  permisoAplica = true,
  children,
  bloqueado = false,
  textoConfirmar,
  destructivo = true,
  onConfirmar,
}: Props) {
  const user = useAuthStore((s) => s.user)
  const necesitaPin = Boolean(permisoRequerido && permisoAplica && !(user?.role && hasPermission(user.role, permisoRequerido)))
  const [motivo, setMotivo] = useState("")
  const [nota, setNota] = useState("")
  const [pin, setPin] = useState("")
  const [enviando, setEnviando] = useState(false)

  useEffect(() => {
    if (!open) return
    setMotivo("")
    setNota("")
    setPin("")
    setEnviando(false)
  }, [open])

  const listo = motivo !== "" && (motivo !== "OTRO" || nota.trim() !== "") && (!necesitaPin || pin.length === 6) && !bloqueado

  const confirmar = async () => {
    if (!listo) return
    setEnviando(true)
    try {
      let autorizacion: string | undefined
      if (necesitaPin && permisoRequerido) {
        const r = await fetch("/api/auth/autorizar", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ pin, permiso: permisoRequerido }),
        })
        const d = await r.json().catch(() => ({}))
        if (!r.ok) {
          setPin("")
          toast({ title: "No se pudo autorizar", description: d.error ?? "Revisa el PIN", variant: "destructive" })
          return
        }
        autorizacion = d.token
      }
      await onConfirmar({ motivo, nota: nota.trim(), autorizacion })
      onOpenChange(false)
    } catch (e) {
      toast({ title: "No se pudo completar", description: e instanceof Error ? e.message : "Intenta de nuevo", variant: "destructive" })
    } finally {
      setEnviando(false)
    }
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="w-[calc(100vw-1rem)] max-w-md max-h-[94vh] overflow-y-auto p-4 sm:p-6">
        <DialogHeader>
          <DialogTitle>{title}</DialogTitle>
          {description && <DialogDescription>{description}</DialogDescription>}
        </DialogHeader>

        <div className="space-y-4">
          <div>
            <Label>Motivo</Label>
            <div className="grid grid-cols-2 gap-1.5 mt-1">
              {motivos.map((m) => (
                <Button
                  key={m.codigo}
                  type="button"
                  size="sm"
                  variant={motivo === m.codigo ? "default" : "outline"}
                  className="h-auto min-h-9 py-1.5 whitespace-normal text-left justify-start text-xs"
                  onClick={() => setMotivo(m.codigo)}
                >
                  {m.etiqueta}
                </Button>
              ))}
            </div>
          </div>

          <div>
            <Label htmlFor="motivo-nota">Nota {motivo === "OTRO" ? "(obligatoria)" : "(opcional)"}</Label>
            <Textarea id="motivo-nota" rows={2} maxLength={150} value={nota} onChange={(e) => setNota(e.target.value)} placeholder="Qué pasó, en una línea" />
          </div>

          {children}

          {necesitaPin && (
            <div className="rounded-md border border-primary/30 p-3 space-y-1.5">
              <Label htmlFor="motivo-pin" className="flex items-center gap-1.5">
                <ShieldCheck className="h-4 w-4 text-primary" />
                PIN de gerencia
              </Label>
              <Input
                id="motivo-pin"
                type="password"
                inputMode="numeric"
                autoComplete="off"
                maxLength={6}
                placeholder="••••••"
                value={pin}
                onChange={(e) => setPin(e.target.value.replace(/\D/g, "").slice(0, 6))}
                className="text-center text-2xl tracking-[0.4em] font-mono h-12"
              />
              <p className="text-xs text-muted-foreground">Esta acción la autoriza un gerente. Su nombre queda junto al tuyo en la bitácora.</p>
            </div>
          )}
        </div>

        <DialogFooter className="gap-2 sm:gap-0">
          <Button type="button" variant="outline" onClick={() => onOpenChange(false)} disabled={enviando}>
            Volver
          </Button>
          <Button
            type="button"
            onClick={confirmar}
            disabled={!listo || enviando}
            className={cn(destructivo && "bg-destructive hover:bg-destructive/90 text-white")}
          >
            {enviando ? <Loader2 className="h-4 w-4 animate-spin mr-2" /> : null}
            {textoConfirmar}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}
