import { Icon } from "@iconify/react";
import * as XLSX from "xlsx";
import {
  Alert,
  Autocomplete,
  Box,
  Button,
  Card,
  CardContent,
  Checkbox,
  Chip,
  Collapse,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  FormControl,
  Grid,
  IconButton,
  InputLabel,
  ListItemIcon,
  ListItemText,
  Menu,
  MenuItem,
  Paper,
  Select,
  Skeleton,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  TextField,
  Tooltip,
  Typography,
  useMediaQuery,
  useTheme,
} from "@mui/material";
import { DatePicker, LocalizationProvider } from "@mui/x-date-pickers";
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
import dayjs from "dayjs";
import "dayjs/locale/es";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useNavegacionListado } from "../../hooks/useNavegacionListado";
import { useNavigate, useSearchParams } from "react-router-dom";
import { toast } from "sonner";
import { searchChoferes } from "../../api/choferes.service";
import { searchTransportistas } from "../../api/transportistas.service";
import { searchAgentesTransporte } from "../../api/agentes-transporte.service";
import { searchVehiculos } from "../../api/vehiculos.service";
import { useReferencialesQuery } from "../../tanstack/ReferencialesStack";
import { getNotasRemision } from "../../api/nota-remision.service";
import {
  useAnularNotaRemisionMutation, useNotasRemisionQuery, useNotasRemisionResumenQuery, useSincronizarNotasRemisionMutation, useEnviarLoteNRMutation, useEventoNRMutation } from "../../tanstack/NotaRemisionStack";
import { TablePaginationBar, EmptyState, ScreenGuia, SifenEstadoChip, ListToolbar, EventoSifenPendienteItem, tieneEventoSifenPendiente, AlertasEmpresaBanner, getSifenPipelineSteps } from "../_standards";
import { fmtFechaHoraSoloFecha } from "../../utils/fecha";
import { DocumentosHeaderActions } from "./DocumentosHeaderActions";
import { SifenSelectionBar } from "./SifenSelectionBar";
import KudePreviewModal from "../organismos/KudePreviewModal";
import RemisionDetalleDialog from "./RemisionDetalleDialog";
import { useAuthStore } from "../../store/AuthStore";
import { usePermission } from "../../hooks/usePermission";
import { sanitizeRecords } from "../_standards";

dayjs.locale("es");

const ESTADOS = [
  { value: "", label: "Todos los estados" },
  { value: "Pendiente", label: "Pendiente", color: "warning" },
  { value: "Aprobado", label: "Aprobado", color: "success" },
  { value: "Rechazado", label: "Rechazado", color: "error" },
  { value: "Anulado", label: "Anulado", color: "default" },
];

const ESTADOS_SIFEN = [
  { value: "", label: "Todos" },
  { value: "none", label: "No enviado" },
  { value: "Aprobado", label: "Aprobado" },
  { value: "Rechazado", label: "Rechazado" },
  { value: "Error", label: "Error" },
];

const FILTROS_RAPIDOS = [
  { label: "Hoy", value: "hoy" },
  { label: "Ayer", value: "ayer" },
  { label: "Esta semana", value: "semana" },
  { label: "Este mes", value: "mes" },
  { label: "Mes anterior", value: "mes_anterior" },
];

const COLUMNAS_DISPONIBLES = [
  { id: "numero", label: "Número", default: true },
  { id: "fecha", label: "Fecha", default: true },
  { id: "cliente", label: "Cliente", default: true },
  { id: "transportista", label: "Transportista", default: true },
  { id: "chofer", label: "Chofer", default: false },
  { id: "vehiculo", label: "Vehículo", default: false },
  { id: "motivo", label: "Motivo", default: true },
  { id: "estado", label: "Estado", default: true },
  { id: "estado_sifen", label: "SIFEN", default: true },
  { id: "pipeline", label: "Pipeline", default: true },
  { id: "cdc", label: "CDC", default: false },
  { id: "acciones", label: "Acciones", default: true },
];

const COLUMNAS_DEFAULT = COLUMNAS_DISPONIBLES.filter((c) => c.default).map((c) => c.id);
const COLUMNAS_STORAGE_KEY = "remisiones_tab_columnas_visibles";

const ESTADO_COLOR = {
  Pendiente: "warning",
  Aprobado: "success",
  Rechazado: "error",
  Anulado: "default",
};

const getColumnasIniciales = () => {
  try {
    const guardadas = localStorage.getItem(COLUMNAS_STORAGE_KEY);
    if (guardadas) {
      const parsed = JSON.parse(guardadas);
      const idsValidos = new Set(COLUMNAS_DISPONIBLES.map((c) => c.id));
      if (Array.isArray(parsed) && parsed.every((id) => idsValidos.has(id))) return parsed;
    }
  } catch (_) { /* ignore */ }
  return COLUMNAS_DEFAULT;
};

function useTransportSearch(searchFn) {
  const [inputValue, setInputValue] = useState("");
  const [options, setOptions] = useState([]);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    if (!inputValue || inputValue.length < 2) { setOptions([]); return; }
    const t = setTimeout(async () => {
      setLoading(true);
      try {
        const data = await searchFn(inputValue);
        setOptions(Array.isArray(data) ? data : (data?.items || []));
      } finally { setLoading(false); }
    }, 300);
    return () => clearTimeout(t);
  }, [inputValue, searchFn]);

  return { inputValue, setInputValue, options, loading };
}

export const RemisionesTab = () => {
  const theme = useTheme();
  const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
  const navigate = useNavigate();
  const sincronizarMutation = useSincronizarNotasRemisionMutation();
  const enviarLoteMutation = useEnviarLoteNRMutation();
  const eventoMutation = useEventoNRMutation();
  const { data: referenciales } = useReferencialesQuery();
  const motivosRef = referenciales?.motivo_emision_remision || [];
  const sifenActivo = useAuthStore((s) => s.empresa?.sifen_activo !== false);
  const { can } = usePermission("VENTAS");
  const canCancelacionNR = can("VEN_REMISION_SIFEN_CANCELAR");
  const anularMutation = useAnularNotaRemisionMutation();
  const canInutilizacionNR = can("VEN_REMISION_SIFEN_INUTILIZAR");
  const canEnviarSifenNR = can("VEN_REMISION_SIFEN_ENVIAR");
  const canEventoSifenNR = canCancelacionNR || canInutilizacionNR;

  // ── Filtros ──
  const [search, setSearch] = useState("");
  const [searchDebounced, setSearchDebounced] = useState("");
  // `?buscar=` viene del link de una alerta ("Ir al documento"): arranca filtrado.
  const [searchParams] = useSearchParams();
  const buscarInicial = searchParams.get("buscar");
  useEffect(() => {
    if (!buscarInicial) return;
    setSearch(buscarInicial);
    setSearchDebounced(buscarInicial);
  }, [buscarInicial]);
  const [estado, setEstado] = useState("");
  const [estadoSifen, setEstadoSifen] = useState("");
  const [fechaDesde, setFechaDesde] = useState(dayjs().startOf("week"));
  const [fechaHasta, setFechaHasta] = useState(dayjs().endOf("day"));
  const [filtroRapido, setFiltroRapido] = useState("semana");
  const [showFilters, setShowFilters] = useState(false);
  const [page, setPage] = useState(1);
  const [limit, setLimit] = useState(20);
  const [isExporting, setIsExporting] = useState(false);

  // ── SIFEN selection & eventos ──
  const [selectedRemisiones, setSelectedRemisiones] = useState([]);
  const [eventoMenuAnchor, setEventoMenuAnchor] = useState(null);
  const [remisionSeleccionada, setRemisionSeleccionada] = useState(null);
  const [dialogEvento, setDialogEvento] = useState({ open: false, tipo: null, motivo: "" });
  const [kudePreview, setKudePreview] = useState({ open: false, remisionId: null });
  const [detalle, setDetalle] = useState({ open: false, remisionId: null });
  const screenGuiaRef = useRef(null);

  // ── Transport filters ──
  const [selectedTransportista, setSelectedTransportista] = useState(null);
  const [selectedChofer, setSelectedChofer] = useState(null);
  const [selectedVehiculo, setSelectedVehiculo] = useState(null);
  const [selectedAgente, setSelectedAgente] = useState(null);

  const transSearch = useTransportSearch(searchTransportistas);
  const chofSearch = useTransportSearch(searchChoferes);
  const vehSearch = useTransportSearch(useCallback((q) => searchVehiculos(q), []));
  const agSearch = useTransportSearch(searchAgentesTransporte);

  // ── Columnas ──
  const [columnasVisibles, setColumnasVisibles] = useState(getColumnasIniciales);
  const [columnMenuAnchor, setColumnMenuAnchor] = useState(null);

  const toggleColumna = (id) => {
    setColumnasVisibles((prev) => {
      const next = prev.includes(id) ? prev.filter((c) => c !== id) : [...prev, id];
      try { localStorage.setItem(COLUMNAS_STORAGE_KEY, JSON.stringify(next)); } catch (_) { /**/ }
      return next;
    });
  };
  const isCol = (id) => columnasVisibles.includes(id);

  // ── Debounce search ──
  useEffect(() => {
    const t = setTimeout(() => { setSearchDebounced(search); setPage(1); }, 500);
    return () => clearTimeout(t);
  }, [search]);

  // ── Filtro rápido ──
  const aplicarFiltroRapido = useCallback((filtro) => {
    const hoy = dayjs();
    setFiltroRapido(filtro);
    switch (filtro) {
      case "hoy": setFechaDesde(hoy); setFechaHasta(hoy); break;
      case "ayer": setFechaDesde(hoy.subtract(1, "day")); setFechaHasta(hoy.subtract(1, "day")); break;
      case "semana": setFechaDesde(hoy.startOf("week")); setFechaHasta(hoy.endOf("week")); break;
      case "mes": setFechaDesde(hoy.startOf("month")); setFechaHasta(hoy.endOf("month")); break;
      case "mes_anterior": setFechaDesde(hoy.subtract(1, "month").startOf("month")); setFechaHasta(hoy.subtract(1, "month").endOf("month")); break;
      default: setFechaDesde(null); setFechaHasta(null);
    }
    setPage(1);
  }, []);

  const limpiarFiltros = () => {
    setSearch(""); setSearchDebounced(""); setEstado(""); setEstadoSifen("");
    setFechaDesde(null); setFechaHasta(null); setFiltroRapido("");
    setSelectedTransportista(null); setSelectedChofer(null);
    setSelectedVehiculo(null); setSelectedAgente(null);
    setPage(1);
  };

  // ── Query params ──
  const queryParams = useMemo(() => ({
    search: searchDebounced || undefined,
    estado: estado || undefined,
    estado_sifen: estadoSifen || undefined,
    transportista_id: selectedTransportista?.id || undefined,
    chofer_id: selectedChofer?.id || undefined,
    vehiculo_id: selectedVehiculo?.id || undefined,
    agente_id: selectedAgente?.id || undefined,
    ...(searchDebounced ? {} : {
      fechaDesde: fechaDesde ? new Date(fechaDesde.format("YYYY-MM-DD") + "T00:00:00").toISOString() : undefined,
      fechaHasta: fechaHasta ? (() => { const d = new Date(fechaHasta.format("YYYY-MM-DD") + "T23:59:59.999"); return d.toISOString(); })() : undefined,
    }),
  }), [searchDebounced, estado, estadoSifen, selectedTransportista, selectedChofer, selectedVehiculo, selectedAgente, fechaDesde, fechaHasta]);

  const resumenParams = useMemo(() => ({ ...queryParams }), [queryParams]);

  const { data: listData, isLoading, isError, error: listError, refetch } = useNotasRemisionQuery(page, limit, queryParams);
  const { data: resumenData, isLoading: isLoadingResumen } = useNotasRemisionResumenQuery(resumenParams);

  const items = useMemo(() => listData?.items || [], [listData]);
  const total = listData?.total || 0;
  const lastPage = listData?.lastPage || 1;

  // Navegación anterior/siguiente del modal de detalle. Acá el diálogo recibe
  // un id, no el objeto, así que el selector guarda solo el id.
  const navegacionDetalle = useNavegacionListado({
    items,
    idActual: detalle.open ? detalle.remisionId : null,
    onSeleccionar: useCallback((item) => setDetalle({ open: true, remisionId: item.id }), []),
    page,
    lastPage,
    limit,
    total,
    setPage,
    paginaCargada: listData?.page,
  });
  const resumen = {
    total: resumenData?.total ?? 0,
    pendientesSifen: resumenData?.pendientesSifen ?? 0,
    aprobadosSifen: resumenData?.aprobadosSifen ?? 0,
    rechazadosSifen: resumenData?.rechazadosSifen ?? 0,
    anuladas: resumenData?.anuladas ?? 0,
  };

  const filtrosActivos = [
    searchDebounced, estado, estadoSifen, fechaDesde, fechaHasta,
    selectedTransportista, selectedChofer, selectedVehiculo, selectedAgente,
  ].filter(Boolean).length;

  const getMotivoDesc = (item) => {
    if (!item.motivo_emision_id) return "—";
    const m = motivosRef.find((r) => r.id === item.motivo_emision_id);
    return m ? `${m.codigo} - ${m.descripcion}` : "—";
  };

  const getTransportistaLabel = (item) => {
    const p = item.transportistas?.personas;
    return p?.razon_social || `${p?.nombre || ""} ${p?.apellido || ""}`.trim() || "—";
  };

  const getChoferLabel = (item) => {
    const p = item.choferes?.personas;
    return p?.razon_social || `${p?.nombre || ""} ${p?.apellido || ""}`.trim() || "—";
  };

  const getVehiculoLabel = (item) => {
    const v = item.vehiculos;
    if (!v) return "—";
    return [v.marca, v.modelo, v.nro_matricula ? `(${v.nro_matricula})` : ""].filter(Boolean).join(" ") || "—";
  };

  const getPersonaLabel = (obj) => {
    const p = obj?.personas;
    if (!p) return obj?.razon_social || obj?.nro_matricula || "Sin nombre";
    return p.razon_social || `${p.nombre || ""} ${p.apellido || ""}`.trim() || "Sin nombre";
  };

  // ── Pipeline SIFEN ──
  const getSifenPipeline = getSifenPipelineSteps;

  const esReenviable = (r) => !r.estado_sifen || r.estado_sifen === "Rechazado" || r.estado_sifen === "Error";
  const esCancelableECAN = (r) => {
    if (!r.fecha_envio_sifen) return false;
    return (Date.now() - new Date(r.fecha_envio_sifen).getTime()) / 3600000 <= 168;
  };

  // ── Selection handlers ──
  const handleSelectAll = (e) => {
    if (e.target.checked) setSelectedRemisiones(items.filter(esReenviable).map((r) => r.id));
    else setSelectedRemisiones([]);
  };
  const handleSelectItem = (id) =>
    setSelectedRemisiones((prev) => prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]);

  // ── Evento handlers ──
  const handleOpenEventoMenu = (e, item) => { e.stopPropagation(); setEventoMenuAnchor(e.currentTarget); setRemisionSeleccionada(item); };
  const handleCloseEventoMenu = () => setEventoMenuAnchor(null);
  const handleSelectEvento = (tipo) => {
    handleCloseEventoMenu();
    setDialogEvento({ open: false, tipo, motivo: "" });
    setTimeout(() => setDialogEvento({ open: true, tipo, motivo: "" }), 0);
  };
  const handleEnviarEvento = () => {
    if (!remisionSeleccionada || !dialogEvento.motivo.trim()) return;
    eventoMutation.mutate(
      { tipoEvento: dialogEvento.tipo, id: remisionSeleccionada.id, motivo: dialogEvento.motivo },
      { onSuccess: () => { setDialogEvento({ open: false, tipo: null, motivo: "" }); setRemisionSeleccionada(null); } }
    );
  };

  const handleExport = async () => {
    setIsExporting(true);
    try {
      const allData = await getNotasRemision(1, 9999, queryParams);
      const rows = (allData?.items || []).map((r) => ({
        Número: `${r.dest}-${r.dpunexp}-${r.dnumdoc}`,
        Fecha: fmtFechaHoraSoloFecha(r.dfeemide),
        Cliente: r.clientes?.personas?.razon_social || "—",
        Transportista: getTransportistaLabel(r),
        Chofer: getChoferLabel(r),
        Vehículo: getVehiculoLabel(r),
        Motivo: getMotivoDesc(r),
        Estado: r.estado || "—",
        SIFEN: r.estado_sifen || "No enviado",
        CDC: r.cdc || "—",
      }));
      const ws = XLSX.utils.json_to_sheet(sanitizeRecords(rows));
      const wb = XLSX.utils.book_new();
      XLSX.utils.book_append_sheet(wb, ws, "Remisiones");
      XLSX.writeFile(wb, `remisiones_${dayjs().format("YYYY-MM-DD")}.xlsx`);
      toast.success("Exportado correctamente");
    } catch {
      toast.error("Error al exportar");
    } finally {
      setIsExporting(false);
    }
  };

  return (
    <LocalizationProvider dateAdapter={AdapterDayjs} adapterLocale="es">
      <Box sx={{ overflowX: "hidden", width: "100%" }}>

        {/* ── Guía de pantalla ── */}
        <Box sx={{ mb: 1.5 }}>
          <ScreenGuia
            ref={screenGuiaRef}
            titulo="Notas de Remisión"
            moduloPadre="Ventas"
            intro="Documentá el traslado de mercaderías (documento electrónico tipo 7 ante la SET)."
            pasos={[
              { icon: "mdi:plus-box", titulo: "Nueva remisión", desc: "Creá una remisión desde una factura electrónica o sin documento asociado (traslado/consignación)." },
              { icon: "mdi:cloud-upload-outline", titulo: "Envío a SIFEN", desc: "Se envía automáticamente al crear. Usá 'Sincronizar SIFEN' para actualizar el estado (Aprobado/Rechazado)." },
              { icon: "mdi:package-variant-closed", titulo: "Stock", desc: "La remisión sin factura descuenta stock del depósito elegido; con factura no toca stock (ya lo hizo la factura)." },
              { icon: "mdi:file-pdf-box", titulo: "KUDE y detalle", desc: "Desde el ojo 👁 ves el detalle completo; el ícono PDF genera el KUDE." },
            ]}
          />
        </Box>
        <AlertasEmpresaBanner tipoDocumento="nota_remision" />

        {/* ── CTA principal en el header (estándar: fuera de la barra de filtros) ── */}
        <Box sx={{ display: "flex", justifyContent: "flex-end", mb: 1 }}>
          <Button variant="contained" size="small" startIcon={<Icon icon="mdi:plus" width={18} />}
            onClick={() => navigate("/ventas/remisiones/nueva")}
            sx={{ whiteSpace: "nowrap" }}
          >
            {isMobile ? "Nueva" : "Nueva Remisión"}
          </Button>
        </Box>

        {/* ── Barra superior estándar: búsqueda + acciones (fila 1) y filtros de período (fila 2) ── */}
        <ListToolbar
          searchText={search}
          onSearchChange={(v) => {
            setSearch(v);
            setPage(1);
          }}
          searchPlaceholder="N° remisión, cliente, CDC…"
          showFilters={showFilters}
          onToggleFilters={() => setShowFilters((p) => !p)}
          filtrosActivos={filtrosActivos}
          showColumns={false}
          quickFilters={FILTROS_RAPIDOS}
          quickFilterActive={filtroRapido}
          onQuickFilter={aplicarFiltroRapido}
          onClearFilters={limpiarFiltros}
          quickFiltersDisabled={Boolean(searchDebounced)}
          quickFiltersDisabledHint="Los filtros de período se desactivan mientras hay una búsqueda de texto activa."
          extraActions={
            <DocumentosHeaderActions
              onRefetch={refetch}
              onSyncSifen={() => sincronizarMutation.mutate()}
              onExport={handleExport}
              onColumns={(e) => setColumnMenuAnchor(e.currentTarget)}
              loadingSync={sincronizarMutation.isPending}
              loadingExport={isExporting}
              canSyncSifen
              showLabels={!isMobile}
            />
          }
        />

        {/* ── Menú columnas ── */}
        <Menu anchorEl={columnMenuAnchor} open={Boolean(columnMenuAnchor)}
          onClose={() => setColumnMenuAnchor(null)} PaperProps={{ sx: { maxHeight: 400, width: 220 } }}>
          <Box sx={{ px: 2, py: 1 }}>
            <Typography variant="subtitle2" fontWeight={600}>Columnas visibles</Typography>
          </Box>
          {COLUMNAS_DISPONIBLES.map((col) => (
            <MenuItem key={col.id} onClick={() => toggleColumna(col.id)} dense>
              <Checkbox checked={isCol(col.id)} size="small" sx={{ p: 0.5, mr: 1 }} />
              <ListItemText primary={col.label} />
            </MenuItem>
          ))}
        </Menu>

        {/* ── Panel de filtros ── */}
        <Collapse in={showFilters}>
          <Paper variant="outlined" sx={{ p: { xs: 1.5, sm: 2 }, mb: 2 }}>
            <Grid container spacing={1.5}>
              <Grid size={{ xs: 12, sm: 6, md: 3 }}>
                <DatePicker label="Fecha desde" value={fechaDesde}
                  onChange={(d) => { setFechaDesde(d); setFiltroRapido(""); setPage(1); }}
                  slotProps={{ textField: { size: "small", fullWidth: true } }} />
              </Grid>
              <Grid size={{ xs: 12, sm: 6, md: 3 }}>
                <DatePicker label="Fecha hasta" value={fechaHasta}
                  onChange={(d) => { setFechaHasta(d); setFiltroRapido(""); setPage(1); }}
                  slotProps={{ textField: { size: "small", fullWidth: true } }} />
              </Grid>
              <Grid size={{ xs: 12, sm: 6, md: 3 }}>
                <FormControl fullWidth size="small">
                  <InputLabel>Estado</InputLabel>
                  <Select value={estado} label="Estado" onChange={(e) => { setEstado(e.target.value); setPage(1); }}>
                    {ESTADOS.map((e) => <MenuItem key={e.value} value={e.value}>{e.label}</MenuItem>)}
                  </Select>
                </FormControl>
              </Grid>
              <Grid size={{ xs: 12, sm: 6, md: 3 }}>
                <FormControl fullWidth size="small">
                  <InputLabel>Estado SIFEN</InputLabel>
                  <Select value={estadoSifen} label="Estado SIFEN" onChange={(e) => { setEstadoSifen(e.target.value); setPage(1); }}>
                    {ESTADOS_SIFEN.map((e) => <MenuItem key={e.value} value={e.value}>{e.label}</MenuItem>)}
                  </Select>
                </FormControl>
              </Grid>
              <Grid size={{ xs: 12, sm: 6, md: 3 }}>
                <Autocomplete size="small" options={transSearch.options} loading={transSearch.loading}
                  value={selectedTransportista}
                  onChange={(_, v) => { setSelectedTransportista(v); setPage(1); }}
                  onInputChange={(_, v) => transSearch.setInputValue(v)}
                  getOptionLabel={(o) => getPersonaLabel(o)}
                  getOptionKey={(o) => o.id}
                  isOptionEqualToValue={(o, v) => o.id === v?.id}
                  noOptionsText={transSearch.inputValue.length < 2 ? "Escribe para buscar..." : "Sin resultados"}
                  renderInput={(params) => <TextField {...params} label="Transportista" placeholder="Buscar..." />}
                />
              </Grid>
              <Grid size={{ xs: 12, sm: 6, md: 3 }}>
                <Autocomplete size="small" options={chofSearch.options} loading={chofSearch.loading}
                  value={selectedChofer}
                  onChange={(_, v) => { setSelectedChofer(v); setPage(1); }}
                  onInputChange={(_, v) => chofSearch.setInputValue(v)}
                  getOptionLabel={(o) => getPersonaLabel(o)}
                  getOptionKey={(o) => o.id}
                  isOptionEqualToValue={(o, v) => o.id === v?.id}
                  noOptionsText={chofSearch.inputValue.length < 2 ? "Escribe para buscar..." : "Sin resultados"}
                  renderInput={(params) => <TextField {...params} label="Chofer" placeholder="Buscar..." />}
                />
              </Grid>
              <Grid size={{ xs: 12, sm: 6, md: 3 }}>
                <Autocomplete size="small" options={vehSearch.options} loading={vehSearch.loading}
                  value={selectedVehiculo}
                  onChange={(_, v) => { setSelectedVehiculo(v); setPage(1); }}
                  onInputChange={(_, v) => vehSearch.setInputValue(v)}
                  getOptionLabel={(o) => [o.marca, o.modelo, o.nro_matricula ? `(${o.nro_matricula})` : ""].filter(Boolean).join(" ") || "—"}
                  getOptionKey={(o) => o.id}
                  isOptionEqualToValue={(o, v) => o.id === v?.id}
                  noOptionsText={vehSearch.inputValue.length < 2 ? "Escribe para buscar..." : "Sin resultados"}
                  renderInput={(params) => <TextField {...params} label="Vehículo" placeholder="Buscar por matrícula, marca..." />}
                />
              </Grid>
              <Grid size={{ xs: 12, sm: 6, md: 3 }}>
                <Autocomplete size="small" options={agSearch.options} loading={agSearch.loading}
                  value={selectedAgente}
                  onChange={(_, v) => { setSelectedAgente(v); setPage(1); }}
                  onInputChange={(_, v) => agSearch.setInputValue(v)}
                  getOptionLabel={(o) => getPersonaLabel(o)}
                  getOptionKey={(o) => o.id}
                  isOptionEqualToValue={(o, v) => o.id === v?.id}
                  noOptionsText={agSearch.inputValue.length < 2 ? "Escribe para buscar..." : "Sin resultados"}
                  renderInput={(params) => <TextField {...params} label="Agente de transporte" placeholder="Buscar..." />}
                />
              </Grid>
              <Grid size={{ xs: 12 }}>
                <Button variant="outlined" size="small" startIcon={<Icon icon="mdi:filter-off" />} onClick={limpiarFiltros}>
                  Limpiar filtros
                </Button>
              </Grid>
            </Grid>
          </Paper>
        </Collapse>

        {/* ── Stats cards ── */}
        <Box sx={{ display: "flex", gap: { xs: 1, sm: 1.5 }, mb: { xs: 2, sm: 2.5 }, flexWrap: "wrap" }}>
          {[
            { label: "Remisiones", icon: "mdi:truck-delivery-outline", value: resumen.total, color: undefined },
            { label: "Pendiente SIFEN", icon: "mdi:cloud-upload-outline", value: resumen.pendientesSifen, color: "warning.main" },
            { label: "Aprobados SIFEN", icon: "mdi:check-circle", value: resumen.aprobadosSifen, color: "success.main" },
            { label: "Rechazados SIFEN", icon: "mdi:close-circle", value: resumen.rechazadosSifen, color: "error.main" },
            { label: "Anuladas", icon: "mdi:file-cancel-outline", value: resumen.anuladas, color: "warning.main" },
          ].map((kpi) => (
            <Card key={kpi.label} variant="outlined" sx={{ flex: "1 1 0", minWidth: 90 }}>
              <CardContent sx={{ p: { xs: 1, sm: 1.5 }, "&:last-child": { pb: { xs: 1, sm: 1.5 } } }}>
                <Typography color="text.secondary" variant="caption" sx={{ display: "flex", alignItems: "center", gap: 0.5, fontSize: { xs: "0.65rem", sm: "0.75rem" } }}>
                  <Icon icon={kpi.icon} width={isMobile ? 14 : 16} />
                  {kpi.label}
                </Typography>
                {(isLoading || isLoadingResumen) ? (
                  <Skeleton width={50} />
                ) : (
                  <Typography variant={isMobile ? "h6" : "h5"} fontWeight={600} color={kpi.color}>
                    {kpi.value}
                  </Typography>
                )}
              </CardContent>
            </Card>
          ))}
        </Box>

        {/* ── Barra de selección SIFEN ── */}
        <SifenSelectionBar
          selectedCount={selectedRemisiones.length}
          rechazadosCount={items.filter((r) => selectedRemisiones.includes(r.id) && r.estado_sifen === "Rechazado").length}
          entityLabel="remisión"
          canSend={canEnviarSifenNR}
          sending={enviarLoteMutation.isPending}
          onSend={() => enviarLoteMutation.mutate(selectedRemisiones, { onSuccess: () => setSelectedRemisiones([]) })}
          onCancel={() => setSelectedRemisiones([])}
        />

        {/* ── Error de carga ── */}
        {isError && (
          <Alert severity="error" sx={{ mb: 2 }} action={<Button color="inherit" size="small" onClick={() => refetch()}>Reintentar</Button>}>
            No se pudo cargar el listado de remisiones: {listError?.response?.data?.message || listError?.message || "Error desconocido"}
          </Alert>
        )}

        {/* ── Tabla ── */}
        <TableContainer component={Paper} variant="outlined">
          <Table size="small">
            <TableHead>
              <TableRow>
                <TableCell padding="checkbox">
                  <Checkbox
                    indeterminate={selectedRemisiones.length > 0 && selectedRemisiones.length < items.filter(esReenviable).length}
                    checked={items.filter(esReenviable).length > 0 && selectedRemisiones.length === items.filter(esReenviable).length}
                    onChange={handleSelectAll}
                  />
                </TableCell>
                {isCol("numero") && <TableCell sx={{ fontWeight: 600 }}>Número</TableCell>}
                {isCol("fecha") && <TableCell sx={{ fontWeight: 600 }}>Fecha</TableCell>}
                {isCol("cliente") && <TableCell sx={{ fontWeight: 600 }}>Cliente</TableCell>}
                {isCol("transportista") && <TableCell sx={{ fontWeight: 600 }}>Transportista</TableCell>}
                {isCol("chofer") && <TableCell sx={{ fontWeight: 600 }}>Chofer</TableCell>}
                {isCol("vehiculo") && <TableCell sx={{ fontWeight: 600 }}>Vehículo</TableCell>}
                {isCol("motivo") && <TableCell sx={{ fontWeight: 600 }}>Motivo</TableCell>}
                {isCol("estado") && <TableCell sx={{ fontWeight: 600 }}>Estado</TableCell>}
                {isCol("estado_sifen") && <TableCell sx={{ fontWeight: 600 }} align="center">SIFEN</TableCell>}
                {isCol("pipeline") && <TableCell sx={{ fontWeight: 600 }} align="center" />}
                {isCol("cdc") && <TableCell sx={{ fontWeight: 600 }}>CDC</TableCell>}
                {isCol("acciones") && <TableCell sx={{ fontWeight: 600 }} align="center">Acciones</TableCell>}
              </TableRow>
            </TableHead>
            <TableBody>
              {isLoading ? (
                Array.from({ length: 5 }).map((_, i) => (
                  <TableRow key={i}>
                    <TableCell padding="checkbox"><Skeleton variant="rectangular" width={18} height={18} /></TableCell>
                    {columnasVisibles.map((col) => (
                      <TableCell key={col}><Skeleton /></TableCell>
                    ))}
                  </TableRow>
                ))
              ) : items.length === 0 ? (
                <TableRow>
                  <TableCell colSpan={columnasVisibles.length + 1} sx={{ py: 4, borderBottom: "none" }}>
                    {filtrosActivos > 0 ? (
                      <EmptyState
                        compact
                        icon="mdi:filter-remove-outline"
                        title="Sin resultados para los filtros"
                        description="No hay remisiones que coincidan con la búsqueda o filtros aplicados."
                        ctaLabel="Limpiar filtros"
                        ctaIcon="mdi:filter-off"
                        onCta={limpiarFiltros}
                        helpLabel="¿Cómo funciona esta pantalla?"
                        onHelp={() => screenGuiaRef.current?.scrollIntoView({ behavior: "smooth", block: "start" })}
                      />
                    ) : (
                      <EmptyState
                        icon="mdi:truck-remove-outline"
                        title="Aún no hay remisiones"
                        description="Creá tu primera nota de remisión para documentar el traslado de mercaderías."
                        ctaLabel="Nueva remisión"
                        ctaIcon="mdi:plus"
                        onCta={() => navigate("/ventas/remisiones/nueva")}
                        helpLabel="¿Cómo funciona esta pantalla?"
                        onHelp={() => screenGuiaRef.current?.scrollIntoView({ behavior: "smooth", block: "start" })}
                      />
                    )}
                  </TableCell>
                </TableRow>
              ) : (
                items.map((item) => {
                  const isSelected = selectedRemisiones.includes(item.id);
                  return (
                  <TableRow key={item.id} hover selected={isSelected} sx={{ cursor: "pointer" }} onClick={() => setDetalle({ open: true, remisionId: item.id })}>
                    <TableCell padding="checkbox">
                      <Checkbox
                        checked={isSelected}
                        disabled={!esReenviable(item)}
                        onClick={(e) => e.stopPropagation()}
                        onChange={() => handleSelectItem(item.id)}
                      />
                    </TableCell>
                    {isCol("numero") && (
                      <TableCell>
                        <Typography variant="body2" fontWeight={500}>
                          {item.dest}-{item.dpunexp}-{item.dnumdoc}
                        </Typography>
                        {item.tipo_aprobacion && (
                          <Typography variant="caption" color="text.disabled">{item.tipo_aprobacion}</Typography>
                        )}
                      </TableCell>
                    )}
                    {isCol("fecha") && (
                      <TableCell>
                        {(() => {
                          const iso = item.dfeemide || "";
                          const [d, t] = iso.split("T");
                          const [y, mo, dy] = (d || "").split("-");
                          return (
                            <>
                              <Typography variant="body2">{dy}/{mo}/{y}</Typography>
                              <Typography variant="caption" color="text.secondary">{(t || "").substring(0, 5)}</Typography>
                            </>
                          );
                        })()}
                      </TableCell>
                    )}
                    {isCol("cliente") && <TableCell>{item.clientes?.personas?.razon_social || "—"}</TableCell>}
                    {isCol("transportista") && <TableCell>{getTransportistaLabel(item)}</TableCell>}
                    {isCol("chofer") && <TableCell>{getChoferLabel(item)}</TableCell>}
                    {isCol("vehiculo") && <TableCell>{getVehiculoLabel(item)}</TableCell>}
                    {isCol("motivo") && <TableCell><Typography variant="caption">{getMotivoDesc(item)}</Typography></TableCell>}
                    {isCol("estado") && (
                      <TableCell align="center">
                        <Chip label={item.estado || "Pendiente"} size="small"
                          color={ESTADO_COLOR[item.estado] || "default"} variant="outlined" />
                      </TableCell>
                    )}
                    {isCol("estado_sifen") && (
                      <TableCell align="center" sx={{ maxWidth: 180 }}>
                        <SifenEstadoChip
                          estadoSifen={item.estado_sifen}
                          mensajeSifen={item.mensaje_sifen}
                        />
                      </TableCell>
                    )}
                    {isCol("pipeline") && (
                      <TableCell align="center" sx={{ px: 0.5 }}>
                        <Box sx={{ display: "flex", alignItems: "center", justifyContent: "center", gap: "2px" }}>
                          {getSifenPipeline(item).map((step, i, arr) => (
                            <Box key={i} sx={{ display: "flex", alignItems: "center", gap: "2px" }}>
                              <Tooltip title={step.label + (step.date ? ` (${step.date})` : "")} arrow>
                                <Box component="span" sx={{ display: "inline-flex", cursor: "default" }}>
                                  <Icon icon={step.icon} width={15} style={{ color: step.done ? step.color : "#555", opacity: step.done ? 1 : 0.3 }} />
                                </Box>
                              </Tooltip>
                              {i < arr.length - 1 && <Icon icon="mdi:chevron-right" width={9} style={{ color: "#555", opacity: 0.4 }} />}
                            </Box>
                          ))}
                        </Box>
                      </TableCell>
                    )}
                    {isCol("cdc") && (
                      <TableCell>
                        <Typography variant="caption" color="text.secondary" sx={{ fontFamily: "monospace", fontSize: "0.65rem" }}>
                          {item.cdc ? item.cdc.slice(0, 12) + "…" : "—"}
                        </Typography>
                      </TableCell>
                    )}
                    {isCol("acciones") && (
                      <TableCell align="center" onClick={(e) => e.stopPropagation()}>
                        <Box sx={{ display: "flex", gap: 0.5, justifyContent: "center" }}>
                          <Tooltip title="Ver detalle">
                            <IconButton size="small" onClick={() => setDetalle({ open: true, remisionId: item.id })}>
                              <Icon icon="mdi:eye" width={18} />
                            </IconButton>
                          </Tooltip>
                          <Tooltip title="Ver KUDE / Imprimir">
                            <IconButton size="small" color="primary" onClick={() => setKudePreview({ open: true, remisionId: item.id })}>
                              <Icon icon="mdi:file-pdf-box" width={18} />
                            </IconButton>
                          </Tooltip>
                          {canEventoSifenNR && (item.estado_sifen === "Rechazado" || item.estado_sifen === "Error" || item.estado_sifen === "Aprobado") && (
                            <Tooltip title="Eventos SIFEN">
                              <IconButton size="small" color="warning" onClick={(e) => handleOpenEventoMenu(e, item)}>
                                <Icon icon="mdi:file-document-alert" width={18} />
                              </IconButton>
                            </Tooltip>
                          )}
                        </Box>
                      </TableCell>
                    )}
                  </TableRow>
                  );
                })
              )}
            </TableBody>
          </Table>
        </TableContainer>

        {/* ── Paginación ── */}
        {total > 0 && (
          <Box sx={{ mt: 1.5 }}>
            <TablePaginationBar
              page={page}
              totalPages={lastPage}
              onPageChange={(n) => setPage(n)}
              total={total}
              shown={items.length}
              noun="remisiones"
              rowsPerPage={limit}
              onRowsPerPageChange={(n) => { setLimit(n); setPage(1); }}
            />
          </Box>
        )}
        {/* ── Menú eventos SIFEN ── */}
        <Menu anchorEl={eventoMenuAnchor} open={Boolean(eventoMenuAnchor)} onClose={handleCloseEventoMenu}>
          {tieneEventoSifenPendiente(remisionSeleccionada) && (
            <EventoSifenPendienteItem documento={remisionSeleccionada} tipoDocumento="nota_remision" onCerrar={handleCloseEventoMenu} />
          )}
          {canCancelacionNR &&
            !tieneEventoSifenPendiente(remisionSeleccionada) &&
            remisionSeleccionada?.estado !== "Anulado" &&
            !["Rechazado", "Error", "Aprobado"].includes(remisionSeleccionada?.estado_sifen) && (
              <MenuItem
                onClick={() => {
                  anularMutation.mutate(remisionSeleccionada.id);
                  handleCloseEventoMenu();
                }}
              >
                <ListItemIcon><Icon icon="mdi:cancel" width={20} /></ListItemIcon>
                <ListItemText
                  primary="Anular remisión"
                  secondary="Sin evento SIFEN: repone el stock y libera lo aplicado a facturas"
                />
              </MenuItem>
            )}
          {canInutilizacionNR && !tieneEventoSifenPendiente(remisionSeleccionada) && (remisionSeleccionada?.estado_sifen === "Rechazado" || remisionSeleccionada?.estado_sifen === "Error") && (
            <MenuItem onClick={() => handleSelectEvento("inutilizacion")}>
              <ListItemIcon><Icon icon="mdi:file-remove" width={20} /></ListItemIcon>
              <ListItemText primary="Inutilizar (EINU)" secondary="Para documentos rechazados o con error" />
            </MenuItem>
          )}
          {canCancelacionNR && !tieneEventoSifenPendiente(remisionSeleccionada) && remisionSeleccionada?.estado_sifen === "Aprobado" && (() => {
            const cancelable = !sifenActivo || esCancelableECAN(remisionSeleccionada);
            return (
              <Tooltip title={sifenActivo && !cancelable ? "Han pasado más de 7 días desde el envío" : ""} placement="left">
                <span>
                  <MenuItem disabled={!cancelable} onClick={() => handleSelectEvento("cancelacion")}>
                    <ListItemIcon><Icon icon="mdi:file-cancel" width={20} /></ListItemIcon>
                    <ListItemText
                      primary="Cancelar (ECAN)"
                      secondary={sifenActivo ? "Dentro de 7 días del envío" : "Cancelación local (sin SIFEN)"}
                    />
                  </MenuItem>
                </span>
              </Tooltip>
            );
          })()}
        </Menu>

        {/* ── Diálogo evento SIFEN ── */}
        <Dialog open={dialogEvento.open} onClose={() => setDialogEvento({ open: false, tipo: null, motivo: "" })} maxWidth="sm" fullWidth>
          <DialogTitle>
            {dialogEvento.tipo === "inutilizacion" ? "Inutilizar Documento (EINU)" : "Cancelar Documento (ECAN)"}
          </DialogTitle>
          <DialogContent>
            <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
              {dialogEvento.tipo === "inutilizacion"
                ? "Este evento inutilizará el documento rechazado en SIFEN."
                : "Este evento cancelará el documento aprobado en SIFEN. Solo disponible dentro de las 168 horas (7 días)."}
            </Typography>
            <TextField
              autoFocus fullWidth label="Motivo" multiline rows={3}
              value={dialogEvento.motivo}
              onChange={(e) => setDialogEvento((prev) => ({ ...prev, motivo: e.target.value }))}
              placeholder="Ingrese el motivo..."
            />
          </DialogContent>
          <DialogActions>
            <Button onClick={() => setDialogEvento({ open: false, tipo: null, motivo: "" })}>Cancelar</Button>
            <Button
              variant="contained"
              color={dialogEvento.tipo === "cancelacion" ? "error" : "warning"}
              onClick={handleEnviarEvento}
              disabled={!dialogEvento.motivo.trim() || eventoMutation.isPending}
            >
              {eventoMutation.isPending ? "Enviando..." : "Enviar Evento"}
            </Button>
          </DialogActions>
        </Dialog>

        {/* ── Modal KUDE preview ── */}
        <KudePreviewModal
          open={kudePreview.open}
          onClose={() => setKudePreview({ open: false, remisionId: null })}
          documentoId={kudePreview.remisionId}
          tipoDocumento={7}
          titulo="KUDE - Nota de Remisión"
          numeroDocumento={(() => {
            const r = items.find((x) => x.id === kudePreview.remisionId);
            return r?.dnumdoc ? `${r.dest}-${r.dpunexp}-${r.dnumdoc}` : undefined;
          })()}
        />

        {/* ── Modal detalle ── */}
        <RemisionDetalleDialog
          open={detalle.open}
          onClose={() => setDetalle({ open: false, remisionId: null })}
          remisionId={detalle.remisionId}
          navegacion={navegacionDetalle}
          onVerKude={(id) => {
            setDetalle({ open: false, remisionId: null });
            setKudePreview({ open: true, remisionId: id });
          }}
        />

      </Box>
    </LocalizationProvider>
  );
};
