import { Icon } from "@iconify/react";
import {
  Alert,
  Box,
  Button,
  Checkbox,
  CircularProgress,
  FormControl,
  IconButton,
  InputLabel,
  MenuItem,
  Paper,
  Select,
  Stack,
  Switch,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Typography,
} from "@mui/material";
import { useEffect, useMemo, useState } from "react";
import { IMaskInput } from "react-imask";
import { toast } from "sonner";
import {
  aplicarConfigAprobacionesRecomendada,
  getAprobacionesConfigRequisiciones,
  updateAprobacionesConfigRequisiciones,
} from "../../api/requisiciones.service";
import { getPerfilesEmpresa, getUsuarios, updateUsuario } from "../../api/usuarios.service";
import { useEmpresa } from "../../context/EmpresaContext";
import { usePermission } from "../../hooks/usePermission";
import { AccesoRestringido } from "../common/AccesoRestringido";
import { ConfirmDialog } from "../ui/ConfirmDialog";

const ORIGEN_LABELS = {
  compra: "Compras",
  gasto: "Gastos",
};

const ORIGEN_DESCRIPCIONES = {
  compra:
    "Niveles que se aplican al enviar a aprobación una requisición de compra. Se evalúan por monto.",
  gasto:
    "Niveles que se aplican al enviar a aprobación una requisición de gasto. Se evalúan por monto.",
};

let tempCounter = 0;
const nextTempKey = () => `tmp-${++tempCounter}-${Date.now()}`;

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

const buildEmptyNivel = (origen) => ({
  _key: nextTempKey(),
  id: null,
  origen_tipo: origen,
  perfil_id: "",
  monto_desde: 0,
  monto_hasta: null,
  sin_tope: true,
  activo: true,
});

const normalizeFromApi = (rows) =>
  (rows || []).map((row) => ({
    _key: row.id || nextTempKey(),
    id: row.id || null,
    origen_tipo: row.origen_tipo,
    perfil_id: row.perfil_id || row.perfiles?.id || "",
    monto_desde: parseNumber(row.monto_desde, 0),
    monto_hasta: row.monto_hasta == null ? null : parseNumber(row.monto_hasta, 0),
    sin_tope: row.monto_hasta == null,
    activo: row.activo !== false,
  }));

const normalizeProfileIds = (ids) =>
  Array.from(
    new Set((ids || []).filter(Boolean).map(String)),
  ).sort();

const areEqualProfileSets = (a, b) => {
  const left = normalizeProfileIds(a);
  const right = normalizeProfileIds(b);
  if (left.length !== right.length) return false;
  return left.every((id, idx) => id === right[idx]);
};

export function RequisicionAprobacionesConfigTab({ embedded = false } = {}) {
  const { hasAccess, can } = usePermission("ADMINISTRACION");
  const canRead = can("ADM_CCFG_CONFIG_VER");
  const canEdit = can("ADM_CCFG_CONFIG_EDITAR");
  const permisosUsuarios = {
    hasAccess,
    canRead: can("ADM_USR_USUARIO_VER"),
    canEdit: can("ADM_USR_USUARIO_EDITAR"),
  };
  const { empresaId } = useEmpresa();
  const [loading, setLoading] = useState(false);
  const [saving, setSaving] = useState(false);
  const [savingAsignaciones, setSavingAsignaciones] = useState(false);
  const [items, setItems] = useState([]);
  const [perfiles, setPerfiles] = useState([]);
  const [usuarios, setUsuarios] = useState([]);
  const [asignacionesPorUsuario, setAsignacionesPorUsuario] = useState({});
  const [asignacionesBasePorUsuario, setAsignacionesBasePorUsuario] = useState({});
  const [perfilesCompletosBasePorUsuario, setPerfilesCompletosBasePorUsuario] = useState({});
  const [validationMessages, setValidationMessages] = useState([]);
  const [feedback, setFeedback] = useState(null);
  const [feedbackAsignaciones, setFeedbackAsignaciones] = useState(null);
  const [confirmOpen, setConfirmOpen] = useState(false);
  const [confirmRecomendadaOpen, setConfirmRecomendadaOpen] = useState(false);
  const [aplicandoRecomendada, setAplicandoRecomendada] = useState(false);

  const itemsPorOrigen = useMemo(() => {
    const groups = { compra: [], gasto: [] };
    items.forEach((item) => {
      const list = groups[item.origen_tipo] || (groups[item.origen_tipo] = []);
      list.push(item);
    });
    return groups;
  }, [items]);

  const perfilesAprobadoresIds = useMemo(
    () => normalizeProfileIds(items.map((item) => item.perfil_id)),
    [items],
  );

  const perfilesAprobadores = useMemo(() => {
    const perfilesById = new Map(
      (perfiles || []).map((perfil) => [String(perfil.id), perfil]),
    );
    return perfilesAprobadoresIds.map((id) => ({
      id,
      label:
        perfilesById.get(id)?.desc_perfil ||
        perfilesById.get(id)?.perfil ||
        id,
    }));
  }, [perfiles, perfilesAprobadoresIds]);

  const usuariosActivos = useMemo(() => {
    return (usuarios || [])
      .filter((usuario) => usuario?.active !== false)
      .sort((a, b) =>
        String(`${a?.nombres || ""} ${a?.apellidos || ""}`)
          .trim()
          .localeCompare(String(`${b?.nombres || ""} ${b?.apellidos || ""}`).trim()),
      );
  }, [usuarios]);

  const canEditarAsignaciones = Boolean(
    canEdit && permisosUsuarios?.hasAccess && permisosUsuarios?.canEdit,
  );

  const hasPermissionUsuariosLectura = Boolean(
    permisosUsuarios?.hasAccess &&
      (permisosUsuarios?.canRead || permisosUsuarios?.canEdit),
  );

  const load = async () => {
    if (!hasAccess || !canRead) return;
    try {
      setLoading(true);
      const [configRows, perfilesRows, usuariosRows] = await Promise.all([
        getAprobacionesConfigRequisiciones().catch(() => []),
        getPerfilesEmpresa().catch(() => []),
        hasPermissionUsuariosLectura && empresaId
          ? getUsuarios(1, 500, empresaId).catch(() => ({ data: [] }))
          : Promise.resolve({ data: [] }),
      ]);
      const normalizedItems = normalizeFromApi(configRows);
      const managedProfileIds = normalizeProfileIds(
        normalizedItems.map((item) => item.perfil_id),
      );
      const usersList = Array.isArray(usuariosRows?.data)
        ? usuariosRows.data
        : Array.isArray(usuariosRows)
          ? usuariosRows
          : [];

      const nextAsignaciones = {};
      const nextBaseAsignaciones = {};
      const nextPerfilesCompletos = {};

      for (const usuario of usersList) {
        const userId = String(usuario?.id || "");
        if (!userId) continue;
        const perfilesUsuario = normalizeProfileIds(
          (usuario?.usuario_perfiles || []).map((up) => up?.perfiles?.id),
        );
        const managedForUser = perfilesUsuario.filter((id) =>
          managedProfileIds.includes(id),
        );
        nextPerfilesCompletos[userId] = perfilesUsuario;
        nextAsignaciones[userId] = managedForUser;
        nextBaseAsignaciones[userId] = managedForUser;
      }

      setItems(normalizedItems);
      setPerfiles(Array.isArray(perfilesRows) ? perfilesRows : perfilesRows?.data || []);
      setUsuarios(usersList);
      setPerfilesCompletosBasePorUsuario(nextPerfilesCompletos);
      setAsignacionesPorUsuario(nextAsignaciones);
      setAsignacionesBasePorUsuario(nextBaseAsignaciones);
    } catch (error) {
      console.error(error);
      toast.error("No se pudo cargar la configuración de aprobaciones");
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    load();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [empresaId, hasPermissionUsuariosLectura]);

  useEffect(() => {
    const managedSet = new Set(perfilesAprobadoresIds);
    setAsignacionesPorUsuario((prev) => {
      const next = {};
      for (const [userId, ids] of Object.entries(prev || {})) {
        next[userId] = normalizeProfileIds((ids || []).filter((id) => managedSet.has(id)));
      }
      return next;
    });
    setAsignacionesBasePorUsuario((prev) => {
      const next = {};
      for (const [userId, ids] of Object.entries(prev || {})) {
        next[userId] = normalizeProfileIds((ids || []).filter((id) => managedSet.has(id)));
      }
      return next;
    });
  }, [perfilesAprobadoresIds]);

  const updateItem = (key, patch) => {
    setItems((prev) =>
      prev.map((it) => (it._key === key ? { ...it, ...patch } : it)),
    );
  };

  const addNivel = (origen) => {
    setItems((prev) => [...prev, buildEmptyNivel(origen)]);
  };

  const removeItem = (key) => {
    setItems((prev) => prev.filter((it) => it._key !== key));
  };

  const moverNivel = (key, dir) => {
    setItems((prev) => {
      const idx = prev.findIndex((it) => it._key === key);
      if (idx < 0) return prev;
      const target = prev[idx];
      const grupo = prev.filter((it) => it.origen_tipo === target.origen_tipo);
      const grupoIdx = grupo.findIndex((it) => it._key === key);
      const swapIdx = grupoIdx + dir;
      if (swapIdx < 0 || swapIdx >= grupo.length) return prev;
      const otro = grupo[swapIdx];
      const newOrder = [...prev];
      const i1 = newOrder.findIndex((it) => it._key === target._key);
      const i2 = newOrder.findIndex((it) => it._key === otro._key);
      [newOrder[i1], newOrder[i2]] = [newOrder[i2], newOrder[i1]];
      return newOrder;
    });
  };

  const toggleAsignacion = (usuarioId, perfilId) => {
    setAsignacionesPorUsuario((prev) => {
      const actual = new Set(prev[usuarioId] || []);
      if (actual.has(perfilId)) actual.delete(perfilId);
      else actual.add(perfilId);
      return {
        ...prev,
        [usuarioId]: normalizeProfileIds(Array.from(actual)),
      };
    });
  };

  const hasCambiosAsignaciones = useMemo(() => {
    const userIds = new Set([
      ...Object.keys(asignacionesBasePorUsuario || {}),
      ...Object.keys(asignacionesPorUsuario || {}),
    ]);
    for (const userId of userIds) {
      if (
        !areEqualProfileSets(
          asignacionesBasePorUsuario[userId] || [],
          asignacionesPorUsuario[userId] || [],
        )
      ) {
        return true;
      }
    }
    return false;
  }, [asignacionesBasePorUsuario, asignacionesPorUsuario]);

  const guardarAsignaciones = async () => {
    if (!canEditarAsignaciones || savingAsignaciones) return;
    try {
      setSavingAsignaciones(true);
      setFeedbackAsignaciones(null);

      const managedSet = new Set(perfilesAprobadoresIds);
      const successes = [];
      const failures = [];
      const nextPerfilesCompletos = { ...perfilesCompletosBasePorUsuario };
      const nextBaseAsignaciones = { ...asignacionesBasePorUsuario };

      for (const usuario of usuariosActivos) {
        const userId = String(usuario?.id || "");
        if (!userId) continue;

        const perfilesBase = normalizeProfileIds(
          perfilesCompletosBasePorUsuario[userId] || [],
        );
        const perfilesSeleccionadosCompras = normalizeProfileIds(
          asignacionesPorUsuario[userId] || [],
        );

        const perfilesNoCompras = perfilesBase.filter((id) => !managedSet.has(id));
        const perfilesFinales = normalizeProfileIds([
          ...perfilesNoCompras,
          ...perfilesSeleccionadosCompras,
        ]);

        if (areEqualProfileSets(perfilesBase, perfilesFinales)) {
          nextPerfilesCompletos[userId] = perfilesFinales;
          nextBaseAsignaciones[userId] = perfilesSeleccionadosCompras;
          continue;
        }

        try {
          await updateUsuario(userId, { perfiles: perfilesFinales });
          nextPerfilesCompletos[userId] = perfilesFinales;
          nextBaseAsignaciones[userId] = perfilesSeleccionadosCompras;
          successes.push(
            `${usuario?.nombres || ""} ${usuario?.apellidos || ""}`.trim() || usuario?.username || userId,
          );
        } catch (error) {
          const name =
            `${usuario?.nombres || ""} ${usuario?.apellidos || ""}`.trim() ||
            usuario?.username ||
            userId;
          failures.push({
            userId,
            name,
            message:
              error?.response?.data?.message ||
              error?.message ||
              "Error al guardar perfiles",
          });
        }
      }

      setPerfilesCompletosBasePorUsuario(nextPerfilesCompletos);
      setAsignacionesBasePorUsuario(nextBaseAsignaciones);

      if (failures.length === 0) {
        setFeedbackAsignaciones({
          severity: "success",
          messages: [
            successes.length > 0
              ? `Asignaciones actualizadas para ${successes.length} usuario(s).`
              : "No había cambios de asignación para guardar.",
          ],
        });
        if (successes.length > 0) {
          toast.success("Asignaciones de perfiles guardadas");
        } else {
          toast.info("No hay cambios de asignación para guardar");
        }
      } else {
        const firstError = failures[0]?.message;
        setFeedbackAsignaciones({
          severity: "warning",
          messages: [
            successes.length > 0
              ? `Se guardaron ${successes.length} usuario(s), con ${failures.length} fallo(s).`
              : `No se pudo guardar ninguna asignación (${failures.length} fallos).`,
            ...failures.slice(0, 5).map((f) => `${f.name}: ${f.message}`),
          ],
        });
        toast.warning(firstError || "Guardado parcial de asignaciones");
      }
    } finally {
      setSavingAsignaciones(false);
    }
  };

  const buildPayload = () => {
    const errors = [];
    const payloadItems = [];
    for (const origen of ["compra", "gasto"]) {
      const grupo = itemsPorOrigen[origen] || [];
      grupo.forEach((item, idx) => {
        const nivel = idx + 1;
        if (!item.perfil_id) {
          errors.push(`${ORIGEN_LABELS[origen]} · Nivel ${nivel}: seleccioná un perfil`);
        }
        const desde = parseNumber(item.monto_desde, 0);
        const hasta = item.sin_tope ? null : parseNumber(item.monto_hasta, 0);
        if (desde < 0)
          errors.push(`${ORIGEN_LABELS[origen]} · Nivel ${nivel}: monto desde no puede ser negativo`);
        if (hasta != null && hasta < desde) {
          errors.push(
            `${ORIGEN_LABELS[origen]} · Nivel ${nivel}: monto hasta debe ser ≥ monto desde`,
          );
        }
        payloadItems.push({
          origen_tipo: origen,
          nivel,
          perfil_id: item.perfil_id,
          monto_desde: desde,
          monto_hasta: hasta,
          activo: item.activo !== false,
        });
      });
    }
    return { errors, items: payloadItems };
  };

  const handleGuardar = () => {
    setValidationMessages([]);
    setFeedback(null);
    const { errors, items: payloadItems } = buildPayload();
    if (errors.length) {
      setValidationMessages(errors);
      toast.warning(errors[0]);
      return;
    }
    if (payloadItems.length === 0) {
      // Permitido: borra todo
    }
    setConfirmOpen(true);
  };

  const handleAdministrarPerfiles = () => {
    if (typeof window !== "undefined") {
      window.dispatchEvent(
        new CustomEvent("configuracion:navigate", { detail: { sectionId: "perfiles" } }),
      );
    }
  };

  const handleAplicarRecomendada = () => {
    setValidationMessages([]);
    setFeedback(null);
    setConfirmRecomendadaOpen(true);
  };

  const confirmAplicarRecomendada = async () => {
    try {
      setAplicandoRecomendada(true);
      const result = await aplicarConfigAprobacionesRecomendada();
      setItems(normalizeFromApi(result?.config || []));
      const perfilesCreados = (result?.perfiles_aplicados || [])
        .map((p) => p.desc_perfil)
        .join(", ");
      setFeedback({
        severity: "success",
        messages: [
          "Configuración recomendada aplicada",
          perfilesCreados
            ? `Perfiles asegurados: ${perfilesCreados}`
            : "Niveles default cargados",
        ],
      });
      toast.success("Configuración recomendada aplicada");
      setConfirmRecomendadaOpen(false);
    } catch (error) {
      console.error(error);
      const apiMsg = error?.response?.data?.message;
      const messages = Array.isArray(apiMsg)
        ? apiMsg
        : [apiMsg || "No se pudo aplicar la configuración recomendada"];
      setValidationMessages(messages);
      setConfirmRecomendadaOpen(false);
      toast.error(messages[0]);
    } finally {
      setAplicandoRecomendada(false);
    }
  };

  const confirmGuardar = async () => {
    const { items: payloadItems } = buildPayload();
    try {
      setSaving(true);
      const updated = await updateAprobacionesConfigRequisiciones({ items: payloadItems });
      setItems(normalizeFromApi(updated));
      setFeedback({
        severity: "success",
        messages: ["Configuración de aprobaciones guardada"],
      });
      toast.success("Configuración de aprobaciones guardada");
      setConfirmOpen(false);
    } catch (error) {
      console.error(error);
      const apiMsg = error?.response?.data?.message;
      const messages = Array.isArray(apiMsg)
        ? apiMsg
        : [apiMsg || "No se pudo guardar la configuración"];
      setValidationMessages(messages);
      setConfirmOpen(false);
      toast.error(messages[0]);
    } finally {
      setSaving(false);
    }
  };

  if (!hasAccess || !canRead) {
    return (
      <AccesoRestringido mensaje="No tienes permisos para configurar aprobaciones de requisiciones." />
    );
  }

  const renderTablaOrigen = (origen) => {
    const grupo = itemsPorOrigen[origen] || [];
    return (
      <Paper key={origen} variant="outlined" sx={{ p: 1.5, mb: 2 }}>
        <Box sx={{ mb: 1 }}>
          <Typography variant="subtitle1" sx={{ fontWeight: 700 }}>
            Aprobaciones de {ORIGEN_LABELS[origen]}
          </Typography>
          <Typography variant="caption" color="text.secondary">
            {ORIGEN_DESCRIPCIONES[origen]}
          </Typography>
        </Box>

        {grupo.length === 0 ? (
          <Alert severity="warning" sx={{ mb: 1 }}>
            Sin niveles configurados — las requisiciones de {ORIGEN_LABELS[origen].toLowerCase()}{" "}
            no podrán enviarse a aprobación. Agregá al menos un nivel.
          </Alert>
        ) : (
          <TableContainer>
            <Table size="small">
              <TableHead>
                <TableRow>
                  <TableCell sx={{ width: 70 }}>Nivel</TableCell>
                  <TableCell sx={{ minWidth: 220 }}>Perfil aprobador</TableCell>
                  <TableCell align="right" sx={{ width: 160 }}>
                    Monto desde
                  </TableCell>
                  <TableCell align="right" sx={{ width: 200 }}>
                    Monto hasta
                  </TableCell>
                  <TableCell align="center" sx={{ width: 100 }}>
                    Activo
                  </TableCell>
                  <TableCell align="center" sx={{ width: 110 }}>
                    Orden
                  </TableCell>
                  <TableCell align="center" sx={{ width: 56 }}></TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                {grupo.map((item, idx) => (
                  <TableRow key={item._key}>
                    <TableCell>{idx + 1}</TableCell>
                    <TableCell sx={{ minWidth: 220 }}>
                      <FormControl size="small" fullWidth>
                        <InputLabel>Perfil</InputLabel>
                        <Select
                          value={item.perfil_id}
                          label="Perfil"
                          onChange={(e) => updateItem(item._key, { perfil_id: e.target.value })}
                          disabled={!canEdit}
                        >
                          {perfiles.map((p) => (
                            <MenuItem key={p.id} value={p.id}>
                              {p.desc_perfil || p.perfil || "Sin nombre"}
                            </MenuItem>
                          ))}
                        </Select>
                      </FormControl>
                    </TableCell>
                    <TableCell align="right" sx={{ width: 160 }}>
                      <IMaskInput
                        mask={Number}
                        scale={2}
                        signed={false}
                        thousandsSeparator="."
                        radix=","
                        mapToRadix={["."]}
                        min={0}
                        unmask
                        value={String(item.monto_desde ?? 0)}
                        onAccept={(val) =>
                          updateItem(item._key, { monto_desde: parseNumber(val, 0) })
                        }
                        style={{ width: "100%", padding: "8px 10px", textAlign: "right" }}
                        disabled={!canEdit}
                      />
                    </TableCell>
                    <TableCell align="right" sx={{ width: 200 }}>
                      <Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
                        <Switch
                          size="small"
                          checked={!item.sin_tope}
                          onChange={(e) =>
                            updateItem(item._key, {
                              sin_tope: !e.target.checked,
                              monto_hasta: e.target.checked ? item.monto_hasta ?? 0 : null,
                            })
                          }
                          disabled={!canEdit}
                        />
                        {item.sin_tope ? (
                          <Typography variant="caption" color="text.secondary">
                            Sin tope
                          </Typography>
                        ) : (
                          <IMaskInput
                            mask={Number}
                            scale={2}
                            signed={false}
                            thousandsSeparator="."
                            radix=","
                            mapToRadix={["."]}
                            min={0}
                            unmask
                            value={String(item.monto_hasta ?? 0)}
                            onAccept={(val) =>
                              updateItem(item._key, { monto_hasta: parseNumber(val, 0) })
                            }
                            style={{
                              width: "100%",
                              padding: "8px 10px",
                              textAlign: "right",
                            }}
                            disabled={!canEdit}
                          />
                        )}
                      </Box>
                    </TableCell>
                    <TableCell align="center">
                      <Switch
                        checked={item.activo !== false}
                        onChange={(e) => updateItem(item._key, { activo: e.target.checked })}
                        disabled={!canEdit}
                      />
                    </TableCell>
                    <TableCell align="center">
                      <IconButton
                        size="small"
                        disabled={!canEdit || idx === 0}
                        onClick={() => moverNivel(item._key, -1)}
                      >
                        <Icon icon="mdi:arrow-up" width={18} />
                      </IconButton>
                      <IconButton
                        size="small"
                        disabled={!canEdit || idx === grupo.length - 1}
                        onClick={() => moverNivel(item._key, 1)}
                      >
                        <Icon icon="mdi:arrow-down" width={18} />
                      </IconButton>
                    </TableCell>
                    <TableCell align="center">
                      <IconButton
                        size="small"
                        color="error"
                        disabled={!canEdit}
                        onClick={() => removeItem(item._key)}
                      >
                        <Icon icon="mdi:delete-outline" width={18} />
                      </IconButton>
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </TableContainer>
        )}

        <Box sx={{ mt: 1.5 }}>
          <Button
            variant="outlined"
            size="small"
            startIcon={<Icon icon="mdi:plus" />}
            disabled={!canEdit}
            onClick={() => addNivel(origen)}
          >
            Agregar nivel
          </Button>
        </Box>
      </Paper>
    );
  };

  const renderMatrizAsignaciones = () => {
    if (!hasPermissionUsuariosLectura) {
      return (
        <Paper variant="outlined" sx={{ p: 1.5, mb: 2 }}>
          <Typography variant="subtitle1" sx={{ fontWeight: 700, mb: 0.5 }}>
            Asignación rápida de perfiles aprobadores
          </Typography>
          <Alert severity="info">
            No tenés permiso de lectura en Configuración de Usuarios para listar usuarios.
          </Alert>
        </Paper>
      );
    }

    return (
      <Paper variant="outlined" sx={{ p: 1.5, mb: 2 }}>
        <Box
          sx={{
            mb: 1.5,
            display: "flex",
            alignItems: "center",
            justifyContent: "space-between",
            gap: 1,
            flexWrap: "wrap",
          }}
        >
          <Box>
            <Typography variant="subtitle1" sx={{ fontWeight: 700 }}>
              Asignación rápida de perfiles aprobadores
            </Typography>
            <Typography variant="caption" color="text.secondary">
              Matriz usuario × perfil para asignar solo perfiles usados en niveles de aprobación de
              requisiciones.
            </Typography>
          </Box>
          <Stack direction="row" spacing={1}>
            <Button
              variant="outlined"
              size="small"
              startIcon={<Icon icon="mdi:refresh" />}
              disabled={loading || savingAsignaciones}
              onClick={load}
            >
              Recargar
            </Button>
            <Button
              variant="contained"
              size="small"
              startIcon={
                savingAsignaciones ? <CircularProgress size={14} color="inherit" /> : <Icon icon="mdi:content-save" />
              }
              disabled={
                !canEditarAsignaciones ||
                loading ||
                savingAsignaciones ||
                !hasCambiosAsignaciones ||
                perfilesAprobadores.length === 0
              }
              onClick={guardarAsignaciones}
            >
              Guardar asignaciones
            </Button>
          </Stack>
        </Box>

        {!canEditarAsignaciones && (
          <Alert severity="info" sx={{ mb: 1.5 }}>
            Modo solo lectura: para guardar asignaciones necesitás permisos de edición en Compras y
            Configuración de Usuarios.
          </Alert>
        )}

        {feedbackAsignaciones && (
          <Alert
            severity={feedbackAsignaciones.severity || "info"}
            onClose={() => setFeedbackAsignaciones(null)}
            sx={{ mb: 1.5 }}
          >
            {(feedbackAsignaciones.messages || []).map((m, idx) => (
              <Typography key={`asig-fb-${idx}`} variant="body2">
                {m}
              </Typography>
            ))}
          </Alert>
        )}

        {perfilesAprobadores.length === 0 ? (
          <Alert severity="warning">
            No hay perfiles de aprobación configurados. Definí primero los niveles por monto para
            habilitar la matriz.
          </Alert>
        ) : usuariosActivos.length === 0 ? (
          <Alert severity="warning">No se encontraron usuarios activos para la empresa.</Alert>
        ) : (
          <TableContainer>
            <Table size="small">
              <TableHead>
                <TableRow>
                  <TableCell sx={{ minWidth: 240 }}>Usuario</TableCell>
                  {perfilesAprobadores.map((perfil) => (
                    <TableCell key={perfil.id} align="center" sx={{ minWidth: 170 }}>
                      {perfil.label}
                    </TableCell>
                  ))}
                </TableRow>
              </TableHead>
              <TableBody>
                {usuariosActivos.map((usuario) => {
                  const userId = String(usuario?.id || "");
                  const selected = new Set(asignacionesPorUsuario[userId] || []);
                  return (
                    <TableRow key={userId}>
                      <TableCell>
                        <Box>
                          <Typography variant="body2" sx={{ fontWeight: 600 }}>
                            {`${usuario?.nombres || ""} ${usuario?.apellidos || ""}`.trim() || "Sin nombre"}
                          </Typography>
                          <Typography variant="caption" color="text.secondary">
                            @{usuario?.username || "sin-usuario"}
                          </Typography>
                        </Box>
                      </TableCell>
                      {perfilesAprobadores.map((perfil) => (
                        <TableCell key={`${userId}-${perfil.id}`} align="center">
                          <Checkbox
                            size="small"
                            checked={selected.has(perfil.id)}
                            disabled={!canEditarAsignaciones || savingAsignaciones}
                            onChange={() => toggleAsignacion(userId, perfil.id)}
                          />
                        </TableCell>
                      ))}
                    </TableRow>
                  );
                })}
              </TableBody>
            </Table>
          </TableContainer>
        )}
      </Paper>
    );
  };

  const headerActions = (
    <Stack direction="row" spacing={1} sx={{ flexWrap: "wrap", gap: 1 }}>
      <Button
        variant="outlined"
        size={embedded ? "small" : "medium"}
        startIcon={<Icon icon="mdi:account-multiple-outline" />}
        onClick={handleAdministrarPerfiles}
      >
        Administrar perfiles
      </Button>
      <Button
        variant="outlined"
        color="secondary"
        size={embedded ? "small" : "medium"}
        startIcon={<Icon icon="mdi:auto-fix" />}
        disabled={!canEdit || saving || loading || aplicandoRecomendada}
        onClick={handleAplicarRecomendada}
      >
        {aplicandoRecomendada ? "Aplicando..." : "Aplicar config. recomendada"}
      </Button>
      <Button
        variant="contained"
        color="error"
        size={embedded ? "small" : "medium"}
        startIcon={<Icon icon="mdi:refresh" />}
        disabled={saving || loading}
        onClick={load}
      >
        Recargar
      </Button>
      <Button
        variant="contained"
        color="primary"
        size={embedded ? "small" : "medium"}
        startIcon={<Icon icon="mdi:check-circle" />}
        disabled={!canEdit || saving || loading}
        onClick={handleGuardar}
      >
        {saving ? "Guardando..." : "Guardar configuración"}
      </Button>
    </Stack>
  );

  const Wrapper = embedded ? Box : Paper;
  const wrapperSx = embedded ? { p: 0 } : { p: 2 };

  return (
    <Wrapper sx={wrapperSx}>
      {!embedded && (
        <Box
          sx={{
            display: "flex",
            justifyContent: "space-between",
            alignItems: "center",
            mb: 2,
            gap: 2,
            flexWrap: "wrap",
          }}
        >
          <Box>
            <Typography variant="h6" sx={{ display: "flex", alignItems: "center", gap: 1 }}>
              <Icon icon="mdi:account-check-outline" /> Aprobaciones de Requisiciones
            </Typography>
            <Typography variant="body2" color="text.secondary">
              Definí los niveles de aprobación que se aplican al enviar requisiciones a flujo de
              aprobación. Se evalúan por monto y origen.
            </Typography>
          </Box>
          {headerActions}
        </Box>
      )}

      {feedback && (
        <Alert
          severity={feedback.severity || "info"}
          onClose={() => setFeedback(null)}
          sx={{ mb: 2 }}
        >
          {(feedback.messages || []).map((m, idx) => (
            <Typography key={`fb-${idx}`} variant="body2">
              {m}
            </Typography>
          ))}
        </Alert>
      )}

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

      {loading ? (
        <Box sx={{ display: "flex", alignItems: "center", gap: 1, py: 3 }}>
          <CircularProgress size={20} />
          <Typography variant="body2" color="text.secondary">
            Cargando configuración…
          </Typography>
        </Box>
      ) : (
        <Box>
          {renderMatrizAsignaciones()}
          {renderTablaOrigen("compra")}
          {renderTablaOrigen("gasto")}
        </Box>
      )}

      {embedded && (
        <Box sx={{ display: "flex", justifyContent: "flex-end", mt: 1.5 }}>
          {headerActions}
        </Box>
      )}

      <ConfirmDialog
        open={confirmOpen}
        loading={saving}
        title="Confirmar guardado"
        message={
          <Typography variant="body2">
            Vas a reemplazar la configuración de niveles de aprobación. Las requisiciones nuevas
            empezarán a evaluarse contra los niveles guardados. ¿Continuar?
          </Typography>
        }
        confirmText="Guardar configuración"
        cancelText="Cancelar"
        confirmColor="primary"
        onClose={() => {
          if (saving) return;
          setConfirmOpen(false);
        }}
        onConfirm={confirmGuardar}
      />

      <ConfirmDialog
        open={confirmRecomendadaOpen}
        loading={aplicandoRecomendada}
        title="Aplicar configuración recomendada"
        maxWidth="sm"
        message={
          <Box sx={{ display: "flex", flexDirection: "column", gap: 1.25 }}>
            <Typography variant="body2">
              Esto creará (si no existen) los siguientes perfiles para tu empresa:
            </Typography>
            <Typography variant="body2" component="ul" sx={{ pl: 2, m: 0 }}>
              <li>Compras Junior</li>
              <li>Compras Senior</li>
              <li>Gerente de Compras</li>
              <li>Director Financiero</li>
            </Typography>
            <Typography variant="body2">
              Y reemplazará los niveles de aprobación de Compras y Gastos por la matriz
              recomendada (4 tramos: hasta Gs. 1M, 5M, 50M y sin tope).
            </Typography>
            <Typography variant="body2" color="text.secondary">
              Los niveles existentes serán eliminados. Los perfiles ya cargados se reutilizan
              por nombre.
            </Typography>
          </Box>
        }
        confirmText="Aplicar configuración"
        cancelText="Cancelar"
        confirmColor="primary"
        onClose={() => {
          if (aplicandoRecomendada) return;
          setConfirmRecomendadaOpen(false);
        }}
        onConfirm={confirmAplicarRecomendada}
      />
    </Wrapper>
  );
}

export default RequisicionAprobacionesConfigTab;
