import { Icon } from "@iconify/react";
import {
  Alert,
  Box,
  Button,
  Card,
  CardContent,
  Chip,
  Collapse,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  FormControl,
  Grid,
  IconButton,
  InputAdornment,
  InputLabel,
  MenuItem,
  Paper,
  Select,
  Tab,
  Tabs,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  TextField,
  Tooltip,
  Typography,
  useMediaQuery,
  useTheme,
  Skeleton,
} from "@mui/material";
import { useEffect, useMemo, useState } from "react";
import { toast } from "sonner";
import styled from "styled-components";
import { getTiposGasto } from "../../../api/gastos.service";
import {
  aprobarRequisicion,
  cancelarRequisicion,
  createRequisicion,
  enviarAprobacionRequisicion,
  getRequisicion,
  getRequisiciones,
  rechazarRequisicion,
  updateRequisicion,
} from "../../../api/requisiciones.service";
import { getSucursales } from "../../../api/sucursales.service";
import { formatMoney } from "../../../utils/formatMoney";
import { ComprasProductSearch } from "./ComprasProductSearch";
import { RequisicionItemsTable } from "./RequisicionItemsTable";
import { CrearOCDesdeRequisicionDialog } from "./CrearOCDesdeRequisicionDialog";
import { CrearGastoDesdeRequisicionDialog } from "./CrearGastoDesdeRequisicionDialog";
import { ConfirmDialog } from "../../ui/ConfirmDialog";
import { PromptDialog } from "../../ui/PromptDialog";
import { usePermission } from "../../../hooks/usePermission";
import { DetailNumberButton, TablePaginationBar } from "../../_standards";
import { fmtFechaCalendario, hoyISO, rangoFiltroRapido } from "../../../utils/fecha";

const parseNumber = (value, fallback = 0) => {
  const parsed = Number(value);
  return Number.isFinite(parsed) ? parsed : fallback;
};

const round = (value, decimals = 2) => {
  const factor = 10 ** decimals;
  return Math.round((parseNumber(value, 0) + Number.EPSILON) * factor) / factor;
};

const formatDate = (value) => {
  if (!value) return "-";
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return "-";
  return date.toLocaleDateString("es-PY");
};

const formatDateTime = (value) => {
  if (!value) return "-";
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return "-";
  return date.toLocaleString("es-PY");
};

const formatUserName = (user) => {
  if (!user) return "Sistema";
  const fullName = `${user.nombres || ""} ${user.apellidos || ""}`.trim();
  if (fullName) return fullName;
  if (user.username) return user.username;
  return "Sistema";
};



const KPI_CARD_SX = {
  width: "100%",
  height: { xs: 74, sm: 96 },
};

const KPI_CARD_CONTENT_SX = {
  height: "100%",
  display: "flex",
  flexDirection: "column",
  justifyContent: "space-between",
  p: { xs: 0.75, sm: 1.5 },
  "&:last-child": { pb: { xs: 0.75, sm: 1.5 } },
  "& .MuiTypography-h5, & .MuiTypography-h6": {
    whiteSpace: "nowrap",
    overflow: "hidden",
    textOverflow: "ellipsis",
    lineHeight: 1.15,
    fontSize: "clamp(1.2rem, 3.8vw, 1.7rem)",
  },
};

const KPI_CAPTION_SX = {
  display: "flex",
  alignItems: "center",
  gap: 0.35,
  fontSize: { xs: "0.52rem", sm: "0.7rem" },
  minHeight: { xs: 14, sm: 20 },
  whiteSpace: "nowrap",
  overflow: "hidden",
  textOverflow: "ellipsis",
};

const KPI_GRID_CONTAINER_SX = {
  display: "grid",
  gridTemplateColumns: { xs: "repeat(2, minmax(0, 1fr))", sm: "repeat(6, minmax(0, 1fr))" },
  gap: { xs: 1, sm: 2 },
  mb: { xs: 2, sm: 3 },
};

const KPI_GRID_ITEM_SX = {
  minWidth: 0,
};

let itemKeyCounter = 0;
const nextKey = () => `req-item-${++itemKeyCounter}-${Date.now()}`;
const UUID_REGEX = /\b[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\b/gi;

const sanitizeTechnicalIds = (message) =>
  String(message || "").replace(UUID_REGEX, "[referencia interna]");

const normalizeUserErrorMessage = (message) => {
  const clean = sanitizeTechnicalIds(message);
  if (/nivel 1 activo de aprobación/i.test(clean)) {
    if (/solución:/i.test(clean)) return clean;
    return `${clean} Solución: configurá el nivel 1 de aprobación para origen compra en Configuración > Compras > Aprobaciones de Requisiciones.`;
  }
  if (/no hay niveles de aprobación configurados/i.test(clean)) {
    if (/solución:/i.test(clean)) return clean;
    return `${clean} Solución: configurá niveles de aprobación por monto y perfil en Configuración > Compras > Aprobaciones de Requisiciones.`;
  }
  return clean;
};

const buildEmptyItem = () => ({
  _key: nextKey(),
  producto_id: "",
  tipo_gasto_id: "",
  producto_codigo: "",
  producto_descripcion: "",
  descripcion: "",
  cantidad_solicitada: 1,
});

const buildEmptyForm = () => ({
  cabecera: {
    origen_tipo: "compra",
    sucursal_id: "",
    fecha_requisicion: hoyISO(),
    descripcion: "",
  },
  items: [],
});

export function RequisicionesTab() {
  const theme = useTheme();
  const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
  const { canEdit: canComprasEdit } = usePermission("COMPRAS");
  const canViewAmounts = canComprasEdit;
  const [loading, setLoading] = useState(false);
  const [saving, setSaving] = useState(false);
  const [showForm, setShowForm] = useState(false);

  const [editingId, setEditingId] = useState(null);
  const [data, setData] = useState([]);
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(1);
  const [limit, setLimit] = useState(20);
  const [estado, setEstado] = useState("");
  const [origen, setOrigen] = useState("");
  const [search, setSearch] = useState("");
  // El chip arranca en "Esta semana": las fechas se inicializan con él, porque
  // marcarlo sin setear el rango dejaba la lista mostrando todo.
  const [fechaDesde, setFechaDesde] = useState(() => rangoFiltroRapido("semana").desde);
  const [fechaHasta, setFechaHasta] = useState(() => rangoFiltroRapido("semana").hasta);
  const [filtroRapido, setFiltroRapido] = useState("semana");
  const [showFilters, setShowFilters] = useState(false);
  const [sucursales, setSucursales] = useState([]);
  const [tiposGasto, setTiposGasto] = useState([]);
  const [form, setForm] = useState(buildEmptyForm());
  const [dialogOC, setDialogOC] = useState(null);
  const [dialogGasto, setDialogGasto] = useState(null);
  const [confirmGuardarOpen, setConfirmGuardarOpen] = useState(false);
  const [pendingGuardarPayload, setPendingGuardarPayload] = useState(null);
  const [validationMessages, setValidationMessages] = useState([]);
  const [promptAction, setPromptAction] = useState(null);
  const [promptLoading, setPromptLoading] = useState(false);
  const [detalleDialog, setDetalleDialog] = useState({
    open: false,
    loading: false,
    numero: "",
    requisicion: null,
  });
  const [detalleTab, setDetalleTab] = useState("general");

  const notifyError = (error, fallback) => {
    const apiMsg = error?.response?.data?.message;
    const messages = (Array.isArray(apiMsg) ? apiMsg : [apiMsg || fallback]).map(normalizeUserErrorMessage);
    toast.error(messages[0]);
  };

  const notifySuccess = (message) => {
    toast.success(message);
  };

  const totalPages = useMemo(
    () => Math.max(1, Math.ceil(parseNumber(total, 0) / parseNumber(limit, 20))),
    [total, limit],
  );
  const filtrosActivos = useMemo(
    () => [search, estado, origen, fechaDesde, fechaHasta].filter(Boolean).length,
    [search, estado, origen, fechaDesde, fechaHasta],
  );

  // KPIs sobre el filtro completo (no la página): vienen del backend en load().
  const [stats, setStats] = useState({
    total: 0,
    borrador: 0,
    pendiente_aprobacion: 0,
    aprobada: 0,
    ejecutada_parcial: 0,
    ejecutada_total: 0,
    cancelada: 0,
    rechazada: 0,
  });

  const actionIconSx = (colorKey = "text.secondary") => ({
    width: 30,
    height: 30,
    border: "1px solid",
    borderColor: "divider",
    borderRadius: 1,
    color: colorKey,
    "&:hover": {
      borderColor: colorKey,
      backgroundColor: "action.hover",
    },
    "&.Mui-disabled": {
      opacity: 0.45,
    },
  });

  const load = async () => {
    try {
      setLoading(true);
      const resp = await getRequisiciones({
        page,
        limit,
        estado: estado || undefined,
        origen_tipo: origen || undefined,
        search: search || undefined,
        fecha_desde: fechaDesde || undefined,
        fecha_hasta: fechaHasta || undefined,
      });
      setData(resp?.data || []);
      setTotal(resp?.total || 0);
      setStats(
        resp?.stats || {
          total: resp?.total || 0,
          borrador: 0,
          pendiente_aprobacion: 0,
          aprobada: 0,
          ejecutada_parcial: 0,
          ejecutada_total: 0,
          cancelada: 0,
          rechazada: 0,
        },
      );
    } catch (error) {
      console.error(error);
      toast.error("No se pudieron cargar requisiciones");
    } finally {
      setLoading(false);
    }
  };

  const loadLookups = async () => {
    try {
      const [sucResp, tiposGastoResp] = await Promise.all([
        getSucursales(1, 200),
        getTiposGasto().catch(() => []),
      ]);
      const sucList = Array.isArray(sucResp) ? sucResp : sucResp?.data || [];
      const tgList = Array.isArray(tiposGastoResp)
        ? tiposGastoResp
        : tiposGastoResp?.data || [];
      setSucursales(sucList);
      setTiposGasto(tgList.filter((tg) => tg?.activo !== false));
      setForm((prev) => ({
        ...prev,
        cabecera: {
          ...prev.cabecera,
          sucursal_id: prev.cabecera.sucursal_id || sucList?.[0]?.id || "",
        },
      }));
    } catch (error) {
      console.error(error);
      toast.error("No se pudieron cargar catálogos de requisiciones");
    }
  };

  useEffect(() => {
    load();
  }, [page, limit, estado, origen, fechaDesde, fechaHasta]);

  useEffect(() => {
    loadLookups();
  }, []);

  const resetForm = () => {
    const next = buildEmptyForm();
    next.cabecera.sucursal_id = sucursales?.[0]?.id || "";
    setForm(next);
    setEditingId(null);
  };

  const aplicarFiltroRapido = (tipo) => {
    const { desde, hasta } = rangoFiltroRapido(tipo);
    setFiltroRapido(tipo);
    setPage(1);
    setFechaDesde(desde);
    setFechaHasta(hasta);
  };

  const limpiarFiltros = () => {
    setSearch("");
    setEstado("");
    setOrigen("");
    setFechaDesde("");
    setFechaHasta("");
    setFiltroRapido("");
    setShowFilters(false);
    setPage(1);
  };

  const addItemManual = () => {
    setForm((prev) => ({ ...prev, items: [...prev.items, buildEmptyItem()] }));
  };

  const addItemFromSearch = (raw) => {
    setForm((prev) => ({
      ...prev,
      items: [
        ...prev.items,
        {
          ...buildEmptyItem(),
          producto_id: raw?.producto_id || "",
          producto_codigo: raw?.codigo || raw?.cod_producto || "",
          producto_descripcion: raw?.descripcion || "",
          descripcion: raw?.descripcion || "",
          cantidad_solicitada: parseNumber(raw?.cantidad, 1),
        },
      ],
    }));
  };

  const removeItem = (index) => {
    setForm((prev) => ({
      ...prev,
      items: prev.items.filter((_, idx) => idx !== index),
    }));
  };

  const updateCabecera = (key, value) => {
    setForm((prev) => ({
      ...prev,
      cabecera: {
        ...prev.cabecera,
        [key]: value,
      },
    }));
  };

  const updateItem = (index, key, value) => {
    setForm((prev) => {
      const next = [...prev.items];
      next[index] = { ...next[index], [key]: value };
      return { ...prev, items: next };
    });
  };

  const failValidation = (messages) => {
    const list = Array.isArray(messages) ? messages : [messages];
    setValidationMessages(list);
    if (list[0]) toast.warning(list[0]);
  };

  const handleGuardar = () => {
    setValidationMessages([]);
    const errores = [];
    if (!form.cabecera.origen_tipo) errores.push("Seleccioná un origen (Compra o Gasto)");
    if (!form.cabecera.sucursal_id) errores.push("Seleccioná una sucursal");
    if (!form.cabecera.fecha_requisicion) errores.push("Indicá la fecha de la requisición");
    if (form.items.length === 0) errores.push("Agregá al menos un ítem");
    form.items.forEach((it, idx) => {
      const linea = idx + 1;
      if (parseNumber(it.cantidad_solicitada, 0) <= 0)
        errores.push(`Línea ${linea}: la cantidad debe ser mayor a 0`);
      const descripcionVacia =
        !String(it.descripcion || "").trim() && !it.producto_id;
      if (descripcionVacia)
        errores.push(`Línea ${linea}: indicá un producto o una descripción`);
    });

    if (errores.length) {
      failValidation(errores);
      return;
    }

    const payload = {
      cabecera: {
        origen_tipo: form.cabecera.origen_tipo,
        sucursal_id: form.cabecera.sucursal_id || undefined,
        fecha_requisicion: form.cabecera.fecha_requisicion || undefined,
        descripcion: form.cabecera.descripcion || undefined,
      },
      items: form.items.map((it) => {
        const descripcion = String(it.descripcion || "").trim();
        const fallbackDesc = it.producto_obj?.descripcion || "";
        return {
          producto_id: it.producto_id || undefined,
          tipo_gasto_id:
            form.cabecera.origen_tipo === "gasto" && it.tipo_gasto_id
              ? it.tipo_gasto_id
              : undefined,
          descripcion: (descripcion || fallbackDesc) || undefined,
          cantidad_solicitada: round(parseNumber(it.cantidad_solicitada, 0), 4),
        };
      }),
    };

    setPendingGuardarPayload(payload);
    setConfirmGuardarOpen(true);
  };

  const confirmGuardar = async () => {
    if (!pendingGuardarPayload) return;
    try {
      setSaving(true);
      if (editingId) {
        await updateRequisicion(editingId, pendingGuardarPayload);
        toast.success("Requisición actualizada");
      } else {
        await createRequisicion(pendingGuardarPayload);
        toast.success("Requisición creada");
      }
      await load();
      setShowForm(false);
      resetForm();
      setValidationMessages([]);
      setConfirmGuardarOpen(false);
      setPendingGuardarPayload(null);
    } catch (error) {
      console.error(error);
      const apiMsg = error?.response?.data?.message;
      const messages = (Array.isArray(apiMsg) ? apiMsg : [apiMsg || "No se pudo guardar la requisición"]).map(
        normalizeUserErrorMessage,
      );
      setValidationMessages(messages);
      setConfirmGuardarOpen(false);
      toast.error(messages[0]);
    } finally {
      setSaving(false);
    }
  };

  const handleEnviarAprobacion = async (req) => {
    try {
      await enviarAprobacionRequisicion(req.id);
      notifySuccess(`Requisición ${req.numero_requisicion || ""} enviada a aprobación`);
      await load();
    } catch (error) {
      console.error(error);
      notifyError(error, "No se pudo enviar a aprobación", "enviar a aprobación");
    }
  };

  const handleAprobar = (req) => {
    setPromptAction({
      kind: "aprobar",
      req,
      title: `Aprobar requisición ${req.numero_requisicion || ""}`,
      message: "Vas a aprobar esta requisición. Podés agregar un comentario opcional.",
      label: "Comentario de aprobación",
      placeholder: "Ej.: Aprobado para continuar con la compra.",
      required: false,
      confirmText: "Aprobar",
      confirmColor: "success",
    });
  };

  const handleRechazar = (req) => {
    setPromptAction({
      kind: "rechazar",
      req,
      title: `Rechazar requisición ${req.numero_requisicion || ""}`,
      message: "El motivo se enviará al solicitante para que pueda corregir y reenviar.",
      label: "Motivo de rechazo",
      placeholder: "Ej.: Falta justificación del centro de costo.",
      required: true,
      confirmText: "Rechazar",
      confirmColor: "error",
    });
  };

  const handleCancelar = (req) => {
    setPromptAction({
      kind: "cancelar",
      req,
      title: `Cancelar requisición ${req.numero_requisicion || ""}`,
      message: "La requisición quedará anulada y no podrá continuar el flujo operativo.",
      label: "Motivo de cancelación",
      placeholder: "Ej.: Ya no es necesaria.",
      required: false,
      confirmText: "Cancelar requisición",
      confirmColor: "warning",
    });
  };

  const handleConfirmPrompt = async (value) => {
    if (!promptAction) return;
    const { kind, req } = promptAction;
    try {
      setPromptLoading(true);
      if (kind === "aprobar") {
        await aprobarRequisicion(req.id, value ? { comentario: value } : {});
        notifySuccess("Requisición aprobada");
      } else if (kind === "rechazar") {
        await rechazarRequisicion(req.id, { motivo: value });
        notifySuccess("Requisición rechazada");
      } else if (kind === "cancelar") {
        await cancelarRequisicion(req.id, value ? { motivo: value } : {});
        notifySuccess("Requisición cancelada");
      }
      await load();
      setPromptAction(null);
    } catch (error) {
      console.error(error);
      const ctx =
        kind === "aprobar"
          ? "aprobar requisición"
          : kind === "rechazar"
            ? "rechazar requisición"
            : "cancelar requisición";
      notifyError(error, `No se pudo ${ctx}`, ctx);
      setPromptAction(null);
    } finally {
      setPromptLoading(false);
    }
  };

  const handleCrearOC = (req) => {
    setDialogOC(req);
  };

  const handleCrearGasto = (req) => {
    setDialogGasto(req);
  };

  const handleEditar = async (req) => {
    const estadoReq = String(req?.estado || "").toLowerCase();
    if (estadoReq !== "borrador") {
      toast.warning("Solo se puede editar una requisición en borrador (antes de enviarla a aprobación).");
      return;
    }
    try {
      setSaving(true);
      const detalle = await getRequisicion(req.id);
      const cabecera = {
        origen_tipo: detalle?.origen_tipo || "compra",
        sucursal_id: detalle?.sucursal_id || "",
        fecha_requisicion: detalle?.fecha_requisicion
          ? String(detalle.fecha_requisicion).slice(0, 10)
          : hoyISO(),
        descripcion: detalle?.descripcion || "",
      };
      const items = Array.isArray(detalle?.requisicion_det)
        ? detalle.requisicion_det.map((det) => ({
            _key: nextKey(),
            producto_id: det.producto_id || "",
            tipo_gasto_id: det.tipo_gasto_id || "",
            producto_codigo: det?.productos?.cod_producto || "",
            producto_descripcion: det?.productos?.descripcion || "",
            descripcion: det.descripcion || det?.productos?.descripcion || "",
            cantidad_solicitada: parseNumber(det.cantidad_solicitada, 1),
          }))
        : [];

      setEditingId(detalle?.id || req.id);
      setForm({ cabecera, items });
      setValidationMessages([]);
      setShowForm(true);
    } catch (error) {
      console.error(error);
      toast.error("No se pudo cargar la requisición para edición");
    } finally {
      setSaving(false);
    }
  };

  const closeDetalleDialog = () => {
    setDetalleDialog({
      open: false,
      loading: false,
      numero: "",
      requisicion: null,
    });
    setDetalleTab("general");
  };

  const handleVerDetalle = async (req) => {
    const numero =
      req.numero_requisicion ||
      (req.fecha_requisicion ? `del ${fmtFechaCalendario(req.fecha_requisicion)}` : "sin número");
    setDetalleDialog({
      open: true,
      loading: true,
      numero,
      requisicion: null,
    });
    setDetalleTab("general");
    try {
      const detalle = await getRequisicion(req.id);
      setDetalleDialog((prev) => ({
        ...prev,
        loading: false,
        requisicion: detalle || null,
      }));
    } catch (error) {
      console.error(error);
      toast.error("No se pudo cargar el detalle de la requisición");
      setDetalleDialog((prev) => ({ ...prev, loading: false, requisicion: null }));
    }
  };

  return (
    <Box>
      {showForm ? (
        <Paper variant="outlined" sx={{ p: { xs: 1.5, sm: 2 } }}>
          <Box sx={{ display: "flex", justifyContent: "space-between", alignItems: "center", mb: 2, gap: 1 }}>
            <Typography variant="h6" sx={{ fontWeight: 700 }}>
              {editingId ? "Editar requisición" : "Nueva requisición"}
            </Typography>
            <Button variant="outlined" onClick={() => { setShowForm(false); resetForm(); }}>
              Cerrar
            </Button>
          </Box>

          <Box id="requisiciones-form-cabecera" sx={{ display: "grid", gridTemplateColumns: { xs: "1fr", md: "1fr 1fr 1fr 2fr" }, gap: 1.5, mb: 2 }}>
            <FormControl size="small" fullWidth>
              <InputLabel>Origen</InputLabel>
              <Select
                value={form.cabecera.origen_tipo}
                label="Origen"
                onChange={(e) => updateCabecera("origen_tipo", e.target.value)}
              >
                <MenuItem value="compra">Compra</MenuItem>
                <MenuItem value="gasto">Gasto</MenuItem>
              </Select>
            </FormControl>

            <FormControl size="small" fullWidth>
              <InputLabel>Sucursal</InputLabel>
              <Select
                value={form.cabecera.sucursal_id}
                label="Sucursal"
                onChange={(e) => updateCabecera("sucursal_id", e.target.value)}
              >
                {sucursales.map((sucursal) => (
                  <MenuItem key={sucursal.id} value={sucursal.id}>
                    {sucursal.descripcion || sucursal.codigo || "Sin nombre"}
                  </MenuItem>
                ))}
              </Select>
            </FormControl>

            <TextField
              size="small"
              label="Fecha"
              type="date"
              value={form.cabecera.fecha_requisicion}
              onChange={(e) => updateCabecera("fecha_requisicion", e.target.value)}
              InputLabelProps={{ shrink: true }}
            />

            <TextField
              size="small"
              label="Descripción"
              value={form.cabecera.descripcion}
              onChange={(e) => updateCabecera("descripcion", e.target.value)}
            />
          </Box>

          <Box id="requisiciones-form-items">
          <Typography variant="subtitle2" sx={{ mb: 1.25, fontWeight: 700 }}>
            Ítems de la requisición
          </Typography>

          <ComprasProductSearch
            mode="requisicion"
            onAddItem={addItemFromSearch}
            depositoId={null}
            moneda={null}
            lotesEnabled={false}
          />

          <Box sx={{ mt: 1, mb: 1.5 }}>
            <Button variant="outlined" size="small" startIcon={<Icon icon="mdi:plus" />} onClick={addItemManual}>
              Ítem libre
            </Button>
          </Box>
          {form.cabecera.origen_tipo === "compra" && (
            <Alert severity="info" sx={{ mb: 1.5 }}>
              En compra, los ítems libres se pueden aprobar por necesidad (nivel 1). El costo final se define al generar la OC.
            </Alert>
          )}

          <RequisicionItemsTable
            items={form.items}
            origenTipo={form.cabecera.origen_tipo}
            tiposGasto={tiposGasto}
            monedaCodigo="PYG"
            decimalScale={0}
            hidePricing
            onUpdateItem={updateItem}
            onRemoveItem={removeItem}
          />

          {validationMessages.length > 0 && (
            <Alert severity="error" sx={{ mt: 1.5 }}>
              <Typography variant="body2" sx={{ fontWeight: 600, mb: 0.5 }}>
                No se pudo guardar la requisición:
              </Typography>
              {validationMessages.map((msg, idx) => (
                <Typography key={`req-val-${idx}`} variant="body2">
                  • {msg}
                </Typography>
              ))}
            </Alert>
          )}
          </Box>

          <Box
            id="requisiciones-form-footer"
            sx={{
              display: "flex",
              justifyContent: "flex-end",
              alignItems: "center",
              gap: 1,
              mt: 1.5,
              flexWrap: "wrap",
            }}
          >
            <Button
              variant="contained"
              color="error"
              startIcon={<Icon icon="mdi:trash-can" />}
              disabled={saving}
              onClick={() => {
                resetForm();
                setValidationMessages([]);
              }}
            >
              Limpiar
            </Button>
            <Button
              variant="contained"
              color="primary"
              startIcon={<Icon icon="mdi:check-circle" />}
              disabled={saving}
              onClick={handleGuardar}
            >
              {saving ? "Guardando..." : editingId ? "Actualizar requisición" : "Crear requisición"}
            </Button>
          </Box>
        </Paper>
      ) : (
        <Paper variant="outlined" sx={{ p: { xs: 1.5, sm: 2 } }}>
          <Box sx={{ display: "flex", justifyContent: "flex-end", alignItems: "center", mb: 2 }}>
            <Button
              id="requisiciones-nuevo-btn"
              variant="contained"
              startIcon={<Icon icon="mdi:plus" />}
              onClick={() => {
                resetForm();
                setValidationMessages([]);
                setShowForm(true);
              }}
            >
              Nueva requisición
            </Button>
          </Box>

          <Box id="requisiciones-filtros" sx={{ display: "flex", gap: { xs: 1, sm: 2 }, mb: 2, alignItems: "center", flexWrap: "wrap" }}>
            <Box sx={{ display: "flex", gap: 0.5, flexWrap: "wrap", order: { xs: 2, sm: 1 }, width: { xs: "100%", sm: "auto" } }}>
              {[
                { label: "Hoy", value: "hoy" },
                { label: "Ayer", value: "ayer" },
                { label: "Esta semana", value: "semana" },
                { label: "Este mes", value: "mes" },
                { label: "Mes anterior", value: "mes_anterior" },
              ].map((filtro, idx) => (
                <Chip
                  key={filtro.value}
                  label={filtro.label}
                  onClick={() => aplicarFiltroRapido(filtro.value)}
                  color={filtroRapido === filtro.value ? "primary" : "default"}
                  variant={filtroRapido === filtro.value ? "filled" : "outlined"}
                  size="small"
                  sx={{ display: { xs: idx > 2 ? "none" : "inline-flex", sm: "inline-flex" } }}
                />
              ))}
              {filtrosActivos > 0 && (
                <Chip
                  label={isMobile ? "Limpiar" : "Limpiar filtros"}
                  onClick={limpiarFiltros}
                  onDelete={limpiarFiltros}
                  color="error"
                  variant="outlined"
                  size="small"
                />
              )}
            </Box>
            <TextField
              size="small"
              placeholder="Buscar número o descripción..."
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              onKeyDown={(e) => {
                if (e.key === "Enter") {
                  setPage(1);
                  load();
                }
              }}
              sx={{ flex: 1, minWidth: { xs: 120, sm: 220 }, maxWidth: { xs: "100%", sm: 360 }, order: { xs: 1, sm: 2 } }}
              InputProps={{
                startAdornment: (
                  <InputAdornment position="start">
                    <Icon icon="mdi:magnify" />
                  </InputAdornment>
                ),
                endAdornment: search && (
                  <InputAdornment position="end">
                    <IconButton size="small" onClick={() => setSearch("")}>
                      <Icon icon="mdi:close" width={16} />
                    </IconButton>
                  </InputAdornment>
                ),
              }}
            />
            <Button
              variant={showFilters ? "contained" : "outlined"}
              startIcon={!isMobile && <Icon icon="mdi:filter-variant" />}
              onClick={() => setShowFilters((prev) => !prev)}
              color={filtrosActivos > 0 ? "primary" : "inherit"}
              size="small"
              sx={{ order: { xs: 3, sm: 3 }, minWidth: { xs: "auto", sm: 100 } }}
            >
              {isMobile ? <Icon icon="mdi:filter-variant" width={20} /> : `Filtros ${filtrosActivos > 0 ? `(${filtrosActivos})` : ""}`}
            </Button>

            <Box sx={{ flex: 1, display: { xs: "none", sm: "block" }, order: 4 }} />

            <Box sx={{ display: "flex", gap: 0.5, alignItems: "center", order: { xs: 4, sm: 5 } }}>
              <IconButton onClick={() => load()} size="small">
                <Icon icon="mdi:refresh" width={20} />
              </IconButton>
              <IconButton size="small" disabled>
                <Icon icon="mdi:view-column" width={20} />
              </IconButton>
            </Box>
          </Box>

          <Collapse in={showFilters}>
            <Paper sx={{ p: { xs: 1.5, sm: 2 }, mb: 2, overflow: "hidden" }} variant="outlined">
              <Box sx={{ display: "flex", flexDirection: "column", gap: 1.5 }}>
                <Box sx={{ display: "flex", gap: 1.5, flexWrap: "wrap" }}>
                  <Box sx={{ flex: 1, minWidth: { xs: "100%", sm: 160 } }}>
                    <TextField
                      label="Fecha desde"
                      type="date"
                      value={fechaDesde}
                      onChange={(e) => {
                        setFechaDesde(e.target.value);
                        setFiltroRapido("");
                        setPage(1);
                      }}
                      size="small"
                      fullWidth
                      InputLabelProps={{ shrink: true }}
                    />
                  </Box>
                  <Box sx={{ flex: 1, minWidth: { xs: "100%", sm: 160 } }}>
                    <TextField
                      label="Fecha hasta"
                      type="date"
                      value={fechaHasta}
                      onChange={(e) => {
                        setFechaHasta(e.target.value);
                        setFiltroRapido("");
                        setPage(1);
                      }}
                      size="small"
                      fullWidth
                      InputLabelProps={{ shrink: true }}
                    />
                  </Box>
                </Box>
                <Box sx={{ display: "flex", gap: 1.5, flexWrap: "wrap" }}>
                  <FormControl size="small" sx={{ flex: 1, minWidth: { xs: "100%", sm: 180 } }}>
                    <InputLabel>Origen</InputLabel>
                    <Select value={origen} label="Origen" onChange={(e) => { setOrigen(e.target.value); setPage(1); }}>
                      <MenuItem value="">Todos</MenuItem>
                      <MenuItem value="compra">Compra</MenuItem>
                      <MenuItem value="gasto">Gasto</MenuItem>
                    </Select>
                  </FormControl>
                  <FormControl size="small" sx={{ flex: 1, minWidth: { xs: "100%", sm: 210 } }}>
                    <InputLabel>Estado</InputLabel>
                    <Select value={estado} label="Estado" onChange={(e) => { setEstado(e.target.value); setPage(1); }}>
                      <MenuItem value="">Todos</MenuItem>
                      <MenuItem value="borrador">Borrador</MenuItem>
                      <MenuItem value="pendiente_aprobacion">Pendiente aprobación</MenuItem>
                      <MenuItem value="aprobada">Aprobada</MenuItem>
                      <MenuItem value="ejecutada_parcial">Ejecutada parcial</MenuItem>
                      <MenuItem value="ejecutada_total">Ejecutada total</MenuItem>
                      <MenuItem value="rechazada">Rechazada</MenuItem>
                      <MenuItem value="cancelada">Cancelada</MenuItem>
                    </Select>
                  </FormControl>
                  <Button
                    variant="outlined"
                    onClick={limpiarFiltros}
                    startIcon={<Icon icon="mdi:filter-off" />}
                    sx={{ flex: { xs: 1, sm: "none" }, minWidth: { xs: 0, sm: 120 } }}
                  >
                    Limpiar
                  </Button>
                </Box>
              </Box>
            </Paper>
          </Collapse>

          <Box id="requisiciones-dashboard" sx={KPI_GRID_CONTAINER_SX}>
            <Box sx={KPI_GRID_ITEM_SX}>
              <Card variant="outlined" sx={KPI_CARD_SX}>
                <CardContent sx={KPI_CARD_CONTENT_SX}>
                  <Typography
                    variant="caption"
                    color="text.secondary"
                    sx={KPI_CAPTION_SX}
                  >
                    <Icon icon="mdi:file-document-outline" width={isMobile ? 14 : 16} />
                    Requisiciones
                  </Typography>
                  <Typography variant={isMobile ? "h6" : "h5"}>{loading ? <Skeleton width={45} /> : stats.total}</Typography>
                </CardContent>
              </Card>
            </Box>
            <Box sx={KPI_GRID_ITEM_SX}>
              <Card variant="outlined" sx={KPI_CARD_SX}>
                <CardContent sx={KPI_CARD_CONTENT_SX}>
                  <Typography
                    variant="caption"
                    color="text.secondary"
                    sx={KPI_CAPTION_SX}
                  >
                    <Icon icon="mdi:clock-alert-outline" width={isMobile ? 14 : 16} />
                    Pend. aprob.
                  </Typography>
                  <Typography variant={isMobile ? "h6" : "h5"} color="warning.main">{loading ? <Skeleton width={40} /> : stats.pendiente_aprobacion}</Typography>
                </CardContent>
              </Card>
            </Box>
            <Box sx={KPI_GRID_ITEM_SX}>
              <Card variant="outlined" sx={KPI_CARD_SX}>
                <CardContent sx={KPI_CARD_CONTENT_SX}>
                  <Typography
                    variant="caption"
                    color="text.secondary"
                    sx={KPI_CAPTION_SX}
                  >
                    <Icon icon="mdi:check-circle" width={isMobile ? 14 : 16} />
                    Aprobadas
                  </Typography>
                  <Typography variant={isMobile ? "h6" : "h5"} color="success.main">{loading ? <Skeleton width={40} /> : stats.aprobada}</Typography>
                </CardContent>
              </Card>
            </Box>
            <Box sx={KPI_GRID_ITEM_SX}>
              <Card variant="outlined" sx={KPI_CARD_SX}>
                <CardContent sx={KPI_CARD_CONTENT_SX}>
                  <Typography
                    variant="caption"
                    color="text.secondary"
                    sx={KPI_CAPTION_SX}
                  >
                    <Icon icon="mdi:progress-check" width={isMobile ? 14 : 16} />
                    Ejec. parcial
                  </Typography>
                  <Typography variant={isMobile ? "h6" : "h5"} color="info.main">{loading ? <Skeleton width={40} /> : stats.ejecutada_parcial}</Typography>
                </CardContent>
              </Card>
            </Box>
            <Box sx={KPI_GRID_ITEM_SX}>
              <Card variant="outlined" sx={KPI_CARD_SX}>
                <CardContent sx={KPI_CARD_CONTENT_SX}>
                  <Typography
                    variant="caption"
                    color="text.secondary"
                    sx={KPI_CAPTION_SX}
                  >
                    <Icon icon="mdi:check-decagram-outline" width={isMobile ? 14 : 16} />
                    Ejec. total
                  </Typography>
                  <Typography variant={isMobile ? "h6" : "h5"} color="success.main">{loading ? <Skeleton width={40} /> : stats.ejecutada_total}</Typography>
                </CardContent>
              </Card>
            </Box>
            <Box sx={KPI_GRID_ITEM_SX}>
              <Card variant="outlined" sx={{ ...KPI_CARD_SX, borderColor: "warning.light" }}>
                <CardContent sx={KPI_CARD_CONTENT_SX}>
                  <Typography
                    variant="caption"
                    color="text.secondary"
                    sx={KPI_CAPTION_SX}
                  >
                    <Icon icon="mdi:file-cancel-outline" width={isMobile ? 14 : 16} />
                    Cancel./Rech.
                  </Typography>
                  <Typography variant={isMobile ? "h6" : "h5"} color="error.main">{loading ? <Skeleton width={40} /> : stats.cancelada + stats.rechazada}</Typography>
                </CardContent>
              </Card>
            </Box>
          </Box>

          <Box id="requisiciones-lista">
            {loading ? (
              <EmptyState>Cargando requisiciones...</EmptyState>
            ) : data.length === 0 ? (
              <EmptyState>Sin requisiciones</EmptyState>
            ) : isMobile ? (
              <Box sx={{ display: "flex", flexDirection: "column", gap: 1 }}>
                {data.map((req) => {
                  const estadoReq = String(req?.estado || "").toLowerCase();
                  const puedeEditar = estadoReq === "borrador";
                  const puedeEnviar = estadoReq === "borrador" || estadoReq === "rechazada";
                  const puedeAprobar = estadoReq === "pendiente_aprobacion" && canComprasEdit;
                  const puedeCancelar = !["cancelada", "ejecutada_total"].includes(estadoReq);
                  const puedeCrear = ["aprobada", "ejecutada_parcial"].includes(estadoReq);
                  const ordenesCompraGeneradas = Number(req?.ordenes_compra_generadas || 0);
                  const puedeCrearOC = puedeCrear && req.origen_tipo === "compra" && ordenesCompraGeneradas === 0;
                  return (
                    <Paper key={req.id} variant="outlined" sx={{ p: 1.25, borderRadius: 2 }}>
                      <Box sx={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 1 }}>
                        <Box sx={{ minWidth: 0 }}>
                          <DetailNumberButton
                            onClick={() => handleVerDetalle(req)}
                            sx={{ fontSize: "1.05rem" }}
                          >
                            {req.numero_requisicion || "Sin número"}
                          </DetailNumberButton>
                          <Typography
                            variant="body2"
                            sx={{ fontWeight: 600, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}
                          >
                            {String(req.origen_tipo || "-").toUpperCase()}
                          </Typography>
                          <Typography variant="caption" color="text.secondary">
                            {formatDate(req.fecha_requisicion)}
                          </Typography>
                        </Box>
                        <Badge $state={estadoReq}>{String(req.estado || "-").toUpperCase()}</Badge>
                      </Box>

                      <Box sx={{ mt: 1, display: "flex", justifyContent: "space-between", alignItems: "flex-end", gap: 1 }}>
                        <Box>
                          {canViewAmounts && (
                            <Typography sx={{ fontSize: "1.1rem", lineHeight: 1.1, fontWeight: 700, color: "primary.main" }}>
                              {formatMoney(parseNumber(req.total_estimado, 0), "PYG")}
                            </Typography>
                          )}
                        </Box>
                        <RowActions>
                          <Tooltip title="Ver detalle">
                            <IconButton size="small" onClick={() => handleVerDetalle(req)} sx={actionIconSx("info.main")}>
                              <Icon icon="mdi:eye-outline" width={16} />
                            </IconButton>
                          </Tooltip>
                          {puedeEditar && (
                            <Tooltip title="Editar">
                              <IconButton size="small" onClick={() => handleEditar(req)} sx={actionIconSx("primary.main")}>
                                <Icon icon="mdi:pencil-outline" width={16} />
                              </IconButton>
                            </Tooltip>
                          )}
                          {puedeEnviar && (
                            <Tooltip title="Enviar aprobación">
                              <IconButton size="small" onClick={() => handleEnviarAprobacion(req)} sx={actionIconSx("info.main")}>
                                <Icon icon="mdi:send-check-outline" width={16} />
                              </IconButton>
                            </Tooltip>
                          )}
                          {puedeAprobar && (
                            <Tooltip title="Aprobar">
                              <IconButton size="small" onClick={() => handleAprobar(req)} sx={actionIconSx("success.main")}>
                                <Icon icon="mdi:check-circle-outline" width={16} />
                              </IconButton>
                            </Tooltip>
                          )}
                          {puedeAprobar && (
                            <Tooltip title="Rechazar">
                              <IconButton size="small" onClick={() => handleRechazar(req)} sx={actionIconSx("warning.main")}>
                                <Icon icon="mdi:close-circle-outline" width={16} />
                              </IconButton>
                            </Tooltip>
                          )}
                          {puedeCancelar && (
                            <Tooltip title="Cancelar">
                              <IconButton size="small" onClick={() => handleCancelar(req)} sx={actionIconSx("error.main")}>
                                <Icon icon="lucide:ban" width={16} />
                              </IconButton>
                            </Tooltip>
                          )}
                          {puedeCrearOC && (
                            <Tooltip title="Crear OC">
                              <IconButton size="small" onClick={() => handleCrearOC(req)} sx={actionIconSx("secondary.main")}>
                                <Icon icon="mdi:file-document-plus-outline" width={16} />
                              </IconButton>
                            </Tooltip>
                          )}
                          {puedeCrear && req.origen_tipo === "gasto" && (
                            <Tooltip title="Crear gasto">
                              <IconButton size="small" onClick={() => handleCrearGasto(req)} sx={actionIconSx("secondary.main")}>
                                <Icon icon="mdi:receipt-text-plus-outline" width={16} />
                              </IconButton>
                            </Tooltip>
                          )}
                        </RowActions>
                      </Box>
                    </Paper>
                  );
                })}
              </Box>
            ) : (
              <TableWrap $listView>
                <table>
                  <thead>
                    <tr>
                      <th>Número</th>
                      <th>Fecha</th>
                      <th>Origen</th>
                      {canViewAmounts && <th>Total estimado</th>}
                      <th>Estado</th>
                      <th id="requisiciones-acciones-col">Acciones</th>
                    </tr>
                  </thead>
                  <tbody>
                    {data.map((req) => {
                      const estadoReq = String(req?.estado || "").toLowerCase();
                      const puedeEditar = estadoReq === "borrador";
                      const puedeEnviar = estadoReq === "borrador" || estadoReq === "rechazada";
                      const puedeAprobar = estadoReq === "pendiente_aprobacion" && canComprasEdit;
                      const puedeCancelar = !["cancelada", "ejecutada_total"].includes(estadoReq);
                      const puedeCrear = ["aprobada", "ejecutada_parcial"].includes(estadoReq);
                      const ordenesCompraGeneradas = Number(req?.ordenes_compra_generadas || 0);
                      const puedeCrearOC = puedeCrear && req.origen_tipo === "compra" && ordenesCompraGeneradas === 0;
                      return (
                        <tr key={req.id}>
                          <td>
                            <DetailNumberButton onClick={() => handleVerDetalle(req)}>
                              {req.numero_requisicion || "Sin número"}
                            </DetailNumberButton>
                          </td>
                          <td>{formatDate(req.fecha_requisicion)}</td>
                          <td>{String(req.origen_tipo || "-").toUpperCase()}</td>
                          {canViewAmounts && <td>{formatMoney(parseNumber(req.total_estimado, 0), "PYG")}</td>}
                          <td>
                            <Badge $state={estadoReq}>{String(req.estado || "-").toUpperCase()}</Badge>
                          </td>
                          <td>
                            <RowActions>
                              <Tooltip title="Ver detalle">
                                <IconButton size="small" onClick={() => handleVerDetalle(req)} sx={actionIconSx("info.main")}>
                                  <Icon icon="mdi:eye-outline" width={16} />
                                </IconButton>
                              </Tooltip>
                              {puedeEditar && (
                                <Tooltip title="Editar">
                                  <IconButton size="small" onClick={() => handleEditar(req)} sx={actionIconSx("primary.main")}>
                                    <Icon icon="mdi:pencil-outline" width={16} />
                                  </IconButton>
                                </Tooltip>
                              )}
                              {puedeEnviar && (
                                <Tooltip title="Enviar aprobación">
                                  <IconButton size="small" onClick={() => handleEnviarAprobacion(req)} sx={actionIconSx("info.main")}>
                                    <Icon icon="mdi:send-check-outline" width={16} />
                                  </IconButton>
                                </Tooltip>
                              )}
                              {puedeAprobar && (
                                <>
                                  <Tooltip title="Aprobar">
                                    <IconButton size="small" onClick={() => handleAprobar(req)} sx={actionIconSx("success.main")}>
                                      <Icon icon="mdi:check-circle-outline" width={16} />
                                    </IconButton>
                                  </Tooltip>
                                  <Tooltip title="Rechazar">
                                    <IconButton size="small" onClick={() => handleRechazar(req)} sx={actionIconSx("warning.main")}>
                                      <Icon icon="mdi:close-circle-outline" width={16} />
                                    </IconButton>
                                  </Tooltip>
                                </>
                              )}
                              {puedeCancelar && (
                                <Tooltip title="Cancelar">
                                  <IconButton size="small" onClick={() => handleCancelar(req)} sx={actionIconSx("error.main")}>
                                    <Icon icon="lucide:ban" width={16} />
                                  </IconButton>
                                </Tooltip>
                              )}
                              {puedeCrearOC && (
                                <Tooltip title="Crear OC">
                                  <IconButton size="small" onClick={() => handleCrearOC(req)} sx={actionIconSx("secondary.main")}>
                                    <Icon icon="mdi:file-document-plus-outline" width={16} />
                                  </IconButton>
                                </Tooltip>
                              )}
                              {puedeCrear && req.origen_tipo === "gasto" && (
                                <Tooltip title="Crear gasto">
                                  <IconButton size="small" onClick={() => handleCrearGasto(req)} sx={actionIconSx("secondary.main")}>
                                    <Icon icon="mdi:receipt-text-plus-outline" width={16} />
                                  </IconButton>
                                </Tooltip>
                              )}
                            </RowActions>
                          </td>
                        </tr>
                      );
                    })}
                  </tbody>
                </table>
              </TableWrap>
            )}
          </Box>

          <TablePaginationBar
            page={page}
            totalPages={totalPages}
            onPageChange={setPage}
            total={total}
            shown={data.length}
            noun="requisiciones"
            rowsPerPage={limit}
            onRowsPerPageChange={(n) => {
              setLimit(n);
              setPage(1);
            }}
          />
        </Paper>
      )}

      <CrearOCDesdeRequisicionDialog
        open={Boolean(dialogOC)}
        requisicion={dialogOC}
        sucursales={sucursales}
        onClose={() => setDialogOC(null)}
        onSuccess={async (result) => {
          setDialogOC(null);
          const total = result?.total_ordenes_creadas ?? 1;
          toast.success(
            total > 1
              ? `${total} órdenes de compra generadas desde requisición`
              : "Orden de compra generada desde requisición",
          );
          await load();
        }}
      />

      <CrearGastoDesdeRequisicionDialog
        open={Boolean(dialogGasto)}
        requisicion={dialogGasto}
        sucursales={sucursales}
        onClose={() => setDialogGasto(null)}
        onSuccess={async () => {
          setDialogGasto(null);
          toast.success("Gasto generado desde requisición");
          await load();
        }}
      />

      <PromptDialog
        open={Boolean(promptAction)}
        loading={promptLoading}
        title={promptAction?.title || ""}
        message={promptAction?.message || ""}
        label={promptAction?.label || "Comentario"}
        placeholder={promptAction?.placeholder || ""}
        required={Boolean(promptAction?.required)}
        confirmText={promptAction?.confirmText || "Confirmar"}
        confirmColor={promptAction?.confirmColor || "primary"}
        onClose={() => {
          if (promptLoading) return;
          setPromptAction(null);
        }}
        onConfirm={handleConfirmPrompt}
      />

      <Dialog
        open={detalleDialog.open}
        onClose={closeDetalleDialog}
        fullWidth
        maxWidth="md"
        PaperProps={{ id: "requisicion-detalle-dialog" }}
      >
        <DialogTitle>Detalle requisición {detalleDialog.numero}</DialogTitle>
        <DialogContent dividers>
          {detalleDialog.loading ? (
            <Typography variant="body2">Cargando detalle...</Typography>
          ) : !detalleDialog.requisicion ? (
            <Typography variant="body2" color="text.secondary">
              No se pudo obtener el detalle de la requisición.
            </Typography>
          ) : (
            <Box sx={{ display: "flex", flexDirection: "column", gap: 1.5 }}>
              <Tabs
                value={detalleTab}
                onChange={(_, value) => setDetalleTab(value)}
                variant="fullWidth"
                sx={{ borderBottom: 1, borderColor: "divider" }}
              >
                <Tab label="General" value="general" />
                <Tab label="Historial" value="historial" />
              </Tabs>

              {detalleTab === "general" ? (
                <>
                  <Paper variant="outlined" sx={{ p: 1.25 }}>
                    <Grid container spacing={1}>
                      <Grid item xs={12} sm={6}>
                        <Typography variant="caption" color="text.secondary">Estado</Typography>
                        <Typography variant="body2" sx={{ fontWeight: 700 }}>
                          {String(detalleDialog.requisicion?.estado || "-").toUpperCase()}
                        </Typography>
                      </Grid>
                      <Grid item xs={12} sm={6}>
                        <Typography variant="caption" color="text.secondary">Fecha</Typography>
                        <Typography variant="body2" sx={{ fontWeight: 700 }}>
                          {formatDate(detalleDialog.requisicion?.fecha_requisicion)}
                        </Typography>
                      </Grid>
                      <Grid item xs={12} sm={6}>
                        <Typography variant="caption" color="text.secondary">Origen</Typography>
                        <Typography variant="body2" sx={{ fontWeight: 700 }}>
                          {String(detalleDialog.requisicion?.origen_tipo || "-").toUpperCase()}
                        </Typography>
                      </Grid>
                      <Grid item xs={12} sm={6}>
                        <Typography variant="caption" color="text.secondary">Solicitante</Typography>
                        <Typography variant="body2" sx={{ fontWeight: 700 }}>
                          {formatUserName(detalleDialog.requisicion?.solicitante)}
                        </Typography>
                      </Grid>
                      {canViewAmounts && (
                        <Grid item xs={12} sm={6}>
                          <Typography variant="caption" color="text.secondary">Total estimado</Typography>
                          <Typography variant="body2" sx={{ fontWeight: 700 }}>
                            {formatMoney(parseNumber(detalleDialog.requisicion?.total_estimado, 0), "PYG")}
                          </Typography>
                        </Grid>
                      )}
                    </Grid>
                  </Paper>

                  {String(detalleDialog.requisicion?.descripcion || "").trim() && (
                    <Paper variant="outlined" sx={{ p: 1.25 }}>
                      <Typography variant="caption" color="text.secondary">Descripción</Typography>
                      <Typography variant="body2">{String(detalleDialog.requisicion.descripcion)}</Typography>
                    </Paper>
                  )}

                  <Typography variant="subtitle2">Ítems</Typography>
                  {Array.isArray(detalleDialog.requisicion?.requisicion_det) &&
                  detalleDialog.requisicion.requisicion_det.length > 0 ? (
                    <TableContainer component={Paper} variant="outlined">
                      <Table size="small">
                        <TableHead>
                          <TableRow>
                            <TableCell>#</TableCell>
                            <TableCell>Descripción</TableCell>
                            <TableCell align="right">Cant. solicitada</TableCell>
                            <TableCell align="right">Cant. ejecutada</TableCell>
                            {canViewAmounts && <TableCell align="right">Subtotal</TableCell>}
                            <TableCell>Estado</TableCell>
                          </TableRow>
                        </TableHead>
                        <TableBody>
                          {detalleDialog.requisicion.requisicion_det.map((det, idx) => (
                            <TableRow key={det.id || idx}>
                              <TableCell>{idx + 1}</TableCell>
                              <TableCell>{det?.productos?.descripcion || det?.descripcion || "-"}</TableCell>
                              <TableCell align="right">{parseNumber(det?.cantidad_solicitada, 0).toLocaleString("es-PY")}</TableCell>
                              <TableCell align="right">{parseNumber(det?.cantidad_ejecutada, 0).toLocaleString("es-PY")}</TableCell>
                              {canViewAmounts && (
                                <TableCell align="right">
                                  {formatMoney(parseNumber(det?.subtotal_estimado, 0), "PYG")}
                                </TableCell>
                              )}
                              <TableCell>{String(det?.estado || "-").toUpperCase()}</TableCell>
                            </TableRow>
                          ))}
                        </TableBody>
                      </Table>
                    </TableContainer>
                  ) : (
                    <Typography variant="body2" color="text.secondary">
                      Esta requisición no tiene ítems cargados.
                    </Typography>
                  )}
                </>
              ) : (
                <>
                  {Array.isArray(detalleDialog.requisicion?.requisicion_historial) &&
                  detalleDialog.requisicion.requisicion_historial.length > 0 ? (
                    <Box sx={{ display: "flex", flexDirection: "column", gap: 1 }}>
                      {detalleDialog.requisicion.requisicion_historial.map((event, idx) => (
                        <Paper key={`${event.id || idx}-${event.created_at || idx}`} variant="outlined" sx={{ p: 1.25 }}>
                          <Typography variant="body2" sx={{ fontWeight: 700 }}>
                            {String(event.accion || "evento").replaceAll("_", " ").toUpperCase()}
                          </Typography>
                          <Typography variant="caption" color="text.secondary" sx={{ display: "block" }}>
                            {formatDateTime(event.created_at)} · {formatUserName(event.usuario)}
                          </Typography>
                          {event.comentario && (
                            <Typography variant="body2" sx={{ mt: 0.5 }}>
                              {event.comentario}
                            </Typography>
                          )}
                        </Paper>
                      ))}
                    </Box>
                  ) : (
                    <Typography variant="body2" color="text.secondary">
                      Sin eventos de historial para esta requisición.
                    </Typography>
                  )}
                </>
              )}
            </Box>
          )}
        </DialogContent>
        <DialogActions>
          <Button onClick={closeDetalleDialog}>Cerrar</Button>
        </DialogActions>
      </Dialog>

      <ConfirmDialog
        open={confirmGuardarOpen}
        loading={saving}
        title={editingId ? "Confirmar actualización de requisición" : "Confirmar creación de requisición"}
        message={(
          <Box sx={{ display: "flex", flexDirection: "column", gap: 1 }}>
            <Typography variant="body2">
              Vas a {editingId ? "actualizar" : "crear"} una requisición de tipo <strong>{form.cabecera.origen_tipo}</strong> con{" "}
              <strong>{form.items.length}</strong> ítem{form.items.length === 1 ? "" : "s"}.
            </Typography>
            <Typography variant="body2" color="text.secondary">
              Quedará en estado borrador y podrás enviarla a aprobación luego.
            </Typography>
          </Box>
        )}
        confirmText={editingId ? "Actualizar requisición" : "Crear requisición"}
        cancelText="Cancelar"
        confirmColor="primary"
        onClose={() => {
          if (saving) return;
          setConfirmGuardarOpen(false);
          setPendingGuardarPayload(null);
        }}
        onConfirm={confirmGuardar}
      />
    </Box>
  );
}

const TableWrap = styled.div`
  overflow: auto;
  margin-bottom: 8px;
  border: ${({ $listView, theme }) =>
    $listView ? `1px solid ${theme.color2 || theme.bg4}` : "none"};
  border-radius: 10px;

  table {
    width: 100%;
    border-collapse: collapse;
  }

  th,
  td {
    border-bottom: 1px solid ${({ theme }) => theme.color2 || theme.bg4};
    padding: 10px 12px;
    text-align: left;
    white-space: nowrap;
    vertical-align: middle;
  }

  th {
    font-size: ${({ $listView }) => ($listView ? "0.95rem" : "0.75rem")};
    font-weight: ${({ $listView }) => ($listView ? 700 : 600)};
    text-transform: ${({ $listView }) => ($listView ? "none" : "uppercase")};
    letter-spacing: ${({ $listView }) => ($listView ? "0" : "0.4px")};
    background: ${({ theme, $listView }) => ($listView ? theme.bg3 : "transparent")};
  }

  tbody tr:hover {
    background: ${({ theme, $listView }) =>
      $listView ? `${theme.primary || "#5b7fff"}10` : "transparent"};
  }
`;

const RowActions = styled.div`
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
`;

const Badge = styled.span`
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 0.74rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.3px;
  background: ${({ $state }) => {
    if ($state === "aprobada" || $state === "ejecutada_total") return "rgba(16, 185, 129, 0.16)";
    if ($state === "pendiente_aprobacion") return "rgba(245, 158, 11, 0.16)";
    if ($state === "ejecutada_parcial") return "rgba(14, 165, 233, 0.16)";
    if ($state === "rechazada" || $state === "cancelada") return "rgba(239, 68, 68, 0.16)";
    return "rgba(59, 130, 246, 0.16)";
  }};
  color: ${({ $state }) => {
    if ($state === "aprobada" || $state === "ejecutada_total") return "#10b981";
    if ($state === "pendiente_aprobacion") return "#f59e0b";
    if ($state === "ejecutada_parcial") return "#0ea5e9";
    if ($state === "rechazada" || $state === "cancelada") return "#ef4444";
    return "#60a5fa";
  }};
`;

const EmptyState = styled.div`
  min-height: 180px;
  border: 1px dashed ${({ theme }) => theme.color2 || theme.bg4};
  border-radius: 10px;
  display: grid;
  place-items: center;
  color: ${({ theme }) => theme.textSecondary || theme.text};
  font-size: 0.92rem;
  margin-bottom: 8px;
`;
