import { Icon } from "@iconify/react";
import {
  Autocomplete,
  Box,
  Button,
  Card,
  CardContent,
  Chip,
  FormControl,
  InputAdornment,
  InputLabel,
  MenuItem,
  Pagination,
  Paper,
  Select,
  Skeleton,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  TextField,
  Typography,
  useMediaQuery,
  useTheme,
} from "@mui/material";
import { useQuery } from "@tanstack/react-query";
import { useCallback, useMemo, useRef, useState } from "react";
import { useNavigate } from "react-router-dom";
import { toast } from "sonner";
import { getMovimientos } from "../api";
import { getDepositos } from "../api/depositos.service";
import { buscarProductos } from "../api/productos.service";
import { getSucursales } from "../api/sucursales.service";
import { AccesoRestringido } from "../components/common/AccesoRestringido";
import { usePermission } from "../hooks/usePermission";
import { useReferencialesQuery } from "../tanstack/ReferencialesStack";
import { descargarCSV, descargarExcel, ExportarMenuButton } from "../components/_standards";
import { hoyISO } from "../utils/fecha";

// Documento que originó el movimiento, para mostrar (nunca el código interno).
const DOCUMENTO_ORIGEN_LABEL = {
  factura_venta: "Factura de venta",
  anulacion_factura: "Anulación de factura",
  nota_credito: "Nota de crédito",
  nota_remision: "Nota de remisión",
  nota_remision_anulacion: "Anulación de remisión",
  factura_compra: "Factura de compra",
  factura_compra_reversa: "Reversa de factura de compra",
  recepcion_compra: "Recepción de compra",
  recepcion_compra_reversa: "Reversa de recepción de compra",
  nota_credito_compra: "Nota de crédito de compra",
  nota_credito_compra_anulada: "Anulación de nota de crédito de compra",
  transferencia: "Transferencia",
  ajuste_manual: "Ajuste manual",
};
const documentoOrigen = (codigo) => {
  if (!codigo) return "";
  if (DOCUMENTO_ORIGEN_LABEL[codigo]) return DOCUMENTO_ORIGEN_LABEL[codigo];
  const t = String(codigo).replace(/_/g, " ");
  return t.charAt(0).toUpperCase() + t.slice(1);
};

// ==================== HELPERS ====================

const formatNum = (n) => new Intl.NumberFormat("es-PY").format(Number(n) || 0);

const formatFecha = (fecha) => {
  if (!fecha) return "-";
  if (typeof fecha === "string" && !fecha.includes("T")) return fecha;
  const d = new Date(fecha);
  if (isNaN(d.getTime())) return fecha;
  return `${String(d.getDate()).padStart(2, "0")}/${String(d.getMonth() + 1).padStart(2, "0")}/${d.getFullYear()} ${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
};

const getHoy = () => hoyISO();

// ==================== ENTRADA / SALIDA ====================

// Como un debe y haber: la cantidad va en Entrada si el tipo suma stock y en
// Salida si lo resta, siempre en positivo. Los tipos que no mueven stock
// (afecta_stock = 0, p. ej. Devolución) no van en ninguna para no inflar totales.
const efectoStock = (m) => Math.sign(Number(m.tipo_movimiento?.afecta_stock || 0));
const cantidadEntrada = (m) => (efectoStock(m) > 0 ? Math.abs(Number(m.cantidad || 0)) : null);
const cantidadSalida = (m) => (efectoStock(m) < 0 ? Math.abs(Number(m.cantidad || 0)) : null);

// ==================== EXPORT ====================

const armarTabla = (movimientos) => {
  const encabezados = [
    "Fecha", "Producto", "Código", "Depósito", "Sucursal", "Tipo",
    "Entrada", "Salida", "Documento", "Observaciones",
  ];
  const filas = movimientos.map((m) => [
    m.created_at || "",
    m.producto?.descripcion || "",
    m.producto?.cod_producto || "",
    m.deposito_origen?.descripcion || "",
    m.deposito_origen?.sucursal?.descripcion || m.deposito_origen?.sucursal?.nombre || "",
    m.tipo_movimiento?.descripcion || "",
    cantidadEntrada(m) ?? "",
    cantidadSalida(m) ?? "",
    documentoOrigen(m.documento_origen),
    [efectoStock(m) === 0 ? `No mueve stock (${Number(m.cantidad || 0)})` : null, m.observaciones || null]
      .filter(Boolean)
      .join(". "),
  ]);
  const totalEntradas = movimientos.reduce((a, m) => a + (cantidadEntrada(m) ?? 0), 0);
  const totalSalidas = movimientos.reduce((a, m) => a + (cantidadSalida(m) ?? 0), 0);
  filas.push([]);
  filas.push(["TOTALES", "", "", "", "", "", totalEntradas, totalSalidas, "", `Neto: ${Math.round((totalEntradas - totalSalidas) * 10000) / 10000}`]);
  return { encabezados, filas };
};

// ==================== COMPONENT ====================

export function ReporteMovimientosStock() {
  const navigate = useNavigate();
  const muiTheme = useTheme();
  const isMobile = useMediaQuery(muiTheme.breakpoints.down("md"));
  const { canRead } = usePermission("REPORTES");
  const canReadMovimientos = usePermission("INVENTARIO").can("INV_MOV_MOVIMIENTO_VER");

  // Filtros
  const [search, setSearch] = useState("");
  const [searchDebounced, setSearchDebounced] = useState("");
  const [productoId, setProductoId] = useState("");
  const [productoSearch, setProductoSearch] = useState("");
  const [depositoId, setDepositoId] = useState("");
  const [sucursalId, setSucursalId] = useState("");
  const [tipoMovimientoId, setTipoMovimientoId] = useState("");
  const [desde, setDesde] = useState("");
  const [hasta, setHasta] = useState("");
  const [page, setPage] = useState(1);
  const limit = 20;

  // Anchos de columnas (redimensionables por drag)
  const DEFAULT_COL_WIDTHS = {
    fecha: 160,
    producto: 280,
    deposito: 130,
    sucursal: 130,
    tipo: 180,
    entrada: 100,
    salida: 100,
    documento: 160,
    observaciones: 240,
  };
  const [colWidths, setColWidths] = useState(() => {
    try {
      const saved = localStorage.getItem("reporte-mov-stock-col-widths");
      if (saved) return { ...DEFAULT_COL_WIDTHS, ...JSON.parse(saved) };
    } catch {
      // ignore
    }
    return DEFAULT_COL_WIDTHS;
  });
  const resizingRef = useRef(null);

  const handleResizeStart = useCallback(
    (key) => (e) => {
      e.preventDefault();
      e.stopPropagation();
      resizingRef.current = {
        key,
        startX: e.clientX,
        startWidth: colWidths[key] || 120,
      };
      const onMove = (ev) => {
        if (!resizingRef.current) return;
        const delta = ev.clientX - resizingRef.current.startX;
        const next = Math.max(60, resizingRef.current.startWidth + delta);
        setColWidths((prev) => ({ ...prev, [resizingRef.current.key]: next }));
      };
      const onUp = () => {
        resizingRef.current = null;
        document.removeEventListener("mousemove", onMove);
        document.removeEventListener("mouseup", onUp);
        setColWidths((prev) => {
          try {
            localStorage.setItem(
              "reporte-mov-stock-col-widths",
              JSON.stringify(prev),
            );
          } catch {
            // ignore
          }
          return prev;
        });
      };
      document.addEventListener("mousemove", onMove);
      document.addEventListener("mouseup", onUp);
    },
    [colWidths],
  );

  const resizeHandleSx = {
    position: "absolute",
    top: "20%",
    right: 0,
    width: 8,
    height: "60%",
    cursor: "col-resize",
    userSelect: "none",
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    "&::after": {
      content: '""',
      display: "block",
      width: "2px",
      height: "100%",
      bgcolor: "divider",
      transition: "background-color 120ms ease",
    },
    "&:hover::after": { bgcolor: "primary.main", width: "3px" },
    "&:active::after": { bgcolor: "primary.main", width: "3px" },
  };

  const headerCellSx = (key) => ({
    fontWeight: 600,
    position: "relative",
    width: colWidths[key],
    minWidth: colWidths[key],
    maxWidth: colWidths[key],
  });

  const bodyCellSx = (key) => ({
    width: colWidths[key],
    minWidth: colWidths[key],
    maxWidth: colWidths[key],
    overflow: "hidden",
    textOverflow: "ellipsis",
  });

  // Debounce search
  const handleSearchChange = useCallback((e) => {
    setSearch(e.target.value);
    clearTimeout(window._stockSearchTimer);
    window._stockSearchTimer = setTimeout(() => {
      setSearchDebounced(e.target.value);
      setPage(1);
    }, 400);
  }, []);

  // Referenciales
  const { data: referenciales } = useReferencialesQuery();
  const tiposMovimiento = referenciales?.tipo_movimiento_inventario || [];

  // Sucursales
  const { data: sucursalesData } = useQuery({
    queryKey: ["sucursales-reporte-stock"],
    queryFn: () => getSucursales(1, 100),
    staleTime: 5 * 60 * 1000,
  });
  const sucursales = sucursalesData?.data || sucursalesData || [];

  // Depósitos (filtrados por sucursal si se selecciona)
  const { data: depositosData } = useQuery({
    queryKey: ["depositos-reporte-stock", sucursalId],
    queryFn: () => getDepositos(sucursalId || undefined),
    staleTime: 5 * 60 * 1000,
  });
  const depositos = depositosData?.data || depositosData || [];

  // Búsqueda de productos para autocomplete
  const { data: productosSearch } = useQuery({
    queryKey: ["productos-search-reporte", productoSearch],
    queryFn: () => buscarProductos(productoSearch, 20),
    enabled: productoSearch.length >= 2,
    staleTime: 30 * 1000,
  });
  const productosOptions = productosSearch?.data || productosSearch || [];

  // Query principal
  const queryParams = {
    page,
    limit,
    ...(productoId && { producto_id: productoId }),
    ...(depositoId && { deposito_id: depositoId }),
    ...(sucursalId && { sucursal_id: sucursalId }),
    ...(tipoMovimientoId && { tipo_movimiento_id: tipoMovimientoId }),
    ...(searchDebounced && { search: searchDebounced }),
    ...(desde && { fecha_desde: new Date(desde).toISOString() }),
    ...(hasta && {
      fecha_hasta: new Date(hasta + "T23:59:59").toISOString(),
    }),
  };

  const { data: response, isLoading } = useQuery({
    queryKey: ["reporte-movimientos-stock", queryParams],
    queryFn: () => getMovimientos(queryParams),
  });

  const movimientos = useMemo(() => response?.data || [], [response]);
  const totalItems = response?.total || 0;
  const totalPages = Math.max(1, Math.ceil(totalItems / limit));

  // KPIs: totales de todo lo filtrado, que calcula el backend. Antes se sumaban
  // solo los 20 movimientos de la página ("Total entradas 11" sobre 2.257).
  // Si el backend todavía no los manda, se cae al cálculo por página.
  const kpis = useMemo(() => {
    const t = response?.totales;
    if (t) {
      return { totalEntradas: t.entradas, totalSalidas: t.salidas, neto: t.neto, total: totalItems };
    }
    const entradas = movimientos.reduce((acc, m) => acc + (cantidadEntrada(m) ?? 0), 0);
    const salidas = movimientos.reduce((acc, m) => acc + (cantidadSalida(m) ?? 0), 0);
    return { totalEntradas: entradas, totalSalidas: salidas, neto: entradas - salidas, total: totalItems };
  }, [response, movimientos, totalItems]);

  // Export
  const handleExport = async (formato) => {
    try {
      // El backend devuelve como máximo 100 por página: antes se pedían 10.000 de
      // una vez y el archivo traía solo los primeros 100. Se recorren las páginas.
      const todos = [];
      let pagina = 1;
      let ultima = 1;
      do {
        const r = await getMovimientos({ ...queryParams, page: pagina, limit: 100 });
        todos.push(...(r?.data || []));
        ultima = r?.lastPage || 1;
        pagina += 1;
      } while (pagina <= ultima);
      const tabla = { ...armarTabla(todos), archivo: `movimientos_stock_${getHoy()}` };
      if (formato === "xlsx") descargarExcel({ ...tabla, hoja: "Movimientos de stock" });
      else descargarCSV(tabla);
      toast.success("Reporte exportado correctamente");
    } catch {
      toast.error("Error al exportar");
    }
  };

  const getTipoColor = (tipo) => {
    if (!tipo) return "default";
    if (tipo.afecta_stock > 0) return "success";
    if (tipo.afecta_stock < 0) return "error";
    return "default";
  };

  if (!canRead || !canReadMovimientos) {
    return (
      <AccesoRestringido mensaje="No tienes permisos para ver este reporte." />
    );
  }

  return (
    <Box sx={{ width: "100%", mx: "auto", p: { xs: 2, md: 3 } }}>
      {/* ── Header ── */}
      <Box
        sx={{
          display: "flex",
          justifyContent: "space-between",
          alignItems: "flex-start",
          mb: 1,
          flexWrap: "wrap",
          gap: 1,
        }}
      >
        <Box sx={{ display: "flex", alignItems: "center", gap: 1.5 }}>
          <Button
            size="small"
            onClick={() => navigate("/reportes")}
            sx={{ minWidth: 32, p: 0.5 }}
          >
            <Icon icon="lucide:arrow-left" width={20} />
          </Button>
          <Box>
            <Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
              <Icon icon="lucide:package-search" width={22} />
              <Typography variant="h6" fontWeight={700}>
                Movimientos de Stock
              </Typography>
            </Box>
            <Typography variant="caption" color="text.secondary">
              Reporte detallado de entradas y salidas de inventario
            </Typography>
          </Box>
        </Box>
        <ExportarMenuButton onExcel={() => handleExport("xlsx")} onCSV={() => handleExport("csv")} />
      </Box>

      {/* Breadcrumb */}
      <Typography variant="caption" color="text.secondary" sx={{ mb: 2, display: "block" }}>
        <span
          style={{ cursor: "pointer" }}
          onClick={() => navigate("/reportes")}
        >
          Reportes
        </span>
        {" > "}Movimientos de Stock
      </Typography>

      {/* ── Filtros ── */}
      <Paper variant="outlined" sx={{ p: 2, mb: 2, borderRadius: 2 }}>
        {/* Filtros cortos: la grilla reparte por el ancho de la tarjeta (mínimo
            170px por campo, lo que necesita una fecha dd/mm/aaaa completa). */}
        <Box
          sx={{
            display: "grid",
            gap: 1.5,
            alignItems: "center",
            gridTemplateColumns: "repeat(auto-fill, minmax(170px, 1fr))",
          }}
        >
          {/* Sucursal */}
          <FormControl size="small" fullWidth>
            <InputLabel>Sucursal</InputLabel>
            <Select
              value={sucursalId}
              label="Sucursal"
              onChange={(e) => {
                setSucursalId(e.target.value);
                setDepositoId("");
                setPage(1);
              }}
            >
              <MenuItem value="">Todas</MenuItem>
              {sucursales.map((s) => (
                <MenuItem key={s.id} value={s.id}>
                  {s.nombre || s.descripcion}
                </MenuItem>
              ))}
            </Select>
          </FormControl>

          {/* Depósito */}
          <FormControl size="small" fullWidth>
            <InputLabel>Depósito</InputLabel>
            <Select
              value={depositoId}
              label="Depósito"
              onChange={(e) => {
                setDepositoId(e.target.value);
                setPage(1);
              }}
            >
              <MenuItem value="">Todos</MenuItem>
              {depositos.map((d) => (
                <MenuItem key={d.id} value={d.id}>
                  {d.descripcion}
                </MenuItem>
              ))}
            </Select>
          </FormControl>

          {/* Tipo Movimiento */}
          <FormControl size="small" fullWidth>
            <InputLabel>Tipo</InputLabel>
            <Select
              value={tipoMovimientoId}
              label="Tipo"
              onChange={(e) => {
                setTipoMovimientoId(e.target.value);
                setPage(1);
              }}
            >
              <MenuItem value="">Todos los tipos</MenuItem>
              {tiposMovimiento.map((t) => (
                <MenuItem key={t.id} value={t.id}>
                  {t.descripcion}
                </MenuItem>
              ))}
            </Select>
          </FormControl>

          {/* Fechas */}
          <TextField
            size="small"
            type="date"
            label="Desde"
            value={desde}
            onChange={(e) => {
              setDesde(e.target.value);
              setPage(1);
            }}
            InputLabelProps={{ shrink: true }}
            fullWidth
          />
          <TextField
            size="small"
            type="date"
            label="Hasta"
            value={hasta}
            onChange={(e) => {
              setHasta(e.target.value);
              setPage(1);
            }}
            InputLabelProps={{ shrink: true }}
            fullWidth
          />
        </Box>
        {/* Producto en su propia fila y bien ancho: las descripciones largas se
            leen completas. El buscador de texto lo acompaña y baja si no entra. */}
        <Box sx={{ display: "flex", gap: 1.5, flexWrap: "wrap", mt: 1.5 }}>
          {/* Producto (Autocomplete) */}
          <Autocomplete
            size="small"
            sx={{ flex: "2 1 360px", minWidth: 0 }}
            options={productosOptions}
            getOptionLabel={(opt) =>
              opt?.descripcion
                ? `${opt.descripcion}${opt.cod_producto ? ` (${opt.cod_producto})` : ""}`
                : ""
            }
            isOptionEqualToValue={(opt, val) => opt?.id === val?.id}
            onInputChange={(_, val) => setProductoSearch(val)}
            onChange={(_, val) => {
              setProductoId(val?.id || "");
              setPage(1);
            }}
            renderInput={(params) => (
              <TextField {...params} label="Producto" />
            )}
            noOptionsText={
              productoSearch.length < 2
                ? "Escribí al menos 2 caracteres"
                : "Sin resultados"
            }
          />

          {/* Buscador de texto (documento/observaciones) */}
          <TextField
            size="small"
            placeholder="Buscar documento u observaciones..."
            value={search}
            onChange={handleSearchChange}
            sx={{ flex: "1 1 260px", minWidth: 0 }}
            InputProps={{
              startAdornment: (
                <InputAdornment position="start">
                  <Icon icon="lucide:search" width={16} />
                </InputAdornment>
              ),
            }}
          />

        </Box>
      </Paper>

      {/* ── KPIs ── */}
      <Box
        sx={{
          display: "grid",
          gridTemplateColumns: { xs: "repeat(2, 1fr)", md: "repeat(4, 1fr)" },
          gap: 2,
          mb: 2,
        }}
      >
        {[
          {
            icon: "lucide:arrow-down-circle",
            label: "Total Entradas",
            value: formatNum(kpis.totalEntradas),
            color: "success.main",
          },
          {
            icon: "lucide:arrow-up-circle",
            label: "Total Salidas",
            value: formatNum(kpis.totalSalidas),
            color: "error.main",
          },
          {
            icon: "lucide:scale",
            label: "Neto",
            value: formatNum(kpis.neto),
            color: "info.main",
          },
          {
            icon: "lucide:hash",
            label: "Movimientos",
            value: formatNum(kpis.total),
            color: "primary.main",
          },
        ].map((kpi, i) => (
          <Card key={i} variant="outlined" sx={{ borderRadius: 2 }}>
            <CardContent
              sx={{
                p: "14px !important",
                display: "flex",
                alignItems: "center",
                gap: 1.5,
              }}
            >
              <Icon icon={kpi.icon} width={20} style={{ opacity: 0.6 }} />
              <Box>
                <Typography variant="caption" color="text.secondary">
                  {kpi.label}
                </Typography>
                <Typography variant="h6" fontWeight={700} color={kpi.color}>
                  {kpi.value}
                </Typography>
              </Box>
            </CardContent>
          </Card>
        ))}
      </Box>

      {/* ── Tabla ── */}
      {isLoading ? (
        <Box sx={{ display: "flex", flexDirection: "column", gap: 1 }}>
          {[...Array(10)].map((_, i) => (
            <Skeleton key={i} variant="rounded" height={44} />
          ))}
        </Box>
      ) : movimientos.length === 0 ? (
        <Paper
          variant="outlined"
          sx={{ p: 6, textAlign: "center", borderRadius: 2 }}
        >
          <Icon
            icon="lucide:package-x"
            width={48}
            style={{ opacity: 0.3, marginBottom: 12 }}
          />
          <Typography color="text.secondary">
            No se encontraron movimientos con los filtros aplicados
          </Typography>
        </Paper>
      ) : isMobile ? (
        <Box sx={{ display: "flex", flexDirection: "column", gap: 1 }}>
          {movimientos.map((mov) => (
            <Card key={mov.id} variant="outlined" sx={{ borderRadius: 2 }}>
              <CardContent sx={{ p: "12px !important" }}>
                <Box
                  sx={{
                    display: "flex",
                    justifyContent: "space-between",
                    mb: 0.5,
                  }}
                >
                  <Typography variant="body2" fontWeight={600} noWrap>
                    {mov.producto?.descripcion || "-"}
                  </Typography>
                  <Chip
                    label={mov.tipo_movimiento?.descripcion || "-"}
                    color={getTipoColor(mov.tipo_movimiento)}
                    size="small"
                    sx={{ fontSize: "0.68rem", height: 20 }}
                  />
                </Box>
                <Box sx={{ display: "flex", gap: 2, flexWrap: "wrap" }}>
                  <Typography variant="caption" color="text.secondary">
                    {formatFecha(mov.created_at)}
                  </Typography>
                  <Typography
                    variant="caption"
                    fontWeight={600}
                    color={efectoStock(mov) > 0 ? "success.main" : efectoStock(mov) < 0 ? "error.main" : "text.secondary"}
                  >
                    {efectoStock(mov) > 0
                      ? `Entrada: ${formatNum(cantidadEntrada(mov))}`
                      : efectoStock(mov) < 0
                        ? `Salida: ${formatNum(cantidadSalida(mov))}`
                        : `No mueve stock: ${formatNum(mov.cantidad)}`}
                  </Typography>
                  <Typography variant="caption" color="text.secondary">
                    {mov.deposito_origen?.descripcion || ""}
                  </Typography>
                </Box>
                {mov.documento_origen && (
                  <Typography
                    variant="caption"
                    color="text.secondary"
                    sx={{ display: "block", mt: 0.25 }}
                  >
                    {documentoOrigen(mov.documento_origen)}
                  </Typography>
                )}
              </CardContent>
            </Card>
          ))}
        </Box>
      ) : (
        <>
        <Typography
          variant="caption"
          color="text.secondary"
          sx={{ display: "flex", alignItems: "center", gap: 0.5, mb: 0.5 }}
        >
          <Icon icon="lucide:move-horizontal" width={14} />
          Arrastrá el borde derecho de cada columna para ajustar su ancho
        </Typography>
        <TableContainer
          component={Paper}
          variant="outlined"
          sx={{ borderRadius: 2 }}
        >
          <Table size="small" sx={{ tableLayout: "fixed" }}>
            <TableHead>
              <TableRow>
                <TableCell sx={headerCellSx("fecha")}>
                  Fecha
                  <Box sx={resizeHandleSx} onMouseDown={handleResizeStart("fecha")} />
                </TableCell>
                <TableCell sx={headerCellSx("producto")}>
                  Producto
                  <Box sx={resizeHandleSx} onMouseDown={handleResizeStart("producto")} />
                </TableCell>
                <TableCell sx={headerCellSx("deposito")}>
                  Depósito
                  <Box sx={resizeHandleSx} onMouseDown={handleResizeStart("deposito")} />
                </TableCell>
                <TableCell sx={headerCellSx("sucursal")}>
                  Sucursal
                  <Box sx={resizeHandleSx} onMouseDown={handleResizeStart("sucursal")} />
                </TableCell>
                <TableCell sx={headerCellSx("tipo")}>
                  Tipo
                  <Box sx={resizeHandleSx} onMouseDown={handleResizeStart("tipo")} />
                </TableCell>
                <TableCell sx={{ ...headerCellSx("entrada"), textAlign: "right" }} align="right">
                  Entrada
                  <Box sx={resizeHandleSx} onMouseDown={handleResizeStart("entrada")} />
                </TableCell>
                <TableCell sx={{ ...headerCellSx("salida"), textAlign: "right" }} align="right">
                  Salida
                  <Box sx={resizeHandleSx} onMouseDown={handleResizeStart("salida")} />
                </TableCell>
                <TableCell sx={headerCellSx("documento")}>
                  Documento
                  <Box sx={resizeHandleSx} onMouseDown={handleResizeStart("documento")} />
                </TableCell>
                <TableCell sx={headerCellSx("observaciones")}>
                  Observaciones
                  <Box sx={resizeHandleSx} onMouseDown={handleResizeStart("observaciones")} />
                </TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {movimientos.map((mov) => (
                <TableRow
                  key={mov.id}
                  hover
                  sx={{ "&:last-child td": { borderBottom: 0 } }}
                >
                  <TableCell sx={{ ...bodyCellSx("fecha"), whiteSpace: "nowrap" }}>
                    {formatFecha(mov.created_at)}
                  </TableCell>
                  <TableCell sx={bodyCellSx("producto")}>
                    <Typography variant="body2" fontWeight={500} noWrap title={mov.producto?.descripcion || ""}>
                      {mov.producto?.descripcion || "-"}
                    </Typography>
                    {mov.producto?.cod_producto && (
                      <Typography variant="caption" color="text.secondary">
                        {mov.producto.cod_producto}
                      </Typography>
                    )}
                  </TableCell>
                  <TableCell sx={bodyCellSx("deposito")}>
                    <Typography variant="body2" noWrap title={mov.deposito_origen?.descripcion || ""}>
                      {mov.deposito_origen?.descripcion || "-"}
                    </Typography>
                  </TableCell>
                  <TableCell sx={bodyCellSx("sucursal")}>
                    <Typography
                      variant="body2"
                      noWrap
                      title={mov.deposito_origen?.sucursal?.descripcion || mov.deposito_origen?.sucursal?.nombre || ""}
                    >
                      {mov.deposito_origen?.sucursal?.descripcion || mov.deposito_origen?.sucursal?.nombre || "-"}
                    </Typography>
                  </TableCell>
                  <TableCell sx={bodyCellSx("tipo")}>
                    <Chip
                      label={mov.tipo_movimiento?.descripcion || "-"}
                      color={getTipoColor(mov.tipo_movimiento)}
                      size="small"
                      sx={{ fontSize: "0.75rem", maxWidth: "100%" }}
                    />
                    {efectoStock(mov) === 0 && (
                      <Typography variant="caption" color="text.secondary" sx={{ display: "block" }}>
                        no mueve stock: {formatNum(mov.cantidad)}
                      </Typography>
                    )}
                  </TableCell>
                  <TableCell sx={bodyCellSx("entrada")} align="right">
                    <Typography variant="body2" fontWeight={600} color="success.main">
                      {cantidadEntrada(mov) != null ? formatNum(cantidadEntrada(mov)) : ""}
                    </Typography>
                  </TableCell>
                  <TableCell sx={bodyCellSx("salida")} align="right">
                    <Typography variant="body2" fontWeight={600} color="error.main">
                      {cantidadSalida(mov) != null ? formatNum(cantidadSalida(mov)) : ""}
                    </Typography>
                  </TableCell>
                  <TableCell sx={bodyCellSx("documento")}>
                    <Typography variant="body2" noWrap title={documentoOrigen(mov.documento_origen)}>
                      {documentoOrigen(mov.documento_origen) || "-"}
                    </Typography>
                  </TableCell>
                  <TableCell sx={bodyCellSx("observaciones")}>
                    <Typography
                      variant="body2"
                      color="text.secondary"
                      noWrap
                      title={mov.observaciones || ""}
                    >
                      {mov.observaciones || "-"}
                    </Typography>
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </TableContainer>
        </>
      )}

      {/* ── Paginación ── */}
      {totalItems > 0 && (
        <Box
          sx={{
            display: "flex",
            justifyContent: "space-between",
            alignItems: "center",
            mt: 2,
            flexWrap: "wrap",
            gap: 1,
          }}
        >
          <Typography variant="caption" color="text.secondary">
            Mostrando {(page - 1) * limit + 1}-
            {Math.min(page * limit, totalItems)} de {totalItems}
          </Typography>
          <Pagination
            count={totalPages}
            page={page}
            onChange={(_, p) => setPage(p)}
            size="small"
            color="primary"
          />
        </Box>
      )}
    </Box>
  );
}
