import { Icon } from "@iconify/react";
import {
  Box,
  Button,
  Chip,
  CircularProgress,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  Divider,
  Grid,
  Paper,
  Stack,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  TextField,
  Typography,
  useMediaQuery,
  useTheme,
} from "@mui/material";
import { useState } from "react";
import { useNavigate } from "react-router-dom";
import { useEmpresa } from "../../../context/EmpresaContext";
import { toast } from "sonner";
import { useConfirmDialog } from "../../../hooks/useConfirmDialog";
import {
  useApprovePresupuestoMutation,
  useConvertToOrderMutation,
  useMarkAcceptedMutation,
  useGeneratePresupuestoLinkMutation,
  useNewVersionPresupuestoMutation,
  usePresupuestoQuery,
  useRejectApprovalMutation,
  useSendPresupuestoEmailMutation,
  useSubmitReviewMutation,
} from "../../../tanstack/PresupuestosStack";
import { fmtMoneda } from "../../_standards/enums/monedas";
import { fmtFechaCalendario, fmtFechaHora } from "../../../utils/fecha";
import { getPresupuestoEstado } from "./presupuestoEnums";
import { MarcarAceptadoDialog } from "./MarcarAceptadoDialog";
import { PdfPreviewModal } from "./PdfPreviewModal";

const esItemInformativo = (tipo) => ["SUBTITULO", "TEXTO_LIBRE"].includes(tipo);
// Descuento del ítem: si tiene monto fijo se muestra como importe; si no, como %.
const descItemTexto = (it, moneda) =>
  Number(it.descuento_monto) > 0 ? fmtMoneda(Number(it.descuento_monto), moneda) : `${Number(it.descuento_pct) || 0}%`;
const defaultEmailSubject = (numero) => `Presupuesto ${numero || ""}`.trim();
const splitEmails = (value) =>
  value
    .split(/[,;\s]+/)
    .map((e) => e.trim())
    .filter(Boolean);
const copyText = async (value) => {
  if (navigator?.clipboard?.writeText) {
    await navigator.clipboard.writeText(value);
    return;
  }
  const input = document.createElement("textarea");
  input.value = value;
  input.setAttribute("readonly", "");
  input.style.position = "absolute";
  input.style.left = "-9999px";
  document.body.appendChild(input);
  input.select();
  document.execCommand("copy");
  document.body.removeChild(input);
};

export function DetalleTab({ id, onEditar, onVolver }) {
  const theme = useTheme();
  const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
  const { data: p, isLoading } = usePresupuestoQuery(id);
  const [previewOpen, setPreviewOpen] = useState(false);
  const [emailOpen, setEmailOpen] = useState(false);
  const [emailForm, setEmailForm] = useState({ destinatarios: "", cc: "", asunto: "", mensaje: "" });
  const sendEmail = useSendPresupuestoEmailMutation();
  const generateLink = useGeneratePresupuestoLinkMutation();
  const submitReview = useSubmitReviewMutation();
  const approve = useApprovePresupuestoMutation();
  const rejectApproval = useRejectApprovalMutation();
  const convertToOrder = useConvertToOrderMutation();
  const markAccepted = useMarkAcceptedMutation();
  const [aceptarOpen, setAceptarOpen] = useState(false);
  const newVersion = useNewVersionPresupuestoMutation();
  const { confirm, prompt, dialogs } = useConfirmDialog();
  const navigate = useNavigate();
  const { empresa } = useEmpresa();

  const handleMarcarAceptado = async (payload) => {
    try {
      await markAccepted.mutateAsync({ id, arg: payload });
      setAceptarOpen(false);
    } catch {
      /* el toast de error lo maneja la mutación */
    }
  };

  const handleFacturarDirecto = async () => {
    const ok = await confirm({
      title: "¿Facturar este presupuesto?",
      message:
        "Se abrirá el POS con el presupuesto precargado (cliente, ítems y descuentos) para que emitas la factura, sin crear Orden de Venta. Podés revisar y ajustar antes de confirmar.",
      confirmText: "Sí, facturar",
      confirmColor: "success",
    });
    if (!ok) return;
    navigate(`/pos?presupuesto=${id}`);
  };

  const handleConvertir = async () => {
    const ok = await confirm({
      title: "¿Convertir en Orden de Venta?",
      message:
        "Se creará una Orden de Venta confirmada con las líneas que tengan producto. El presupuesto quedará marcado como Convertido y no podrá modificarse.",
      confirmText: "Convertir",
    });
    if (!ok) return;
    convertToOrder.mutate({ id });
  };

  const handleNuevaVersion = async () => {
    const actual = p?.version || 1;
    const ok = await confirm({
      title: `¿Crear nueva versión de ${p?.numero}?`,
      message: `Se creará la v${actual + 1} como borrador, copiando los datos de la v${actual}. La versión actual se mantiene sin cambios.`,
      confirmText: "Crear versión",
    });
    if (!ok) return;
    try {
      const nuevo = await newVersion.mutateAsync(id);
      if (nuevo?.id) onEditar(nuevo.id);
    } catch {
      /* el toast de error lo maneja la mutación */
    }
  };

  const handleEnviarAprobacion = async () => {
    const ok = await confirm({
      title: "¿Enviar a aprobación?",
      message: "Si el monto supera el umbral configurado, quedará pendiente de aprobación. Si no, se aprobará automáticamente.",
      confirmText: "Enviar a aprobación",
    });
    if (!ok) return;
    submitReview.mutate({ id });
  };

  const handleAprobar = async () => {
    const ok = await confirm({
      title: "¿Aprobar presupuesto?",
      message: "Quedará en estado Aprobado y listo para enviarse al cliente.",
      confirmText: "Aprobar",
      confirmColor: "success",
    });
    if (!ok) return;
    approve.mutate({ id });
  };

  const handleRechazarAprobacion = async () => {
    const motivo = await prompt({
      title: "Rechazar aprobación",
      label: "Motivo del rechazo",
      required: true,
    });
    if (motivo === null) return;
    rejectApproval.mutate({ id, arg: motivo });
  };

  const abrirEnviar = () => {
    setEmailForm({
      destinatarios: p?.clientes?.personas?.email || "",
      cc: "",
      asunto: defaultEmailSubject(p?.numero),
      mensaje: "",
    });
    setEmailOpen(true);
  };

  const handleEnviar = async () => {
    const destinatarios = splitEmails(emailForm.destinatarios);
    const cc = splitEmails(emailForm.cc);
    try {
      await sendEmail.mutateAsync({
        id,
        payload: {
          ...(destinatarios.length ? { destinatarios } : {}),
          ...(cc.length ? { cc } : {}),
          ...(emailForm.asunto.trim() ? { asunto: emailForm.asunto.trim() } : {}),
          ...(emailForm.mensaje.trim() ? { mensaje: emailForm.mensaje.trim() } : {}),
        },
      });
      setEmailOpen(false);
    } catch {
      /* el toast de error lo maneja la mutación */
    }
  };

  const handleCopiarEnlace = async () => {
    try {
      const res = await generateLink.mutateAsync({ id });
      const portalUrl = res?.portalUrl;
      if (!portalUrl) throw new Error("No se recibió el enlace público");
      await copyText(portalUrl);
      toast.success("Enlace copiado. Ya podés compartirlo por WhatsApp.");
    } catch (error) {
      const msg = error?.response?.data?.message;
      toast.error(Array.isArray(msg) ? msg.join(" | ") : msg || "No se pudo copiar el enlace");
    }
  };

  if (isLoading || !p) {
    return <Box sx={{ display: "flex", justifyContent: "center", py: 6 }}><CircularProgress /></Box>;
  }

  const est = getPresupuestoEstado(p.estado);
  const moneda = p.moneda?.codigo || "PYG";
  const editable = p.estado === "DRAFT";
  const enRevision = p.estado === "IN_REVIEW";
  const puedeEnviarEmail = !["DRAFT", "IN_REVIEW", "CONVERTED", "FACTURADO", "CANCELLED", "SUPERSEDED"].includes(p.estado);
  const puedeConvertir = p.estado === "ACCEPTED";
  const puedeFacturarDirecto = puedeConvertir && Boolean(empresa?.presupuesto_facturar_sin_ov);
  const puedeAceptarInterno = ["APPROVED", "SENT", "VIEWED"].includes(p.estado);
  const puedeVersionar = ["SENT", "VIEWED", "REJECTED", "EXPIRED"].includes(p.estado);
  const yaEnviado = !!p.fecha_envio_email;
  const aprobacionPendiente = (p.aprobaciones || []).find((a) => !a.resultado);
  const clienteEmail = p?.clientes?.personas?.email?.trim() || "";
  const faltaDestinatarioPrincipal = !clienteEmail && !emailForm.destinatarios.trim();

  return (
    <>
      <Stack id="presupuestos-detalle" spacing={2}>
        <Stack
          id="presupuestos-detalle-acciones"
          direction={{ xs: "column", sm: "row" }}
          alignItems={{ xs: "stretch", sm: "center" }}
          spacing={1.5}
          flexWrap="wrap"
        >
          <Button
            startIcon={<Icon icon="mdi:arrow-left" />}
            onClick={onVolver}
            sx={{ alignSelf: { xs: "flex-start", sm: "auto" } }}
          >
            Volver
          </Button>
          <Typography variant="h6" sx={{ lineHeight: 1.2 }}>
            {p.numero} <Typography component="span" variant="body2" color="text.secondary">v{p.version}</Typography>
          </Typography>
          <Chip size="small" label={est.label} color={est.color} icon={<Icon icon={est.icon} />} />
          <Box flexGrow={1} />
          <Stack direction="row" spacing={1} flexWrap="wrap" justifyContent={{ xs: "flex-start", sm: "flex-end" }}>
            <Button
              variant="outlined"
              startIcon={<Icon icon="mdi:file-pdf-box" />}
              onClick={() => setPreviewOpen(true)}
              size={isMobile ? "small" : "medium"}
            >
              Ver PDF
            </Button>
            {editable && (
              <Button
                variant="outlined"
                startIcon={<Icon icon="mdi:pencil-outline" />}
                onClick={() => onEditar(p.id)}
                size={isMobile ? "small" : "medium"}
              >
                Editar
              </Button>
            )}
            {editable && (
              <Button
                variant="contained"
                startIcon={<Icon icon="mdi:send-check-outline" />}
                onClick={handleEnviarAprobacion}
                disabled={submitReview.isPending}
                size={isMobile ? "small" : "medium"}
              >
                Enviar a aprobación
              </Button>
            )}
            {enRevision && (
              <>
                <Button
                  variant="outlined"
                  color="error"
                  startIcon={<Icon icon="mdi:thumb-down-outline" />}
                  onClick={handleRechazarAprobacion}
                  disabled={rejectApproval.isPending}
                  size={isMobile ? "small" : "medium"}
                >
                  Rechazar
                </Button>
                <Button
                  variant="contained"
                  color="success"
                  startIcon={<Icon icon="mdi:thumb-up-outline" />}
                  onClick={handleAprobar}
                  disabled={approve.isPending}
                  size={isMobile ? "small" : "medium"}
                >
                  Aprobar
                </Button>
              </>
            )}
            {puedeEnviarEmail && (
              <Button
                variant={puedeConvertir ? "outlined" : "contained"}
                startIcon={<Icon icon={yaEnviado ? "mdi:email-sync-outline" : "mdi:email-send-outline"} />}
                onClick={abrirEnviar}
                size={isMobile ? "small" : "medium"}
              >
                {yaEnviado ? "Reenviar" : "Enviar"}
              </Button>
            )}
            {puedeAceptarInterno && (
              <Button
                variant="contained"
                color="success"
                startIcon={<Icon icon="mdi:thumb-up-outline" />}
                onClick={() => setAceptarOpen(true)}
                disabled={markAccepted.isPending}
                size={isMobile ? "small" : "medium"}
              >
                Marcar como aceptado
              </Button>
            )}
            {puedeVersionar && (
              <Button
                variant="outlined"
                color="secondary"
                startIcon={<Icon icon="mdi:source-branch" />}
                onClick={handleNuevaVersion}
                disabled={newVersion.isPending}
                size={isMobile ? "small" : "medium"}
              >
                Nueva versión
              </Button>
            )}
            {puedeFacturarDirecto && (
              <Button
                variant="contained"
                color="success"
                startIcon={<Icon icon="mdi:receipt-text-outline" />}
                onClick={handleFacturarDirecto}
                size={isMobile ? "small" : "medium"}
              >
                Facturar
              </Button>
            )}
            {puedeConvertir && (
              <Button
                variant={puedeFacturarDirecto ? "outlined" : "contained"}
                color="success"
                startIcon={<Icon icon="mdi:cart-arrow-right" />}
                onClick={handleConvertir}
                disabled={convertToOrder.isPending}
                size={isMobile ? "small" : "medium"}
              >
                Convertir a Orden de Venta
              </Button>
            )}
            {["CONVERTED", "FACTURADO"].includes(p.estado) && p.pedido_id && (
              <Chip
                size="small"
                color="success"
                icon={<Icon icon="mdi:cart-check" />}
                label={p.estado === "FACTURADO" ? "OV facturada" : "Convertido en OV"}
              />
            )}
          </Stack>
        </Stack>

        {enRevision && (
          <Box
            sx={{
              display: "flex",
              alignItems: "center",
              gap: 1,
              p: 1.25,
              borderRadius: 1,
              bgcolor: "warning.50",
              border: "1px solid",
              borderColor: "warning.light",
              color: "warning.dark",
            }}
          >
            <Icon icon="mdi:clock-alert-outline" style={{ fontSize: 20 }} />
            <Typography variant="body2">
              Pendiente de aprobación interna{aprobacionPendiente ? ` (nivel ${aprobacionPendiente.nivel})` : ""}.
            </Typography>
          </Box>
        )}

        <Paper id="presupuestos-detalle-datos" variant="outlined" sx={{ p: { xs: 1.5, sm: 2 } }}>
          <Grid container spacing={1.5}>
            <Info label="Cliente" value={p.clientes?.personas?.razon_social} md={4} />
            <Info label="RUC/CI" value={p.clientes?.personas?.ruc ?? p.clientes?.personas?.nro_documento} md={2} />
            <Info label="Contacto" value={p.contacto_cliente} md={3} />
            <Info label="Vendedor" value={p.vendedor ? `${p.vendedor.nombre ?? ""} ${p.vendedor.apellido ?? ""}`.trim() : "—"} md={3} />
            <Info label="Título" value={p.titulo} md={6} />
            <Info label="Emisión" value={fmtFechaCalendario(p.fecha_emision)} md={2} />
            <Info label="Vigencia" value={fmtFechaCalendario(p.fecha_vigencia)} md={2} />
            <Info label="Moneda" value={moneda} md={2} />
            {moneda !== "PYG" && Number(p.tipo_cambio_usd) > 0 && (
              <Info
                label={`Tipo de cambio (${moneda}→Gs)`}
                value={`₲ ${Number(p.tipo_cambio_usd).toLocaleString("es-PY", { maximumFractionDigits: 4 })}`}
                md={2}
              />
            )}
            <Info label="Condición de pago" value={p.condicion_pago} md={moneda !== "PYG" && Number(p.tipo_cambio_usd) > 0 ? 4 : 6} />
            {p.notas_cliente && <Info label="Notas para el cliente" value={p.notas_cliente} md={6} />}
          </Grid>
        </Paper>

        <Paper id="presupuestos-detalle-items" variant="outlined" sx={{ p: { xs: 1, sm: 1.5 } }}>
          {isMobile ? (
            <Stack spacing={1}>
              {(p.items || []).map((it) => {
                const informativo = esItemInformativo(it.tipo);
                return (
                  <Paper key={it.id} variant="outlined" sx={{ p: 1.25 }}>
                    <Stack spacing={0.4}>
                      <Typography variant="caption" color="text.secondary">#{it.orden}</Typography>
                      <Typography variant="body2" fontWeight={600}>{it.descripcion}</Typography>
                      {it.notas_item && <Typography variant="caption" color="text.secondary">{it.notas_item}</Typography>}
                      <Box sx={{ display: "grid", gridTemplateColumns: "repeat(2, minmax(0, 1fr))", gap: 0.5, mt: 0.5 }}>
                        <ItemCell label="Cant." value={informativo ? "—" : Number(it.cantidad)} />
                        <ItemCell label="P. Unitario" value={informativo ? "—" : fmtMoneda(Number(it.precio_unitario), moneda)} />
                        <ItemCell label="Desc." value={informativo ? "—" : descItemTexto(it, moneda)} />
                        <ItemCell label="IVA" value={it.iva_categoria?.replace("IVA_", "IVA ")} />
                      </Box>
                      <Typography variant="body2" fontWeight={700} sx={{ mt: 0.5 }}>
                        Subtotal: {informativo ? "—" : fmtMoneda(Number(it.subtotal_con_iva), moneda)}
                      </Typography>
                    </Stack>
                  </Paper>
                );
              })}
            </Stack>
          ) : (
            <TableContainer>
              <Table size="small">
                <TableHead>
                  <TableRow>
                    <TableCell>#</TableCell>
                    <TableCell>Descripción</TableCell>
                    <TableCell align="right">Cant.</TableCell>
                    <TableCell align="right">P. Unitario</TableCell>
                    <TableCell align="right">Desc.</TableCell>
                    <TableCell>IVA</TableCell>
                    <TableCell align="right">Subtotal</TableCell>
                  </TableRow>
                </TableHead>
                <TableBody>
                  {(p.items || []).map((it) => {
                    const informativo = esItemInformativo(it.tipo);
                    return (
                      <TableRow key={it.id}>
                        <TableCell>{it.orden}</TableCell>
                        <TableCell>
                          <Typography variant="body2">{it.descripcion}</Typography>
                          {it.notas_item && <Typography variant="caption" color="text.secondary">{it.notas_item}</Typography>}
                        </TableCell>
                        <TableCell align="right">{informativo ? "—" : Number(it.cantidad)}</TableCell>
                        <TableCell align="right">{informativo ? "—" : fmtMoneda(Number(it.precio_unitario), moneda)}</TableCell>
                        <TableCell align="right">{informativo ? "—" : descItemTexto(it, moneda)}</TableCell>
                        <TableCell>{it.iva_categoria?.replace("IVA_", "IVA ")}</TableCell>
                        <TableCell align="right">{informativo ? "—" : fmtMoneda(Number(it.subtotal_con_iva), moneda)}</TableCell>
                      </TableRow>
                    );
                  })}
                </TableBody>
              </Table>
            </TableContainer>
          )}
        </Paper>

        <Paper
          id="presupuestos-detalle-totales"
          variant="outlined"
          sx={{ p: { xs: 1.5, sm: 2 }, display: "flex", justifyContent: { xs: "stretch", sm: "flex-end" } }}
        >
          {(() => {
            const descMonto = Number(p.descuento_global_monto) || 0;
            const totalBruto = Number(p.total) + descMonto; // el descuento se aplica sobre el bruto
            const totalIva = Number(p.iva5 || 0) + Number(p.iva10 || 0);
            const baseGravada = Number(p.base_iva5 || 0) + Number(p.base_iva10 || 0);
            return (
              <Stack spacing={0.6} sx={{ width: { xs: "100%", sm: 340 } }}>
                <Row label="Total Bruto" value={fmtMoneda(totalBruto, moneda)} />
                {descMonto > 0 && (
                  <Row
                    label={`Descuento global (${p.descuento_global_pct}%)`}
                    value={`- ${fmtMoneda(descMonto, moneda)}`}
                    discount
                  />
                )}
                <Divider sx={{ my: 0.4, borderStyle: "dashed" }} />
                <Row label="Liq. IVA 10%" value={fmtMoneda(Number(p.iva10), moneda)} muted />
                <Row label="Liq. IVA 5%" value={fmtMoneda(Number(p.iva5), moneda)} muted />
                <Row label="Total IVA" value={fmtMoneda(totalIva, moneda)} muted />
                <Divider sx={{ my: 0.4, borderStyle: "dashed" }} />
                <Row label="Base Gravada" value={fmtMoneda(baseGravada, moneda)} muted />
                <Row label="Total Exentas" value={fmtMoneda(Number(p.subtotal_exento), moneda)} muted />
                <Divider sx={{ my: 0.5 }} />
                <Row label="TOTAL" value={fmtMoneda(Number(p.total), moneda)} bold />
                {p.total_equivalente != null && (
                  <Row label="Equivalente Gs" value={fmtMoneda(Number(p.total_equivalente), "PYG")} muted />
                )}
              </Stack>
            );
          })()}
        </Paper>

        {(p.fecha_envio_email || p.fecha_vista_cliente || p.fecha_respuesta_cliente) && (
          <Paper variant="outlined" sx={{ p: { xs: 1.5, sm: 2 } }}>
            <Typography variant="subtitle2" sx={{ mb: 1 }}>Seguimiento del cliente</Typography>
            <Stack direction={{ xs: "column", sm: "row" }} spacing={{ xs: 1, sm: 3 }}>
              <Seguimiento icon="mdi:email-send-outline" label="Enviado" value={fmtFechaHora(p.fecha_envio_email)} ok={!!p.fecha_envio_email} />
              <Seguimiento icon="mdi:eye-check-outline" label="Visto" value={fmtFechaHora(p.fecha_vista_cliente)} ok={!!p.fecha_vista_cliente} />
              <Seguimiento
                icon={p.estado === "REJECTED" ? "mdi:thumb-down-outline" : "mdi:thumb-up-outline"}
                label={p.estado === "REJECTED" ? "Rechazado" : "Respondido"}
                value={fmtFechaHora(p.fecha_respuesta_cliente)}
                ok={!!p.fecha_respuesta_cliente}
              />
            </Stack>
            {p.estado === "REJECTED" && p.motivo_rechazo && (
              <Typography variant="body2" color="error" sx={{ mt: 1 }}>
                Motivo: {p.motivo_rechazo}
              </Typography>
            )}
          </Paper>
        )}

        {(p.historial?.length > 0) && (
          <Paper variant="outlined" sx={{ p: { xs: 1.5, sm: 2 } }}>
            <Typography variant="subtitle2" sx={{ mb: 1 }}>Historial</Typography>
            <Stack spacing={0.5}>
              {p.historial.map((h) => (
                <Stack key={h.id} direction="row" spacing={1} alignItems="center" flexWrap="wrap">
                  <Icon icon="mdi:circle-small" />
                  <Typography variant="caption" color="text.secondary">{fmtFechaHora(h.fecha)}</Typography>
                  <Typography variant="body2">
                    {h.estado_anterior ? `${h.estado_anterior} → ` : ""}{h.estado_nuevo}{h.comentario ? ` · ${h.comentario}` : ""}
                  </Typography>
                </Stack>
              ))}
            </Stack>
          </Paper>
        )}
      </Stack>

      <PdfPreviewModal
        open={previewOpen}
        onClose={() => setPreviewOpen(false)}
        id={id}
        numero={p?.numero || ""}
      />

      <Dialog
        id="presupuestos-email-dialog"
        open={emailOpen}
        onClose={() => !sendEmail.isPending && !generateLink.isPending && setEmailOpen(false)}
        fullWidth
        maxWidth="sm"
      >
        <DialogTitle>Enviar presupuesto {p?.numero} por email</DialogTitle>
        <DialogContent>
          <Stack spacing={2} sx={{ mt: 0.5 }}>
            <TextField
              label="Destinatario principal"
              value={emailForm.destinatarios}
              onChange={(e) => setEmailForm((f) => ({ ...f, destinatarios: e.target.value }))}
              placeholder="Ej: cliente@correo.com"
              helperText={
                !clienteEmail
                  ? "Este cliente no tiene email principal configurado. Cargá uno para poder enviar."
                  : "Email principal del cliente. Si lo dejás vacío, se usa el configurado en la ficha del cliente."
              }
              error={faltaDestinatarioPrincipal}
              fullWidth
              autoFocus
            />
            <TextField
              label="Copias (CC) (opcional)"
              value={emailForm.cc}
              onChange={(e) => setEmailForm((f) => ({ ...f, cc: e.target.value }))}
              placeholder="Ej: ventas@empresa.com, compras@empresa.com"
              helperText="Destinatarios adicionales en copia. Separá varios emails con coma."
              fullWidth
            />
            <TextField
              label="Asunto (opcional)"
              value={emailForm.asunto}
              onChange={(e) => setEmailForm((f) => ({ ...f, asunto: e.target.value }))}
              placeholder={`Presupuesto ${p?.numero} — tu empresa`}
              fullWidth
            />
            <TextField
              label="Mensaje (opcional)"
              value={emailForm.mensaje}
              onChange={(e) => setEmailForm((f) => ({ ...f, mensaje: e.target.value }))}
              placeholder="Mensaje personalizado para el cuerpo del correo."
              multiline
              minRows={3}
              fullWidth
            />
            <Typography variant="caption" color="text.secondary">
              <Icon icon="mdi:information-outline" style={{ verticalAlign: "middle" }} /> Podés enviar por email (con PDF adjunto) o copiar el enlace público para compartirlo por WhatsApp u otro medio.
            </Typography>
          </Stack>
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setEmailOpen(false)} disabled={sendEmail.isPending || generateLink.isPending}>Cancelar</Button>
          <Button
            variant="outlined"
            onClick={handleCopiarEnlace}
            disabled={sendEmail.isPending || generateLink.isPending}
            startIcon={generateLink.isPending ? <CircularProgress size={16} /> : <Icon icon="mdi:link-variant" />}
          >
            {generateLink.isPending ? "Generando…" : "Copiar enlace"}
          </Button>
          <Button
            variant="contained"
            onClick={handleEnviar}
            disabled={sendEmail.isPending || generateLink.isPending || faltaDestinatarioPrincipal}
            startIcon={sendEmail.isPending ? <CircularProgress size={16} /> : <Icon icon="mdi:email-send-outline" />}
          >
            {sendEmail.isPending ? "Enviando…" : "Enviar"}
          </Button>
        </DialogActions>
      </Dialog>

      <MarcarAceptadoDialog
        open={aceptarOpen}
        numero={p.numero}
        onClose={() => setAceptarOpen(false)}
        onConfirm={handleMarcarAceptado}
        isPending={markAccepted.isPending}
      />

      {dialogs}
    </>
  );
}

function Seguimiento({ icon, label, value, ok }) {
  return (
    <Stack direction="row" spacing={1} alignItems="center">
      <Icon icon={icon} style={{ fontSize: 20, color: ok ? "#16a34a" : "#cbd5e1" }} />
      <Box>
        <Typography variant="caption" color="text.secondary" sx={{ display: "block", lineHeight: 1.1 }}>{label}</Typography>
        <Typography variant="body2" color={ok ? "text.primary" : "text.secondary"}>{ok ? value : "—"}</Typography>
      </Box>
    </Stack>
  );
}

function Info({ label, value, md = 4 }) {
  return (
    <Grid item xs={12} sm={6} md={md}>
      <Typography variant="caption" color="text.secondary">{label}</Typography>
      <Typography variant="body2">{value || "—"}</Typography>
    </Grid>
  );
}

function ItemCell({ label, value }) {
  return (
    <Box>
      <Typography variant="caption" color="text.secondary" sx={{ display: "block", lineHeight: 1.1 }}>{label}</Typography>
      <Typography variant="body2">{value}</Typography>
    </Box>
  );
}

function Row({ label, value, bold, muted, discount }) {
  const color = discount ? "error.main" : muted ? "text.secondary" : undefined;
  return (
    <Stack direction="row" justifyContent="space-between" alignItems="baseline" gap={2}>
      <Typography variant={bold ? "subtitle1" : "body2"} fontWeight={bold ? 700 : muted ? 400 : 600} color={color}>
        {label}
      </Typography>
      <Typography
        variant={bold ? "h6" : "body2"}
        fontWeight={bold ? 800 : discount ? 600 : muted ? 400 : 600}
        color={bold ? "primary.main" : color}
        sx={{ fontFamily: "monospace", whiteSpace: "nowrap" }}
      >
        {value}
      </Typography>
    </Stack>
  );
}
