import {
  AccountBalance,
  AccountBalanceWallet,
  Add,
  ArrowDownward,
  ArrowUpward,
  Assignment,
  Payment,
  PointOfSale,
  TrendingUp,
} from "@mui/icons-material";
import {
  Autocomplete,
  Box,
  Button,
  Card,
  CardContent,
  Chip,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  Divider,
  Grid,
  Paper,
  Skeleton,
  Tab,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Tabs,
  TextField,
  Typography,
  useMediaQuery,
  useTheme,
} from "@mui/material";
import { useCallback, useMemo, useState } from "react";
import { useSearchParams } from "react-router-dom";
import { toast } from "sonner";
import styled from "styled-components";
import { getPosConfig } from "../api/pos-security.service";
import { ArqueoPdfModal } from "../components/tesoreria/ArqueoPdfModal";
import { CerrarCajaDialog, parseMonto } from "../components/organismos/POSDesign/CajaDesign/CerrarCajaDialog";
import { ModalPinSupervisor } from "../components/organismos/POSDesign/CajaDesign/ModalPinSupervisor";
import { RendicionesPanel } from "../components/organismos/RendicionesDesign/RendicionesPanel";
import { RendicionViaticosPage } from "./RendicionViaticosPage";
import { CxpEmpleadosPage } from "./CxpEmpleadosPage";
import { RendicionSaldosPorEmpleadoPage } from "./RendicionSaldosPorEmpleadoPage";
import { AsignacionCobranzaPanel } from "../components/organismos/VendedoresCobradoresDesign/AsignacionCobranzaPanel";
import { ComisionesWrapper } from "../components/organismos/VendedoresCobradoresDesign/ComisionesWrapper";
import { LiquidacionesPanel } from "../components/organismos/VendedoresCobradoresDesign/LiquidacionesPanel";
import { useAuthStore } from "../store/AuthStore";
import {
  useAbrirCajaMutation,
  useArqueosQuery,
  useCajasDisponiblesQuery,
  useCancelarCierreMutation,
  useCerrarCajaMutation,
  useIniciarCierreMutation,
  useMovimientosQuery,
  useRegistrarMovimientoMutation,
  useSesionesAbiertasQuery,
} from "../tanstack/TesoreriaStack";
import { TourTrigger } from "../tours/components/TourTrigger";
import { finanzasSteps } from "../tours/definitions/finanzasTour";

function TabPanel({ children, value, index }) {
  return (
    <div role="tabpanel" hidden={value !== index} style={{ height: "100%" }}>
      {value === index && <Box sx={{ pt: 2, height: "100%" }}>{children}</Box>}
    </div>
  );
}

// Definición de tabs con sus permisos requeridos (refactor seguridad — códigos 2-niveles)
const ALL_TABS = [
  {
    key: "caja_dia",
    label: "Caja del Día",
    icon: <PointOfSale />,
    modulo: "TESORERIA",
    permiso: "TES_CAJ_CAJA_VER",
    component: (permisos) => <CajaDelDiaSection canAperturaCierre={permisos.canAperturaCierre} canCrear={permisos.canCrear} />,
  },
  {
    key: "comisiones",
    label: "Comisiones",
    icon: <TrendingUp />,
    modulo: "COBRANZAS",
    permiso: "COB_COM_COMISION_VER",
    component: () => <ComisionesWrapper />,
  },
  {
    key: "liquidaciones",
    label: "Liquidaciones",
    icon: <Payment />,
    modulo: "COBRANZAS",
    permiso: "COB_COM_LIQUIDACION_VER",
    component: (permisos) => <LiquidacionesPanel canLiquidar={permisos.canLiquidar} />,
  },
  {
    key: "asignacion_cobranza",
    label: "Asignación",
    icon: <Assignment />,
    modulo: "COBRANZAS",
    permiso: "COB_ASG_ASIGNACION_VER",
    component: () => <AsignacionCobranzaPanel />,
  },
  {
    key: "rendiciones",
    label: "Rendiciones",
    icon: <AccountBalance />,
    modulo: "COBRANZAS",
    permiso: "COB_RND_RENDICION_VER",
    component: () => <RendicionesPanel />,
  },
  // Recibos, Libro Retenciones, Saldos a Favor, Revisión CxC y Hoja de Ruta
  // se migraron al módulo Cobranzas (A.3.7 Paso 4 — sidebar reorg).
  // Acceso vía: /cobranzas/recibos · /reportes (sección Cobranzas) ·
  // /cobranzas/cuentas-cobrar · /cobranzas/cobradores?tab=hoja-ruta.
  // "Cuentas a Pagar" y "Orden de Pago" se movieron al módulo Compras
  // (ComprasTemplate) — acceso vía /compras.
  {
    key: "anticipos_empleados",
    label: "Anticipos a Empleados",
    icon: <AccountBalance />,
    modulo: "RRHH",
    permiso: "RH_VIA_RENDICION_VER",
    component: () => <RendicionViaticosPage />,
  },
  {
    key: "cxp_empleados",
    label: "CxP a Empleados",
    icon: <AccountBalanceWallet />,
    modulo: "RRHH",
    permiso: "RH_VIA_RENDICION_VER",
    component: () => <CxpEmpleadosPage />,
  },
  {
    key: "saldos_viaticos_empleado",
    label: "Saldos por Empleado",
    icon: <AccountBalance />,
    modulo: "RRHH",
    permiso: "RH_VIA_RENDICION_VER",
    component: () => <RendicionSaldosPorEmpleadoPage />,
  },
];

export const Tesoreria = () => {
  const [searchParams, setSearchParams] = useSearchParams();
  const { hasPermission } = useAuthStore();
  const theme = useTheme();
  const isMobile = useMediaQuery(theme.breakpoints.down("sm"));

  // Permisos específicos para acciones internas (refactor seguridad — códigos 2-niveles)
  const permisos = useMemo(
    () => ({
      canAperturaCierre: hasPermission("TESORERIA", "TES_CAJ_CAJA_ABRIR") || hasPermission("TESORERIA", "TES_CAJ_CAJA_CERRAR"),
      canCrear: hasPermission("TESORERIA", "TES_MOV_MOVIMIENTO_CREAR"),
      canLiquidar: hasPermission("COBRANZAS", "COB_COM_LIQUIDACION_PAGAR"),
    }),
    [hasPermission],
  );

  // Filtrar tabs según permisos del usuario
  const visibleTabs = useMemo(
    () => ALL_TABS.filter((tab) => hasPermission(tab.modulo, tab.permiso)),
    [hasPermission],
  );

  const tabSlug = searchParams.get("tab") ?? "caja_dia";
  const tabValue = Math.max(
    0,
    visibleTabs.findIndex((t) => t.key === tabSlug),
  );

  return (
    <Container>
      <Paper
        id="finanzas-header"
        sx={{
          mb: { xs: 1, sm: 2 },
          p: { xs: 1.5, sm: 2 },
          display: "flex",
          alignItems: "center",
          justifyContent: "space-between",
        }}
      >
        <Box sx={{ display: "flex", alignItems: "center", gap: { xs: 1, sm: 2 } }}>
          <AccountBalance color="primary" sx={{ fontSize: { xs: 24, sm: 32 } }} />
          <Typography variant="h5" component="h1" sx={{ fontWeight: 600, fontSize: { xs: "1.1rem", sm: "1.5rem" } }}>
            Finanzas
          </Typography>
        </Box>
        <Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
          <TourTrigger steps={finanzasSteps} tourKey="finanzas" autoStart={true} />
        </Box>
      </Paper>

      {visibleTabs.length === 0 ? (
        <Paper sx={{ p: 4, textAlign: "center" }}>
          <Typography color="text.secondary">No tienes permisos para acceder a ningún módulo de Finanzas.</Typography>
        </Paper>
      ) : (
        <Paper
          sx={{
            flex: 1,
            display: "flex",
            flexDirection: "column",
            overflow: "hidden",
          }}
        >
          <Box id="finanzas-tabs" sx={{ borderBottom: 1, borderColor: "divider" }}>
            <Tabs
              value={tabValue}
              onChange={(_, v) => setSearchParams({ tab: visibleTabs[v]?.key ?? "caja_dia" }, { replace: true })}
              variant="scrollable"
              scrollButtons="auto"
              allowScrollButtonsMobile
              sx={{
                "& .MuiTab-root": {
                  minHeight: { xs: 44, sm: 56 },
                  textTransform: "none",
                  fontSize: { xs: "0.8rem", sm: "0.9rem" },
                  minWidth: { xs: "auto", sm: 110 },
                  px: { xs: 1.5, sm: 2 },
                },
              }}
            >
              {visibleTabs.map((tab) => (
                <Tab key={tab.key} icon={tab.icon} iconPosition="start" label={isMobile ? undefined : tab.label} title={tab.label} />
              ))}
            </Tabs>
          </Box>

          <Box sx={{ p: { xs: 1, sm: 2 }, flex: 1, overflow: "auto" }}>
            {visibleTabs.map((tab, index) => (
              <TabPanel key={tab.key} value={tabValue} index={index}>
                {tab.component(permisos)}
              </TabPanel>
            ))}
          </Box>
        </Paper>
      )}
    </Container>
  );
};

function CajaDelDiaSection({ canAperturaCierre, canCrear }) {
  const {
    data: sesionesAbiertas = [],
    isLoading: loadingSesiones,
    error: errorSesiones,
  } = useSesionesAbiertasQuery();
  const {
    data: cajasDisponibles = [],
    isLoading: loadingCajas,
    error: errorCajas,
  } = useCajasDisponiblesQuery();

  // Un fallo de la API (403 por falta de TES_CAJ_CAJA_VER, caída del backend)
  // dejaba estos arrays vacíos y la pantalla decía "No hay cajas abiertas",
  // indistinguible de que realmente no hubiera ninguna. Hay que mostrarlo.
  const errorCarga = errorSesiones || errorCajas;
  const abrirMutation = useAbrirCajaMutation();
  const cerrarMutation = useCerrarCajaMutation();
  const iniciarCierreMutation = useIniciarCierreMutation();
  const cancelarCierreMutation = useCancelarCierreMutation();
  const movimientoMutation = useRegistrarMovimientoMutation();

  const [selectedSesion, setSelectedSesion] = useState(null);
  const [abrirDialogOpen, setAbrirDialogOpen] = useState(false);
  const [cerrarDialogOpen, setCerrarDialogOpen] = useState(false);
  const [movDialogOpen, setMovDialogOpen] = useState(false);
  const [selectedCaja, setSelectedCaja] = useState(null);
  const [montoApertura, setMontoApertura] = useState("");
  const [montoCierre, setMontoCierre] = useState("");
  const [observaciones, setObservaciones] = useState("");
  const [movTipo, setMovTipo] = useState("ENTRADA");
  const [movMonto, setMovMonto] = useState("");
  const [movConcepto, setMovConcepto] = useState("");

  // Fase 1: estado de autorización
  const [showPinModal, setShowPinModal] = useState(false);
  const [pinOperacion, setPinOperacion] = useState(null);
  const [tokenAutorizacion, setTokenAutorizacion] = useState(null);
  const [posConfig, setPosConfig] = useState(null);
  const [pendingArqueoDetalle, setPendingArqueoDetalle] = useState(null);
  const [pdfSesionId, setPdfSesionId] = useState(null);

  const cargarConfig = async (cajaId) => {
    try {
      const config = await getPosConfig(cajaId);
      setPosConfig(config);
      return config;
    } catch {
      setPosConfig(null);
      return null;
    }
  };

  const handleAbrir = async (token) => {
    if (!selectedCaja) {
      toast.warning("Seleccioná una caja antes de abrir");
      return;
    }
    const montoNum = montoApertura === "" || montoApertura == null ? 0 : parseFloat(montoApertura);
    if (Number.isNaN(montoNum) || montoNum < 0) {
      toast.warning("El monto inicial debe ser un número mayor o igual a 0");
      return;
    }
    const authToken = typeof token === "string" ? token : tokenAutorizacion;
    // Cargar config si no está cargada
    let config = posConfig;
    if (!config || config._caja_id !== selectedCaja.id) {
      config = await cargarConfig(selectedCaja.id);
    }
    // Verificar si requiere autorización
    if (config?.requiere_autorizacion_apertura && !authToken) {
      setPinOperacion("apertura_caja");
      setShowPinModal(true);
      return;
    }
    abrirMutation.mutate(
      {
        caja_id: selectedCaja.id,
        monto_apertura: montoNum,
        token_autorizacion: authToken || undefined,
      },
      {
        onSuccess: () => {
          setAbrirDialogOpen(false);
          setSelectedCaja(null);
          setMontoApertura("");
          setTokenAutorizacion(null);
        },
      },
    );
  };

  const handleCerrar = async (tokenOrEvent, arqueoDetalle) => {
    if (!selectedSesion) return;
    // Guardar arqueoDetalle si viene (para recuperarlo tras PIN)
    if (arqueoDetalle) {
      setPendingArqueoDetalle(arqueoDetalle);
    }
    const token = typeof tokenOrEvent === "string" ? tokenOrEvent : null;
    const authToken = token || tokenAutorizacion;
    // Cargar config si no está cargada
    let config = posConfig;
    if (!config && selectedSesion?.caja_id) {
      config = await cargarConfig(selectedSesion.caja_id);
    }
    // Verificar si requiere autorización
    if (config?.requiere_autorizacion_cierre && !authToken) {
      setPinOperacion("cierre_caja");
      setShowPinModal(true);
      return;
    }
    const detalle = arqueoDetalle || pendingArqueoDetalle;
    // parseMonto y no parseInt(replace(/\D/g)): ese replace borra el separador
    // decimal. En prod, "2.592.999,99" se envió como 259.299.999 y el backend
    // rechazó el cierre por una "diferencia" de 256.706.999,01 que la pantalla
    // no mostraba (decía "Sin diferencia"). Los POS ya usaban parseMonto.
    const monto = parseMonto(montoCierre);
    cerrarMutation.mutate(
      {
        sesion_id: selectedSesion.id,
        data: {
          monto_cierre: monto,
          observaciones: observaciones || null,
          token_autorizacion: authToken || undefined,
          arqueo_detalle: detalle || undefined,
        },
      },
      {
        onSuccess: () => {
          const sesionCerradaId = selectedSesion.id;
          setCerrarDialogOpen(false);
          setMontoCierre("");
          setObservaciones("");
          setSelectedSesion(null);
          setTokenAutorizacion(null);
          setPendingArqueoDetalle(null);
          setPdfSesionId(sesionCerradaId);
        },
      },
    );
  };

  const handlePinSuccess = useCallback(
    (data) => {
      setTokenAutorizacion(data.token);
      setShowPinModal(false);
      if (pinOperacion === "apertura_caja") {
        setTimeout(() => handleAbrir(data.token), 100);
      } else if (pinOperacion === "cierre_caja") {
        setTimeout(() => handleCerrar(data.token), 100);
      }
    },
    [pinOperacion],
  );

  const handleMovimiento = () => {
    if (!movMonto) return;
    movimientoMutation.mutate(
      {
        tipo: movTipo,
        monto: parseFloat(movMonto),
        concepto: movConcepto || `${movTipo === "ENTRADA" ? "Entrada" : "Salida"} manual`,
      },
      {
        onSuccess: () => {
          setMovDialogOpen(false);
          setMovMonto("");
          setMovConcepto("");
        },
      },
    );
  };

  const formatMoney = (num) => {
    return new Intl.NumberFormat("es-PY").format(num || 0);
  };

  const cajasLibres = cajasDisponibles.filter((c) => !c.en_uso);

  if (loadingSesiones || loadingCajas) {
    return (
      <Box sx={{ display: "flex", flexDirection: "column", gap: 2 }}>
        {[1, 2].map((i) => (
          <Card key={i} sx={{ p: 2 }}>
            <Skeleton variant="text" width="60%" height={28} />
            <Skeleton variant="text" width="40%" height={20} sx={{ mt: 1 }} />
            <Skeleton variant="rectangular" height={60} sx={{ mt: 1, borderRadius: 1 }} />
          </Card>
        ))}
      </Box>
    );
  }

  return (
    <Box>
      <Grid container spacing={2}>
        {/* Panel izquierdo - Lista de cajas abiertas */}
        <Grid item xs={12} md={5} lg={4}>
          <Box
            sx={{
              display: "flex",
              flexDirection: "column",
              height: "100%",
              gap: 2,
            }}
          >
            {/* Cajas abiertas */}
            {sesionesAbiertas.length > 0 ? (
              sesionesAbiertas.map((sesion) => {
                const isSelected = selectedSesion?.id === sesion.id;
                const saldoActual = sesion.saldo_actual || 0;

                return (
                  <Card
                    key={sesion.id}
                    sx={{
                      cursor: "pointer",
                      border: isSelected ? "2px solid" : "1px solid",
                      borderColor: isSelected ? "primary.main" : "divider",
                      transition: "all 0.2s",
                      "&:hover": { borderColor: "primary.light" },
                    }}
                    onClick={() => setSelectedSesion(sesion)}
                  >
                    <CardContent sx={{ p: 2, "&:last-child": { pb: 2 } }}>
                      <Box
                        sx={{
                          display: "flex",
                          justifyContent: "space-between",
                          alignItems: "center",
                          mb: 1,
                          flexWrap: "wrap",
                          gap: 1,
                        }}
                      >
                        <Typography variant="subtitle1" fontWeight={600}>
                          {sesion.cajas?.descripcion || "Caja"}
                        </Typography>
                        {canAperturaCierre && !sesion.bloqueado && (
                          <Button
                            variant="contained"
                            color="error"
                            size="small"
                            disabled={iniciarCierreMutation.isPending}
                            onClick={async (e) => {
                              e.stopPropagation();
                              setSelectedSesion(sesion);
                              iniciarCierreMutation.mutate(sesion.id, {
                                onSuccess: async () => {
                                  if (sesion.caja_id) {
                                    await cargarConfig(sesion.caja_id);
                                  }
                                  setCerrarDialogOpen(true);
                                },
                              });
                            }}
                          >
                            {iniciarCierreMutation.isPending ? "Bloqueando..." : "Cerrar Caja"}
                          </Button>
                        )}
                        {canAperturaCierre && sesion.bloqueado && sesion.estado_cierre === "en_proceso" && (
                          <Box sx={{ display: "flex", gap: 0.5 }}>
                            <Button
                              variant="contained"
                              color="warning"
                              size="small"
                              onClick={async (e) => {
                                e.stopPropagation();
                                setSelectedSesion(sesion);
                                if (sesion.caja_id) {
                                  await cargarConfig(sesion.caja_id);
                                }
                                setCerrarDialogOpen(true);
                              }}
                            >
                              Continuar Cierre
                            </Button>
                            <Button
                              variant="outlined"
                              color="inherit"
                              size="small"
                              disabled={cancelarCierreMutation.isPending}
                              onClick={(e) => {
                                e.stopPropagation();
                                cancelarCierreMutation.mutate({
                                  sesion_id: sesion.id,
                                  token_autorizacion: tokenAutorizacion,
                                });
                              }}
                            >
                              Cancelar
                            </Button>
                          </Box>
                        )}
                      </Box>
                      <Chip label={sesion.bloqueado ? "EN CIERRE" : "ABIERTA"} color={sesion.bloqueado ? "warning" : "success"} size="small" sx={{ mb: 1.5 }} />

                      <Grid container spacing={1}>
                        <Grid item xs={6}>
                          <Typography variant="caption" color="text.secondary">
                            Monto Apertura
                          </Typography>
                          <Typography variant="body2" fontWeight={600}>
                            ₲ {formatMoney(sesion.monto_apertura)}
                          </Typography>
                        </Grid>
                        <Grid item xs={6}>
                          <Typography variant="caption" color="text.secondary">
                            Ventas Efectivo
                          </Typography>
                          <Typography variant="body2" fontWeight={600} color="success.main">
                            ₲ {formatMoney(sesion.monto_ventas_efectivo)}
                          </Typography>
                        </Grid>
                        <Grid item xs={6}>
                          <Typography variant="caption" color="text.secondary">
                            Ventas Tarjeta
                          </Typography>
                          <Typography variant="body2" fontWeight={600} color="info.main">
                            ₲ {formatMoney(sesion.monto_ventas_tarjeta)}
                          </Typography>
                        </Grid>
                        <Grid item xs={6}>
                          <Typography variant="caption" color="text.secondary">
                            Ventas Transferencia
                          </Typography>
                          <Typography variant="body2" fontWeight={600} color="info.main">
                            ₲ {formatMoney(sesion.monto_ventas_transferencia)}
                          </Typography>
                        </Grid>
                        <Grid item xs={6}>
                          <Typography variant="caption" color="text.secondary">
                            Entradas Manuales
                          </Typography>
                          <Typography variant="body2" fontWeight={600} color="success.main">
                            ₲ {formatMoney(sesion.monto_entradas_manual)}
                          </Typography>
                        </Grid>
                        <Grid item xs={6}>
                          <Typography variant="caption" color="text.secondary">
                            Salidas Manuales
                          </Typography>
                          <Typography variant="body2" fontWeight={600} color="error.main">
                            ₲ {formatMoney(sesion.monto_salidas_manual)}
                          </Typography>
                        </Grid>
                      </Grid>

                      <Divider sx={{ my: 1.5 }} />

                      <Box
                        sx={{
                          display: "flex",
                          justifyContent: "space-between",
                          alignItems: "center",
                          flexWrap: "wrap",
                          gap: 1,
                        }}
                      >
                        <Typography variant="body1" fontWeight={700} sx={{ fontSize: { xs: "0.9rem", sm: "1rem" } }}>
                          Saldo Actual: ₲ {formatMoney(saldoActual)}
                        </Typography>
                        {canCrear && (
                          <Box sx={{ display: "flex", gap: 0.5 }}>
                            <Button
                              variant="outlined"
                              color="success"
                              size="small"
                              startIcon={<ArrowDownward />}
                              onClick={(e) => {
                                e.stopPropagation();
                                setMovTipo("ENTRADA");
                                setMovDialogOpen(true);
                              }}
                            >
                              Entrada
                            </Button>
                            <Button
                              variant="outlined"
                              color="error"
                              size="small"
                              startIcon={<ArrowUpward />}
                              onClick={(e) => {
                                e.stopPropagation();
                                setMovTipo("SALIDA");
                                setMovDialogOpen(true);
                              }}
                            >
                              Salida
                            </Button>
                          </Box>
                        )}
                      </Box>
                    </CardContent>
                  </Card>
                );
              })
            ) : (
              <Card sx={{ p: 3, textAlign: "center" }}>
                <PointOfSale sx={{ fontSize: 48, color: "text.disabled", mb: 1 }} />
                {errorCarga ? (
                  <>
                    <Typography variant="body1" color="error">
                      No se pudieron cargar las cajas
                    </Typography>
                    <Typography variant="body2" color="text.secondary" sx={{ mt: 0.5 }}>
                      {errorCarga?.response?.status === 403
                        ? "Tu perfil no tiene el permiso para ver cajas (Tesorería › Ver caja)."
                        : errorCarga?.response?.data?.message ||
                          errorCarga?.message ||
                          "Error de conexión con el servidor."}
                    </Typography>
                  </>
                ) : (
                  <Typography variant="body1" color="text.secondary">
                    No hay cajas abiertas
                  </Typography>
                )}
              </Card>
            )}

            {/* Botón para abrir nueva caja */}
            {canAperturaCierre && (
              <Button variant="contained" startIcon={<Add />} onClick={() => setAbrirDialogOpen(true)} disabled={cajasLibres.length === 0} sx={{ mt: "auto" }}>
                Abrir Nueva Caja
              </Button>
            )}
          </Box>
        </Grid>

        {/* Panel derecho - Movimientos de la caja seleccionada */}
        <Grid item xs={12} md={7} lg={8}>
          <Card
            sx={{
              display: "flex",
              flexDirection: "column",
              minHeight: { xs: 200, md: 400 },
            }}
          >
            <CardContent
              sx={{
                flex: 1,
                display: "flex",
                flexDirection: "column",
                overflow: "hidden",
              }}
            >
              <Typography variant="h6" fontWeight={600} sx={{ mb: 2 }}>
                Últimos Movimientos
                {selectedSesion && ` - ${selectedSesion.cajas?.descripcion || "Caja"}`}
              </Typography>

              <Box sx={{ flex: 1, overflow: "auto" }}>
                {selectedSesion ? (
                  selectedSesion.movimiento_cajas?.length > 0 ? (
                    selectedSesion.movimiento_cajas.map((mov) => (
                      <Box
                        key={mov.id}
                        sx={{
                          display: "flex",
                          justifyContent: "space-between",
                          alignItems: "center",
                          py: 1.5,
                          px: 1,
                          borderBottom: "1px solid",
                          borderColor: "divider",
                          "&:hover": { bgcolor: "action.hover" },
                        }}
                      >
                        <Box>
                          <Typography variant="body2" fontWeight={500}>
                            {mov.descripcion || "Movimiento"}
                          </Typography>
                          <Typography variant="caption" color="text.secondary">
                            {mov.fecha_mov ? new Date(mov.fecha_mov).toLocaleString("es-PY") : "-"}
                          </Typography>
                        </Box>
                        <Typography variant="body1" fontWeight={600} color={mov.tipo_movimiento_cajas?.descripcion?.toLowerCase().includes("entrada") ? "success.main" : "error.main"}>
                          {mov.tipo_movimiento_cajas?.descripcion?.toLowerCase().includes("entrada") ? "+" : "-"}₲ {formatMoney(mov.monto)}
                        </Typography>
                      </Box>
                    ))
                  ) : (
                    <Box sx={{ textAlign: "center", py: 4 }}>
                      <Typography variant="body2" color="text.secondary">
                        Sin movimientos
                      </Typography>
                    </Box>
                  )
                ) : (
                  <Box sx={{ textAlign: "center", py: 4 }}>
                    <Typography variant="body2" color="text.secondary">
                      Selecciona una caja para ver sus movimientos
                    </Typography>
                  </Box>
                )}
              </Box>
            </CardContent>
          </Card>
        </Grid>
      </Grid>

      {/* Dialog Abrir Caja */}
      <Dialog open={abrirDialogOpen} onClose={() => setAbrirDialogOpen(false)} maxWidth="sm" fullWidth>
        <DialogTitle>Abrir Caja</DialogTitle>
        <DialogContent>
          <Box sx={{ mt: 2, display: "flex", flexDirection: "column", gap: 2 }}>
            <Autocomplete
              options={cajasLibres}
              getOptionLabel={(opt) => opt.descripcion || "Caja"}
              value={selectedCaja}
              onChange={(_, v) => setSelectedCaja(v)}
              renderInput={(params) => <TextField {...params} label="Seleccionar Caja" />}
            />
            <TextField fullWidth label="Monto Inicial" type="number" value={montoApertura} onChange={(e) => setMontoApertura(e.target.value)} placeholder="Ej: 500000" />
          </Box>
        </DialogContent>
        <DialogActions sx={{ p: 2 }}>
          <Button onClick={() => setAbrirDialogOpen(false)}>Cancelar</Button>
          <Button variant="contained" onClick={handleAbrir} disabled={abrirMutation.isPending || !selectedCaja}>
            {abrirMutation.isPending ? "Abriendo..." : "Abrir Caja"}
          </Button>
        </DialogActions>
      </Dialog>

      {/* Dialog Cerrar Caja con Arqueo */}
      <CerrarCajaDialog
        open={cerrarDialogOpen}
        onClose={() => setCerrarDialogOpen(false)}
        sesionCaja={selectedSesion}
        cajaDescripcion={selectedSesion?.cajas?.descripcion || "Caja"}
        mediosPago={[]}
        montoCierre={montoCierre}
        setMontoCierre={setMontoCierre}
        observacionesCierre={observaciones}
        setObservacionesCierre={setObservaciones}
        onCerrarCaja={handleCerrar}
        isLoading={cerrarMutation.isPending}
        requiereArqueo={!!posConfig?.requiere_arqueo_cierre}
      />

      {/* Dialog Movimiento */}
      <Dialog open={movDialogOpen} onClose={() => setMovDialogOpen(false)} maxWidth="sm" fullWidth>
        <DialogTitle>{movTipo === "ENTRADA" ? "Registrar Entrada" : "Registrar Salida"}</DialogTitle>
        <DialogContent>
          <Box sx={{ mt: 2, display: "flex", flexDirection: "column", gap: 2 }}>
            <TextField
              fullWidth
              label="Monto"
              type="number"
              value={movMonto}
              onChange={(e) => setMovMonto(e.target.value)}
              error={!movMonto}
              helperText={!movMonto ? "El monto es requerido" : ""}
              required
              autoFocus
            />
            <TextField
              fullWidth
              label="Concepto"
              value={movConcepto}
              onChange={(e) => setMovConcepto(e.target.value)}
              placeholder={movTipo === "ENTRADA" ? "Ej: Cobro de deuda" : "Ej: Pago a proveedor"}
            />
          </Box>
        </DialogContent>
        <DialogActions sx={{ p: 2 }}>
          <Button onClick={() => setMovDialogOpen(false)}>Cancelar</Button>
          <Button variant="contained" color={movTipo === "ENTRADA" ? "success" : "error"} onClick={handleMovimiento} disabled={movimientoMutation.isPending || !movMonto}>
            {movimientoMutation.isPending ? "Guardando..." : "Guardar"}
          </Button>
        </DialogActions>
      </Dialog>

      {/* Modal PDF Arqueo (auto-abre al cerrar caja) */}
      <ArqueoPdfModal
        open={!!pdfSesionId}
        sesionId={pdfSesionId}
        onClose={() => setPdfSesionId(null)}
        titulo="Arqueo de Cierre"
      />

      {/* Fase 1: Modal PIN Supervisor */}
      <ModalPinSupervisor
        open={showPinModal}
        onClose={() => setShowPinModal(false)}
        onSuccess={handlePinSuccess}
        tipoOperacion={pinOperacion || "apertura_caja"}
        contexto={{ caja_id: selectedCaja?.id || selectedSesion?.caja_id }}
      />
    </Box>
  );
}

function MovimientosSection() {
  const { data: movimientos = [], isLoading } = useMovimientosQuery();

  const formatMoney = (num) => new Intl.NumberFormat("es-PY").format(num || 0);
  const formatFecha = (fecha) => {
    if (!fecha) return "-";
    // La fecha puede venir como string, Date object, o ISO string
    let dateObj;
    if (fecha instanceof Date) {
      dateObj = fecha;
    } else if (typeof fecha === "string") {
      dateObj = new Date(fecha);
    } else {
      return "-";
    }
    // Si la fecha es inválida, retornar "-"
    if (isNaN(dateObj.getTime())) {
      return "-";
    }
    const day = String(dateObj.getUTCDate()).padStart(2, "0");
    const month = String(dateObj.getUTCMonth() + 1).padStart(2, "0");
    const year = dateObj.getUTCFullYear();
    const hours = String(dateObj.getUTCHours()).padStart(2, "0");
    const minutes = String(dateObj.getUTCMinutes()).padStart(2, "0");
    return `${day}/${month}/${year} ${hours}:${minutes}`;
  };

  return (
    <Paper sx={{ p: { xs: 1, sm: 2 } }}>
      <Typography variant="h6" sx={{ mb: 2, fontSize: { xs: "1rem", sm: "1.25rem" } }}>
        Movimientos de Caja
      </Typography>

      <TableContainer sx={{ overflowX: "auto" }}>
        <Table size="small" sx={{ minWidth: 500 }}>
          <TableHead>
            <TableRow>
              <TableCell>Fecha</TableCell>
              <TableCell>Caja</TableCell>
              <TableCell>Tipo</TableCell>
              <TableCell>Concepto</TableCell>
              <TableCell align="right">Monto</TableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            {isLoading ? (
              <TableRow>
                <TableCell colSpan={5} align="center">
                  Cargando...
                </TableCell>
              </TableRow>
            ) : movimientos.length === 0 ? (
              <TableRow>
                <TableCell colSpan={5} align="center">
                  <Typography color="text.secondary" sx={{ py: 2 }}>
                    No hay movimientos registrados
                  </Typography>
                </TableCell>
              </TableRow>
            ) : (
              movimientos.map((mov) => (
                <TableRow key={mov.id} hover>
                  <TableCell>{formatFecha(mov.fecha_mov)}</TableCell>
                  <TableCell>{mov.sesiones_caja?.cajas?.descripcion || "-"}</TableCell>
                  <TableCell>
                    <Chip
                      label={mov.tipo_movimiento_cajas?.descripcion || "Movimiento"}
                      size="small"
                      color={mov.tipo_movimiento_cajas?.descripcion?.includes("Entrada") ? "success" : "error"}
                      variant="outlined"
                    />
                  </TableCell>
                  <TableCell>{mov.descripcion}</TableCell>
                  <TableCell align="right">
                    <Typography fontWeight={600}>₲ {formatMoney(mov.monto)}</Typography>
                  </TableCell>
                </TableRow>
              ))
            )}
          </TableBody>
        </Table>
      </TableContainer>
    </Paper>
  );
}

function ArqueosSection() {
  const [page, setPage] = useState(1);
  const { data: arqueosData, isLoading } = useArqueosQuery(page, 20);
  const arqueos = arqueosData?.items || [];

  const formatMoney = (num) => new Intl.NumberFormat("es-PY").format(num || 0);
  const formatFecha = (fecha) => {
    if (!fecha) return "-";
    // La fecha puede venir como string, Date object, o ISO string
    let dateObj;
    if (fecha instanceof Date) {
      dateObj = fecha;
    } else if (typeof fecha === "string") {
      dateObj = new Date(fecha);
    } else {
      return "-";
    }
    // Si la fecha es inválida, retornar "-"
    if (isNaN(dateObj.getTime())) {
      return "-";
    }
    const day = String(dateObj.getUTCDate()).padStart(2, "0");
    const month = String(dateObj.getUTCMonth() + 1).padStart(2, "0");
    const year = dateObj.getUTCFullYear();
    return `${day}/${month}/${year}`;
  };

  return (
    <Paper sx={{ p: { xs: 1, sm: 2 } }}>
      <Typography variant="h6" sx={{ mb: 2, fontSize: { xs: "1rem", sm: "1.25rem" } }}>
        Historial de Arqueos
      </Typography>

      <TableContainer sx={{ overflowX: "auto" }}>
        <Table size="small" sx={{ minWidth: 600 }}>
          <TableHead>
            <TableRow>
              <TableCell>Fecha</TableCell>
              <TableCell>Caja</TableCell>
              <TableCell align="right">Total Sistema</TableCell>
              <TableCell align="right">Total Contado</TableCell>
              <TableCell align="right">Diferencia</TableCell>
              <TableCell>Observación</TableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            {isLoading ? (
              <TableRow>
                <TableCell colSpan={6} align="center">
                  Cargando...
                </TableCell>
              </TableRow>
            ) : arqueos.length === 0 ? (
              <TableRow>
                <TableCell colSpan={6} align="center">
                  <Typography color="text.secondary" sx={{ py: 2 }}>
                    No hay arqueos registrados
                  </Typography>
                </TableCell>
              </TableRow>
            ) : (
              arqueos.map((arq) => (
                <TableRow key={arq.id} hover>
                  <TableCell>{formatFecha(arq.fecha)}</TableCell>
                  <TableCell>{arq.cajas?.descripcion || "-"}</TableCell>
                  <TableCell align="right">₲ {formatMoney(arq.total_sistema)}</TableCell>
                  <TableCell align="right">₲ {formatMoney(arq.total_contado)}</TableCell>
                  <TableCell align="right">
                    <Typography fontWeight={600} color={Number(arq.diferencia) === 0 ? "success.main" : Number(arq.diferencia) > 0 ? "info.main" : "error.main"}>
                      ₲ {formatMoney(arq.diferencia)}
                    </Typography>
                  </TableCell>
                  <TableCell>
                    <Typography variant="body2" noWrap sx={{ maxWidth: 200 }}>
                      {arq.observacion || "-"}
                    </Typography>
                  </TableCell>
                </TableRow>
              ))
            )}
          </TableBody>
        </Table>
      </TableContainer>

      {arqueosData?.totalPages > 1 && (
        <Box sx={{ display: "flex", justifyContent: "center", mt: 2, gap: 1 }}>
          <Button disabled={page === 1} onClick={() => setPage(page - 1)}>
            Anterior
          </Button>
          <Typography sx={{ alignSelf: "center" }}>
            Página {page} de {arqueosData.totalPages}
          </Typography>
          <Button disabled={page >= arqueosData.totalPages} onClick={() => setPage(page + 1)}>
            Siguiente
          </Button>
        </Box>
      )}
    </Paper>
  );
}

const Container = styled.div`
  /* min-height (no height fija) → crece con el contenido; único scroll = el del body. */
  min-height: calc(100vh - 50px);
  margin-top: 50px;
  padding: 15px;
  display: flex;
  flex-direction: column;

  @media (max-width: 600px) {
    padding: 8px;
    margin-top: 40px;
    min-height: calc(100vh - 40px);
  }
`;
