import React, { useMemo, useState } from "react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Badge } from "@/components/ui/badge";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import {
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Checkbox } from "@/components/ui/checkbox";
import {
  Archive,
  ClipboardList,
  Factory,
  History,
  ListOrdered,
  Loader2,
  Send,
  Trash2,
} from "lucide-react";
import { toast } from "sonner";
import { ProductionAPI } from "@/apis/ProductionAPI";
import { useProduction } from "@/hooks/useProduction";
import { createPanelPageUrl } from "@/utils";
import Link from "next/link";

const getTodayLocalInputDate = () => {
  const now = new Date();
  const tzOffsetMs = now.getTimezoneOffset() * 60 * 1000;
  return new Date(now.getTime() - tzOffsetMs).toISOString().slice(0, 10);
};

const statusLabel = {
  open: "Abierta",
  in_review: "En revisión",
  closed: "Cerrada",
  cancelled: "Cancelada",
  pending: "Pendiente",
  partial: "Parcial",
  fulfilled: "Completado",
  backlog: "Colgado",
};

export default function ProductionRequestsPage() {
  const queryClient = useQueryClient();
  const { companyId, formulas, products, isLoading: productionLoading } = useProduction();

  const [addProductId, setAddProductId] = useState("");
  const [addFormulaId, setAddFormulaId] = useState("");
  const [addQty, setAddQty] = useState("1");
  const [captureOpen, setCaptureOpen] = useState(false);
  const [captureRequestId, setCaptureRequestId] = useState("");
  const [captureDate, setCaptureDate] = useState(getTodayLocalInputDate);
  const [captureLines, setCaptureLines] = useState({});
  const [bitacoraOpen, setBitacoraOpen] = useState(false);
  const [bitacoraRequestId, setBitacoraRequestId] = useState("");
  const [archiveView, setArchiveView] = useState("active");
  const [archiveSelected, setArchiveSelected] = useState({});

  const productIdsWithFormula = useMemo(() => {
    return new Set(
      (formulas || []).map((f) => String(f.idproduct ?? f.product_id ?? "").trim()).filter(Boolean),
    );
  }, [formulas]);

  const eligibleProducts = useMemo(() => {
    return (products || []).filter((p) => productIdsWithFormula.has(String(p.id)));
  }, [products, productIdsWithFormula]);

  const formulasByProduct = useMemo(() => {
    const map = {};
    (formulas || []).forEach((f) => {
      const pid = String(f.idproduct ?? f.product_id ?? "");
      if (!pid) return;
      if (!map[pid]) map[pid] = [];
      map[pid].push(f);
    });
    return map;
  }, [formulas]);

  const { data: openRequest, isLoading: loadingOpen } = useQuery({
    queryKey: ["production-request-open", companyId],
    queryFn: () => ProductionAPI.getOpenProductionRequest(companyId),
    enabled: Boolean(companyId),
  });

  const { data: reviewRequests = [], isLoading: loadingReview } = useQuery({
    queryKey: ["production-requests-review", companyId],
    queryFn: () => ProductionAPI.listProductionRequests(companyId, "in_review", { archived: "0" }),
    enabled: Boolean(companyId),
  });

  const { data: archiveList = [], isLoading: loadingArchiveList } = useQuery({
    queryKey: ["production-requests-archive", companyId, archiveView],
    queryFn: () =>
      ProductionAPI.listProductionRequests(
        companyId,
        undefined,
        { archived: archiveView === "archived" ? "1" : "0" },
      ),
    enabled: Boolean(companyId),
  });

  const { data: backlogItems = [], isLoading: loadingBacklog } = useQuery({
    queryKey: ["production-requests-backlog", companyId],
    queryFn: () => ProductionAPI.getBacklogProductionRequestItems(companyId),
    enabled: Boolean(companyId),
  });

  const { data: bitacoraRows = [], isFetching: loadingBitacora } = useQuery({
    queryKey: ["production-request-bitacora", companyId, bitacoraRequestId],
    queryFn: () => ProductionAPI.getProductionRequestBitacora(companyId, bitacoraRequestId),
    enabled: Boolean(companyId && bitacoraRequestId && bitacoraOpen),
  });

  const openBitacora = (requestId) => {
    setBitacoraRequestId(String(requestId));
    setBitacoraOpen(true);
  };

  const invalidate = async () => {
    await queryClient.invalidateQueries({ queryKey: ["production-request-open", companyId] });
    await queryClient.invalidateQueries({ queryKey: ["production-requests-review", companyId] });
    await queryClient.invalidateQueries({ queryKey: ["production-requests-backlog", companyId] });
    await queryClient.invalidateQueries({ queryKey: ["production-requests-archive"] });
    await queryClient.invalidateQueries({ queryKey: ["production-orders", companyId] });
    await queryClient.invalidateQueries({ queryKey: ["production-request-bitacora"] });
  };

  const addItemMutation = useMutation({
    mutationFn: async () => {
      if (!openRequest?.id) throw new Error("Sin solicitud abierta");
      const qty = Number(addQty);
      if (!addProductId || !Number.isFinite(qty) || qty <= 0) throw new Error("Producto y cantidad válidos");
      return ProductionAPI.addProductionRequestItem(String(openRequest.id), companyId, {
        idproduct: addProductId,
        quantity: qty,
        idproduction_formula: addFormulaId || undefined,
      });
    },
    onSuccess: async () => {
      toast.success("Ítem agregado al carrito");
      setAddQty("1");
      setAddFormulaId("");
      await invalidate();
    },
    onError: (e) => toast.error(e?.message || "No se pudo agregar"),
  });

  const submitReviewMutation = useMutation({
    mutationFn: async () => {
      if (!openRequest?.id) throw new Error("Sin solicitud");
      return ProductionAPI.submitProductionRequestReview(String(openRequest.id));
    },
    onSuccess: async () => {
      toast.success("Enviado a producción");
      await invalidate();
    },
    onError: () => toast.error("No se pudo enviar"),
  });

  const deleteItemMutation = useMutation({
    mutationFn: (itemId) => ProductionAPI.deleteProductionRequestItem(String(itemId)),
    onSuccess: async () => {
      toast.success("Ítem eliminado");
      await invalidate();
    },
    onError: () => toast.error("No se pudo eliminar"),
  });

  const backlogMutation = useMutation({
    mutationFn: (itemId) => ProductionAPI.moveProductionRequestItemToBacklog(String(itemId)),
    onSuccess: async () => {
      toast.success("Marcado como colgado");
      await invalidate();
    },
    onError: () => toast.error("No se pudo actualizar"),
  });

  const captureMutation = useMutation({
    mutationFn: async () => {
      const req = reviewRequests.find((r) => String(r.id) === String(captureRequestId));
      if (!req?.items?.length) throw new Error("Solicitud sin ítems");
      const lines = [];
      req.items.forEach((it) => {
        const rem = Number(it.quantity_remaining ?? 0);
        if (rem <= 0 || it.status === "backlog" || it.status === "cancelled") return;
        const raw = captureLines[String(it.id)] ?? String(rem);
        const planned = Math.min(Number(raw) || 0, rem);
        if (planned <= 0) return;
        const fPick = captureLines[`${it.id}_formula`];
        const fallback = formulasByProduct[String(it.idproduct)]?.[0]?.id;
        const formulaId =
          (fPick && fPick !== "__pick__" ? fPick : null) || it.idproduction_formula || fallback;
        if (!formulaId) {
          throw new Error(`Selecciona una fórmula para: ${it.product?.name || "ítem"}`);
        }
        lines.push({
          idproduction_request_item: String(it.id),
          planned_quantity: planned,
          idproduction_formula: String(formulaId),
        });
      });
      if (!lines.length) throw new Error("Indica cantidades a capturar");
      return ProductionAPI.captureProductionRequest(String(req.id), {
        planned_date: captureDate,
        lines,
      });
    },
    onSuccess: async (data) => {
      toast.success(`OP ${data?.production_order?.order_number || ""} creada`);
      setCaptureOpen(false);
      setCaptureLines({});
      await invalidate();
    },
    onError: (e) => toast.error(e?.message || "Error en captura"),
  });

  const reassignMutation = useMutation({
    mutationFn: (requestId) => ProductionAPI.reassignProductionRequestBacklog(String(requestId)),
    onSuccess: async (data) => {
      toast.success(`Nueva solicitud #${data?.new_request?.id || ""}`);
      await invalidate();
    },
    onError: () => toast.error("No se pudo reasignar"),
  });

  const bulkArchiveMutation = useMutation({
    mutationFn: (ids) => ProductionAPI.bulkArchiveProductionRequests(companyId, ids),
    onSuccess: async (data) => {
      toast.success(`Archivadas: ${data?.updated ?? 0}`);
      setArchiveSelected({});
      await invalidate();
    },
    onError: () => toast.error("No se pudo archivar"),
  });

  const openCaptureFor = (req) => {
    setCaptureRequestId(String(req.id));
    const initial = {};
    (req.items || []).forEach((it) => {
      const rem = Number(it.quantity_remaining ?? 0);
      if (rem > 0) {
        initial[String(it.id)] = String(rem);
        const defF =
          it.idproduction_formula ?? formulasByProduct[String(it.idproduct)]?.[0]?.id ?? "";
        initial[`${it.id}_formula`] = defF ? String(defF) : "";
      }
    });
    setCaptureLines(initial);
    setCaptureDate(getTodayLocalInputDate());
    setCaptureOpen(true);
  };

  const isLoading = productionLoading || loadingOpen;

  return (
    <div className="p-4 md:p-6 space-y-6 max-w-6xl mx-auto">
      <div className="flex flex-col gap-2 md:flex-row md:items-center md:justify-between">
        <div>
          <h1 className="text-2xl font-semibold tracking-tight flex items-center gap-2">
            <Factory className="h-7 w-7 text-violet-600" />
            Solicitudes de producción
          </h1>
          <p className="text-muted-foreground text-sm mt-1">
            Carrito tipo solicitud, revisión, captura a OP y colgados. Las unidades mostradas son solo referencia.
          </p>
        </div>
        <div className="flex flex-wrap gap-2">
          {openRequest?.id ? (
            <Button
              type="button"
              variant="outline"
              size="sm"
              onClick={() => openBitacora(openRequest.id)}
            >
              <History className="h-4 w-4 mr-1" />
              Bitácora (#{openRequest.id})
            </Button>
          ) : null}
          <Button variant="outline" size="sm" asChild>
            <Link href={createPanelPageUrl("production/orders")}>Ir a órdenes</Link>
          </Button>
        </div>
      </div>

      <Tabs defaultValue="cart" className="space-y-4">
        <TabsList className="grid w-full grid-cols-2 sm:grid-cols-4 max-w-3xl">
          <TabsTrigger value="cart">Solicitud abierta</TabsTrigger>
          <TabsTrigger value="review">Revisión</TabsTrigger>
          <TabsTrigger value="backlog">Colgados</TabsTrigger>
          <TabsTrigger value="archive">Archivo</TabsTrigger>
        </TabsList>

        <TabsContent value="cart">
          <Card className="glass-card border-white/20">
            <CardHeader>
              <CardTitle className="text-lg flex items-center gap-2">
                <ListOrdered className="h-5 w-5" />
                Tu solicitud (merge por producto + fórmula)
              </CardTitle>
            </CardHeader>
            <CardContent className="space-y-6">
              {isLoading ? (
                <div className="flex items-center gap-2 text-muted-foreground">
                  <Loader2 className="h-4 w-4 animate-spin" /> Cargando…
                </div>
              ) : (
                <>
                  <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4 items-end">
                    <div className="space-y-2">
                      <Label>Producto</Label>
                      <Select value={addProductId} onValueChange={(v) => { setAddProductId(v); setAddFormulaId(""); }}>
                        <SelectTrigger>
                          <SelectValue placeholder="Seleccionar" />
                        </SelectTrigger>
                        <SelectContent>
                          {eligibleProducts.map((p) => (
                            <SelectItem key={String(p.id)} value={String(p.id)}>
                              {p.name} {p.sku ? `(${p.sku})` : ""}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    </div>
                    <div className="space-y-2">
                      <Label>Fórmula (opcional)</Label>
                      <Select
                        value={addFormulaId || "__none__"}
                        onValueChange={(v) => setAddFormulaId(v === "__none__" ? "" : v)}
                        disabled={!addProductId}
                      >
                        <SelectTrigger>
                          <SelectValue placeholder="Predeterminada del producto" />
                        </SelectTrigger>
                        <SelectContent>
                          <SelectItem value="__none__">—</SelectItem>
                          {(formulasByProduct[addProductId] || []).map((f) => (
                            <SelectItem key={String(f.id)} value={String(f.id)}>
                              {f.code} — {f.name}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    </div>
                    <div className="space-y-2">
                      <Label>Cantidad</Label>
                      <Input
                        type="number"
                        min="0.0001"
                        step="any"
                        value={addQty}
                        onChange={(e) => setAddQty(e.target.value)}
                      />
                    </div>
                    <Button
                      type="button"
                      onClick={() => addItemMutation.mutate()}
                      disabled={addItemMutation.isPending || !openRequest?.id}
                    >
                      {addItemMutation.isPending ? <Loader2 className="h-4 w-4 animate-spin" /> : "Agregar"}
                    </Button>
                  </div>

                  <div className="rounded-lg border border-white/20 overflow-hidden">
                    <table className="w-full text-sm">
                      <thead className="bg-muted/50">
                        <tr className="text-left">
                          <th className="p-3">Producto</th>
                          <th className="p-3">Cantidad</th>
                          <th className="p-3">Estado</th>
                          <th className="p-3 w-24" />
                        </tr>
                      </thead>
                      <tbody>
                        {(openRequest?.items || []).length === 0 ? (
                          <tr>
                            <td colSpan={4} className="p-6 text-center text-muted-foreground">
                              Aún no hay ítems. Agrega productos con fórmula definida.
                            </td>
                          </tr>
                        ) : (
                          openRequest.items.map((it) => (
                            <tr key={String(it.id)} className="border-t border-white/10">
                              <td className="p-3">
                                <div className="font-medium">{it.product?.name || "—"}</div>
                                <div className="flex flex-wrap gap-1 mt-1">
                                  {it.product?.unit_suggestion ? (
                                    <Badge variant="secondary" className="text-xs font-normal">
                                      Ref. unidad: {it.product.unit_suggestion}
                                    </Badge>
                                  ) : null}
                                  {it.formula?.name ? (
                                    <Badge variant="outline" className="text-xs">
                                      {it.formula.code}
                                    </Badge>
                                  ) : null}
                                </div>
                              </td>
                              <td className="p-3">
                                {Number(it.quantity || 0).toLocaleString("es-CL")}
                                {Number(it.quantity_captured) > 0 ? (
                                  <span className="text-muted-foreground text-xs block">
                                    Capturado: {Number(it.quantity_captured).toLocaleString("es-CL")}
                                  </span>
                                ) : null}
                              </td>
                              <td className="p-3">
                                <Badge>{statusLabel[it.status] || it.status}</Badge>
                              </td>
                              <td className="p-3">
                                <div className="flex gap-1">
                                  <Button
                                    type="button"
                                    variant="ghost"
                                    size="icon"
                                    className="h-8 w-8"
                                    onClick={() => deleteItemMutation.mutate(it.id)}
                                    disabled={Number(it.quantity_captured) > 0 || deleteItemMutation.isPending}
                                    title="Eliminar"
                                  >
                                    <Trash2 className="h-4 w-4" />
                                  </Button>
                                  <Button
                                    type="button"
                                    variant="ghost"
                                    size="sm"
                                    className="h-8 text-xs"
                                    onClick={() => backlogMutation.mutate(it.id)}
                                    disabled={Number(it.quantity_captured) > 0}
                                  >
                                    Colgar
                                  </Button>
                                </div>
                              </td>
                            </tr>
                          ))
                        )}
                      </tbody>
                    </table>
                  </div>

                  <div className="flex flex-wrap gap-2">
                    <Button
                      onClick={() => submitReviewMutation.mutate()}
                      disabled={
                        submitReviewMutation.isPending ||
                        !openRequest?.id ||
                        openRequest?.status !== "open" ||
                        !(openRequest?.items || []).length
                      }
                    >
                      {submitReviewMutation.isPending ? (
                        <Loader2 className="h-4 w-4 animate-spin mr-2" />
                      ) : (
                        <Send className="h-4 w-4 mr-2" />
                      )}
                      Enviar a revisión producción
                    </Button>
                    <Badge variant="outline" className="h-9 px-3">
                      Estado solicitud: {statusLabel[openRequest?.status] || openRequest?.status || "—"}
                    </Badge>
                  </div>
                </>
              )}
            </CardContent>
          </Card>
        </TabsContent>

        <TabsContent value="review">
          <Card className="glass-card border-white/20">
            <CardHeader>
              <CardTitle className="text-lg flex items-center gap-2">
                <ClipboardList className="h-5 w-5" />
                Bandeja en revisión
              </CardTitle>
            </CardHeader>
            <CardContent className="space-y-4">
              {loadingReview ? (
                <Loader2 className="h-4 w-4 animate-spin text-muted-foreground" />
              ) : reviewRequests.length === 0 ? (
                <p className="text-muted-foreground text-sm">No hay solicitudes en revisión.</p>
              ) : (
                <div className="space-y-3">
                  {reviewRequests.map((req) => (
                    <div
                      key={String(req.id)}
                      className="flex flex-col gap-2 md:flex-row md:items-center md:justify-between border border-white/15 rounded-lg p-4"
                    >
                      <div>
                        <div className="font-medium">Solicitud #{req.id}</div>
                        <div className="text-xs text-muted-foreground">
                          {(req.items || []).length} ítems · {statusLabel[req.status]}
                        </div>
                      </div>
                      <div className="flex flex-wrap gap-2">
                        <Button type="button" variant="outline" size="sm" onClick={() => openBitacora(req.id)}>
                          <History className="h-4 w-4 mr-1" />
                          Bitácora
                        </Button>
                        <Button type="button" size="sm" onClick={() => openCaptureFor(req)}>
                          Capturar → OP
                        </Button>
                      </div>
                    </div>
                  ))}
                </div>
              )}
            </CardContent>
          </Card>
        </TabsContent>

        <TabsContent value="archive">
          <Card className="glass-card border-white/20">
            <CardHeader>
              <CardTitle className="text-lg flex items-center gap-2">
                <Archive className="h-5 w-5" />
                Archivo y limpieza
              </CardTitle>
              <p className="text-sm text-muted-foreground font-normal">
                Las solicitudes archivadas no aparecen en el listado activo ni en &quot;abierta&quot;. Filtra por
                antiguas o ya archivadas y usa archivado masivo (sin jobs automáticos).
              </p>
            </CardHeader>
            <CardContent className="space-y-4">
              <div className="flex flex-wrap gap-3 items-end">
                <div className="space-y-2">
                  <Label>Vista</Label>
                  <Select value={archiveView} onValueChange={(v) => { setArchiveView(v); setArchiveSelected({}); }}>
                    <SelectTrigger className="w-[220px]">
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="active">No archivadas (histórico)</SelectItem>
                      <SelectItem value="archived">Solo archivadas</SelectItem>
                    </SelectContent>
                  </Select>
                </div>
                {archiveView === "active" ? (
                  <Button
                    type="button"
                    variant="secondary"
                    disabled={
                      bulkArchiveMutation.isPending ||
                      !Object.keys(archiveSelected).filter((id) => archiveSelected[id]).length
                    }
                    onClick={() => {
                      const ids = Object.keys(archiveSelected).filter((id) => archiveSelected[id]);
                      if (!ids.length) return;
                      bulkArchiveMutation.mutate(ids);
                    }}
                  >
                    {bulkArchiveMutation.isPending ? (
                      <Loader2 className="h-4 w-4 animate-spin mr-2" />
                    ) : (
                      <Archive className="h-4 w-4 mr-2" />
                    )}
                    Archivar seleccionadas
                  </Button>
                ) : null}
              </div>

              {loadingArchiveList ? (
                <Loader2 className="h-4 w-4 animate-spin text-muted-foreground" />
              ) : archiveList.length === 0 ? (
                <p className="text-muted-foreground text-sm">No hay solicitudes en esta vista.</p>
              ) : (
                <div className="rounded-lg border border-white/20 overflow-x-auto">
                  <table className="w-full text-sm min-w-[520px]">
                    <thead className="bg-muted/50">
                      <tr className="text-left">
                        {archiveView === "active" ? (
                          <th className="p-2 w-10">
                            <Checkbox
                              checked={
                                archiveList.length > 0 &&
                                archiveList.every((r) => archiveSelected[String(r.id)])
                              }
                              onCheckedChange={(checked) => {
                                const next = { ...archiveSelected };
                                archiveList.forEach((r) => {
                                  next[String(r.id)] = Boolean(checked);
                                });
                                setArchiveSelected(next);
                              }}
                              aria-label="Seleccionar todas"
                            />
                          </th>
                        ) : null}
                        <th className="p-2">#</th>
                        <th className="p-2">Estado</th>
                        <th className="p-2">Archivada</th>
                        <th className="p-2">Ítems</th>
                      </tr>
                    </thead>
                    <tbody>
                      {archiveList.map((req) => (
                        <tr key={String(req.id)} className="border-t border-white/10">
                          {archiveView === "active" ? (
                            <td className="p-2">
                              <Checkbox
                                checked={Boolean(archiveSelected[String(req.id)])}
                                onCheckedChange={(checked) =>
                                  setArchiveSelected((prev) => ({
                                    ...prev,
                                    [String(req.id)]: Boolean(checked),
                                  }))
                                }
                                aria-label={`Seleccionar solicitud ${req.id}`}
                              />
                            </td>
                          ) : null}
                          <td className="p-2 font-mono">{req.id}</td>
                          <td className="p-2">
                            <Badge variant="outline">{statusLabel[req.status] || req.status}</Badge>
                          </td>
                          <td className="p-2 text-xs text-muted-foreground">
                            {req.archived_at
                              ? new Date(req.archived_at).toLocaleString("es-CL")
                              : "—"}
                          </td>
                          <td className="p-2">{(req.items || []).length}</td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              )}
            </CardContent>
          </Card>
        </TabsContent>

        <TabsContent value="backlog">
          <Card className="glass-card border-white/20">
            <CardHeader>
              <CardTitle>Ítems colgados</CardTitle>
            </CardHeader>
            <CardContent>
              {loadingBacklog ? (
                <Loader2 className="h-4 w-4 animate-spin text-muted-foreground" />
              ) : backlogItems.length === 0 ? (
                <p className="text-muted-foreground text-sm">Sin colgados.</p>
              ) : (
                <div className="space-y-3">
                  {Object.entries(
                    backlogItems.reduce((acc, it) => {
                      const rid = String(it.idproduction_request ?? it.request?.id ?? "—");
                      if (!acc[rid]) acc[rid] = [];
                      acc[rid].push(it);
                      return acc;
                    }, {}),
                  ).map(([rid, items]) => (
                    <div key={rid} className="border border-white/15 rounded-lg p-4 space-y-2">
                      <div className="flex flex-wrap justify-between gap-2">
                        <span className="font-medium">Solicitud #{rid}</span>
                        <Button
                          type="button"
                          variant="secondary"
                          size="sm"
                          onClick={() => reassignMutation.mutate(rid)}
                          disabled={reassignMutation.isPending || rid === "—"}
                        >
                          Reasignar a nueva solicitud
                        </Button>
                      </div>
                      <ul className="text-sm space-y-1 list-disc list-inside text-muted-foreground">
                        {items.map((it) => (
                          <li key={String(it.id)}>
                            {it.product?.name} — {Number(it.quantity).toLocaleString("es-CL")}
                          </li>
                        ))}
                      </ul>
                    </div>
                  ))}
                </div>
              )}
            </CardContent>
          </Card>
        </TabsContent>
      </Tabs>

      <Dialog
        open={bitacoraOpen}
        onOpenChange={(open) => {
          setBitacoraOpen(open);
          if (!open) setBitacoraRequestId("");
        }}
      >
        <DialogContent className="max-w-2xl max-h-[85vh] flex flex-col">
          <DialogHeader>
            <DialogTitle>Bitácora · solicitud #{bitacoraRequestId}</DialogTitle>
          </DialogHeader>
          <ScrollArea className="flex-1 max-h-[60vh] pr-3">
            {loadingBitacora ? (
              <div className="flex items-center gap-2 text-muted-foreground py-8">
                <Loader2 className="h-4 w-4 animate-spin" /> Cargando…
              </div>
            ) : bitacoraRows.length === 0 ? (
              <p className="text-sm text-muted-foreground py-6">Sin registros aún.</p>
            ) : (
              <table className="w-full text-sm">
                <thead>
                  <tr className="text-left border-b">
                    <th className="p-2">Cuándo</th>
                    <th className="p-2">Evento</th>
                    <th className="p-2">Detalle</th>
                    <th className="p-2">Usuario</th>
                  </tr>
                </thead>
                <tbody>
                  {bitacoraRows.map((row) => (
                    <tr key={String(row.id)} className="border-b border-white/10 align-top">
                      <td className="p-2 whitespace-nowrap text-xs text-muted-foreground">
                        {row.created_at
                          ? new Date(row.created_at).toLocaleString("es-CL")
                          : "—"}
                      </td>
                      <td className="p-2">
                        <Badge variant="outline" className="font-mono text-xs">
                          {row.event_type}
                        </Badge>
                      </td>
                      <td className="p-2 text-xs">
                        <div>{row.message || "—"}</div>
                        {row.meta && Object.keys(row.meta).length > 0 ? (
                          <pre className="mt-1 text-[10px] bg-muted/40 rounded p-1 overflow-x-auto max-w-[280px]">
                            {JSON.stringify(row.meta, null, 0)}
                          </pre>
                        ) : null}
                        {row.reference_type ? (
                          <span className="text-muted-foreground block mt-1">
                            Ref: {row.reference_type}
                            {row.reference_id != null ? ` #${row.reference_id}` : ""}
                          </span>
                        ) : null}
                      </td>
                      <td className="p-2 text-xs">{row.user?.name || row.user?.email || "—"}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            )}
          </ScrollArea>
          <DialogFooter>
            <Button type="button" variant="outline" onClick={() => setBitacoraOpen(false)}>
              Cerrar
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <Dialog open={captureOpen} onOpenChange={setCaptureOpen}>
        <DialogContent className="max-w-lg max-h-[90vh] overflow-y-auto">
          <DialogHeader>
            <DialogTitle>Capturar orden de producción</DialogTitle>
          </DialogHeader>
          <div className="space-y-4 py-2">
            <div className="space-y-2">
              <Label>Fecha planificada</Label>
              <Input type="date" value={captureDate} onChange={(e) => setCaptureDate(e.target.value)} />
            </div>
            <p className="text-xs text-muted-foreground">
              Ajusta cantidades a producir por línea (no mayor al pendiente). El rendimiento de fórmula es referencia;
              no bloquea el guardado.
            </p>
            {(reviewRequests.find((r) => String(r.id) === String(captureRequestId))?.items || []).map((it) => {
              const rem = Number(it.quantity_remaining ?? 0);
              if (rem <= 0) return null;
              return (
                <div key={String(it.id)} className="border border-white/10 rounded-md p-3 space-y-2">
                  <div className="font-medium text-sm">{it.product?.name}</div>
                  <div className="grid grid-cols-2 gap-2">
                    <div>
                      <Label className="text-xs">Cantidad</Label>
                      <Input
                        type="number"
                        min="0"
                        max={rem}
                        step="any"
                        value={captureLines[String(it.id)] ?? String(rem)}
                        onChange={(e) =>
                          setCaptureLines((prev) => ({ ...prev, [String(it.id)]: e.target.value }))
                        }
                      />
                      <span className="text-xs text-muted-foreground">Máx. {rem}</span>
                    </div>
                    <div>
                      <Label className="text-xs">Fórmula</Label>
                      <Select
                        value={
                          captureLines[`${it.id}_formula`] ||
                          String(
                            it.idproduction_formula ||
                              formulasByProduct[String(it.idproduct)]?.[0]?.id ||
                              "__pick__",
                          )
                        }
                        onValueChange={(v) =>
                          setCaptureLines((prev) => ({ ...prev, [`${it.id}_formula`]: v }))
                        }
                      >
                        <SelectTrigger>
                          <SelectValue />
                        </SelectTrigger>
                        <SelectContent>
                          <SelectItem value="__pick__">Seleccionar…</SelectItem>
                          {(formulasByProduct[String(it.idproduct)] || []).map((f) => (
                            <SelectItem key={String(f.id)} value={String(f.id)}>
                              {f.code}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
          <DialogFooter>
            <Button type="button" variant="outline" onClick={() => setCaptureOpen(false)}>
              Cancelar
            </Button>
            <Button type="button" onClick={() => captureMutation.mutate()} disabled={captureMutation.isPending}>
              {captureMutation.isPending ? <Loader2 className="h-4 w-4 animate-spin" /> : "Confirmar captura"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
