import {
  AttachMoney,
  CheckCircle,
  Close,
  FilterList,
  Person,
  Print,
  Receipt,
  Refresh,
  Schedule,
  Search,
  Warning,
} from "@mui/icons-material";
import {
  Alert,
  Box,
  Button,
  Chip,
  Dialog,
  DialogContent,
  DialogTitle,
  IconButton,
  InputAdornment,
  LinearProgress,
  MenuItem,
  Paper,
  Skeleton,
  Tab,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  TableSortLabel,
  Tabs,
  TextField,
  Tooltip,
  Typography,
  useMediaQuery,
  useTheme,
} from "@mui/material";
import { Icon } from "@iconify/react";
import { useQuery } from "@tanstack/react-query";
import { useMemo, useState } from "react";
import { useNavigate } from "react-router-dom";
import { toast } from "sonner";
import styled from "styled-components";
import {
  getCobrosHistorialCliente,
  getCuentasCobrarDashboard,
  getCuentasCobrarPorCliente,
  getCuentasCobrarResumen,
  getCuotasPendientes,
} from "../api/cobros.service";
import { AccesoRestringido } from "../components/common/AccesoRestringido";
import { EstadoCuentaPdfModal } from "../components/organismos/EstadoCuentaPdfModal";
import { DetalleMensualExportDialog } from "../components/cobranzas/DetalleMensualExportDialog";
import { getCobMoraEstadoChip } from "../components/_standards/enums/estados";
import { usePermission } from "../hooks/usePermission";
import * as XLSX from "xlsx";
import { sanitizeRecords } from "../components/_standards";

const formatMoney = (num) =>
  new Intl.NumberFormat("es-PY").format(Math.round(num || 0));

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

// ==================== AGING BUCKET COLORS ====================
const BUCKET_CONFIG = [
  { key: "al_dia", label: "Al día", color: "#22c55e", bgLight: "#f0fdf4" },
  { key: "de_1_a_30", label: "1-30 días", color: "#eab308", bgLight: "#fefce8" },
  { key: "de_31_a_60", label: "31-60 días", color: "#f97316", bgLight: "#fff7ed" },
  { key: "de_61_a_90", label: "61-90 días", color: "#ef4444", bgLight: "#fef2f2" },
  { key: "mas_de_90", label: "90+ días", color: "#991b1b", bgLight: "#fef2f2" },
];

// ==================== AGING BUCKETS PANEL ====================
function AgingBucketsPanel({ data, isLoading, totalClientes = 0 }) {
  const theme = useTheme();

  if (isLoading || !data) {
    return (
      <Paper elevation={0} sx={{ p: 2, borderRadius: 2, border: "1px solid", borderColor: "divider", mb: 2 }}>
        <Skeleton variant="rectangular" height={100} sx={{ borderRadius: 2 }} />
      </Paper>
    );
  }

  const { aging_buckets, total_pendiente, total_vencido, total_al_dia, clientes_morosos, cuotas_total, total_mora_proyectada, mora_activa, total_cobrado } = data;
  const total = total_pendiente || 1;
  const pctVencido = total_pendiente > 0 ? Math.round((total_vencido / total_pendiente) * 100) : 0;
  const extraCols = (mora_activa ? 1 : 0) + (total_cobrado > 0 ? 1 : 0);
  const baseCols = 4 + extraCols;
  const kpiCols = { xs: "repeat(2, 1fr)", sm: "repeat(3, 1fr)", md: `repeat(${baseCols}, 1fr)` };

  return (
    <Paper elevation={0} sx={{ p: { xs: 1.5, sm: 2 }, borderRadius: 2, border: "1px solid", borderColor: "divider", mb: 2 }}>
      {/* KPIs principales */}
      <Box sx={{ display: "grid", gridTemplateColumns: kpiCols, gap: 1.5, mb: 2 }}>
        <Paper elevation={0} sx={{ textAlign: "center", p: 1.5, borderRadius: 2, border: "1px solid", borderColor: "divider" }}>
          <Typography variant="caption" color="text.secondary">Total Pendiente</Typography>
          <Typography variant="h6" fontWeight={700} color="primary.main" sx={{ fontSize: { xs: "1rem", sm: "1.2rem" } }}>
            ₲ {formatMoney(total_pendiente)}
          </Typography>
          <Typography variant="caption" color="text.secondary">{cuotas_total} cuotas</Typography>
        </Paper>
        <Paper elevation={0} sx={{ textAlign: "center", p: 1.5, borderRadius: 2, border: "1px solid", borderColor: "error.main", borderLeftWidth: 3 }}>
          <Typography variant="caption" color="text.secondary">Vencido</Typography>
          <Typography variant="h6" fontWeight={700} color="error.main" sx={{ fontSize: { xs: "1rem", sm: "1.2rem" } }}>
            ₲ {formatMoney(total_vencido)}
          </Typography>
          <Typography variant="caption" color="error.main" fontWeight={600}>{pctVencido}% del total</Typography>
        </Paper>
        <Paper elevation={0} sx={{ textAlign: "center", p: 1.5, borderRadius: 2, border: "1px solid", borderColor: "success.main", borderLeftWidth: 3 }}>
          <Typography variant="caption" color="text.secondary">Al Día</Typography>
          <Typography variant="h6" fontWeight={700} color="success.main" sx={{ fontSize: { xs: "1rem", sm: "1.2rem" } }}>
            ₲ {formatMoney(total_al_dia)}
          </Typography>
          <Typography variant="caption" color="success.main" fontWeight={600}>{100 - pctVencido}% del total</Typography>
        </Paper>
        <Paper elevation={0} sx={{ textAlign: "center", p: 1.5, borderRadius: 2, border: "1px solid", borderColor: "divider" }}>
          <Typography variant="caption" color="text.secondary">Clientes con Deuda</Typography>
          <Typography variant="h6" fontWeight={700} color="primary.main" sx={{ fontSize: { xs: "1rem", sm: "1.2rem" } }}>
            {totalClientes || clientes_morosos}
          </Typography>
          <Box sx={{ display: "flex", alignItems: "center", justifyContent: "center", gap: 0.5, flexWrap: "wrap" }}>
            <Typography variant="caption" color="error.main" fontWeight={600}>{clientes_morosos} morosos</Typography>
            {totalClientes > 0 && clientes_morosos < totalClientes && (
              <Typography variant="caption" color="text.secondary">· {totalClientes - clientes_morosos} al día</Typography>
            )}
          </Box>
        </Paper>
        {total_cobrado > 0 && (
          <Paper elevation={0} sx={{ textAlign: "center", p: 1.5, borderRadius: 2, border: "1px solid", borderColor: "success.dark", borderLeftWidth: 3, bgcolor: "success.50" }}>
            <Typography variant="caption" color="text.secondary">Total Cobrado</Typography>
            <Typography variant="h6" fontWeight={700} color="success.dark" sx={{ fontSize: { xs: "1rem", sm: "1.2rem" } }}>
              ₲ {formatMoney(total_cobrado)}
            </Typography>
            <Typography variant="caption" color="success.dark" fontWeight={500}>acumulado histórico</Typography>
          </Paper>
        )}
        {mora_activa && (
          <Tooltip title="Interés proyectado sobre las cuotas vencidas con la configuración de mora actual. Es estimado — el monto real se calcula al cobrar." arrow>
            <Paper elevation={0} sx={{ textAlign: "center", p: 1.5, borderRadius: 2, border: "1px solid", borderColor: "warning.main", borderLeftWidth: 3, cursor: "default" }}>
              <Typography variant="caption" color="text.secondary">Mora Proyectada</Typography>
              <Typography variant="h6" fontWeight={700} color="warning.dark" sx={{ fontSize: { xs: "1rem", sm: "1.2rem" } }}>
                ₲ {formatMoney(total_mora_proyectada)}
              </Typography>
              <Typography variant="caption" color="text.secondary">sobre cuotas vencidas</Typography>
            </Paper>
          </Tooltip>
        )}
      </Box>

      {/* Aging Buckets - Barra + Detalle */}
      <Box sx={{ display: "flex", alignItems: "center", gap: 0.5, mb: 0.5 }}>
        <Typography variant="caption" color="text.secondary" fontWeight={600} sx={{ textTransform: "uppercase", letterSpacing: 0.5 }}>
          Antigüedad de Deuda
        </Typography>
        <Tooltip
          title="Muestra cómo se distribuye la deuda según el tiempo de vencimiento. Verde = al día, Amarillo = 1-30 días vencido, Naranja = 31-60 días, Rojo = 61-90 días, Rojo oscuro = más de 90 días. Si la barra tiene mucho rojo, la cartera está envejeciendo y necesita atención urgente."
          arrow
          placement="right"
          slotProps={{ tooltip: { sx: { maxWidth: 280, fontSize: "0.75rem", lineHeight: 1.4 } } }}
        >
          <IconButton size="small" sx={{ p: 0.25, color: "text.secondary", opacity: 0.6 }}>
            <Icon icon="lucide:info" style={{ width: 14, height: 14 }} />
          </IconButton>
        </Tooltip>
      </Box>

      {/* Barra proporcional */}
      <Box sx={{ display: "flex", height: 12, borderRadius: 1.5, overflow: "hidden", bgcolor: "action.hover", mb: 1 }}>
        {BUCKET_CONFIG.map((cfg) => {
          const bucket = aging_buckets[cfg.key];
          const pct = bucket ? (bucket.monto / total) * 100 : 0;
          return pct > 0 ? (
            <Tooltip key={cfg.key} title={`${cfg.label}: ₲ ${formatMoney(bucket.monto)} (${bucket.cantidad} cuotas)`}>
              <Box sx={{ width: `${pct}%`, bgcolor: cfg.color, minWidth: pct > 0 ? "3px" : 0, transition: "width 0.3s" }} />
            </Tooltip>
          ) : null;
        })}
      </Box>

      {/* Detalle por bucket */}
      <Box sx={{ display: "flex", gap: 0.5, flexWrap: "wrap" }}>
        {BUCKET_CONFIG.map((cfg) => {
          const bucket = aging_buckets[cfg.key];
          if (!bucket || bucket.cantidad === 0) return null;
          return (
            <Chip
              key={cfg.key}
              size="small"
              label={`${cfg.label}: ₲ ${formatMoney(bucket.monto)} (${bucket.cantidad})`}
              sx={{
                bgcolor: `${cfg.color}15`,
                color: cfg.color,
                fontWeight: 600,
                fontSize: "0.7rem",
                borderLeft: `3px solid ${cfg.color}`,
                borderRadius: "4px",
              }}
            />
          );
        })}
      </Box>
    </Paper>
  );
}

// ==================== PROXIMOS VENCIMIENTOS ====================
const VENC_PRESETS = [
  { label: "Mañana", dias: 1 },
  { label: "7 días", dias: 7 },
  { label: "15 días", dias: 15 },
  { label: "30 días", dias: 30 },
];

function ProximosVencimientos({ cuotas }) {
  const [diasFiltro, setDiasFiltro] = useState(7);

  const proximas = useMemo(() => {
    if (!cuotas || cuotas.length === 0) return [];
    const hoy = new Date();
    hoy.setHours(0, 0, 0, 0);
    const limite = new Date(hoy);
    limite.setDate(limite.getDate() + diasFiltro);

    return cuotas
      .filter((c) => {
        if (c.estado === "vencida") return false;
        const fechaStr = c.fecha_vencimiento;
        if (!fechaStr) return false;
        // Parsear dd/mm/yyyy o yyyy-mm-dd
        let fecha;
        if (fechaStr.includes("/")) {
          const [d, m, y] = fechaStr.split("/");
          fecha = new Date(y, m - 1, d);
        } else {
          fecha = new Date(fechaStr);
        }
        return fecha >= hoy && fecha <= limite;
      })
      .sort((a, b) => {
        const parseFecha = (f) => {
          if (!f) return new Date();
          if (f.includes("/")) { const [d, m, y] = f.split("/"); return new Date(y, m - 1, d); }
          return new Date(f);
        };
        return parseFecha(a.fecha_vencimiento) - parseFecha(b.fecha_vencimiento);
      })
      .slice(0, 10);
  }, [cuotas, diasFiltro]);

  // Sumar total de próximos vencimientos
  const totalProximo = proximas.reduce((s, c) => s + (c.saldo_pendiente || 0), 0);

  if (!cuotas || cuotas.length === 0) return null;

  return (
    <Paper elevation={0} sx={{ p: { xs: 1.5, sm: 2 }, borderRadius: 2, border: "1px solid", borderColor: "divider", mb: 2 }}>
      <Box sx={{ display: "flex", alignItems: "center", justifyContent: "space-between", mb: 1, flexWrap: "wrap", gap: 1 }}>
        <Typography variant="caption" color="text.secondary" fontWeight={600} sx={{ display: "flex", alignItems: "center", gap: 0.5, textTransform: "uppercase", letterSpacing: 0.5 }}>
          <Schedule sx={{ fontSize: 14 }} /> Próximos Vencimientos
        </Typography>
        <Box sx={{ display: "flex", gap: 0.5 }}>
          {VENC_PRESETS.map((p) => (
            <Chip
              key={p.dias}
              label={p.label}
              size="small"
              variant={diasFiltro === p.dias ? "filled" : "outlined"}
              color={diasFiltro === p.dias ? "primary" : "default"}
              onClick={() => setDiasFiltro(p.dias)}
              sx={{ fontWeight: 600, fontSize: "0.7rem", cursor: "pointer" }}
            />
          ))}
        </Box>
      </Box>

      {proximas.length === 0 ? (
        <Alert severity="success" sx={{ borderRadius: 2, py: 0.5 }}>
          No hay cuotas por vencer en los próximos {diasFiltro} día{diasFiltro !== 1 ? "s" : ""}
        </Alert>
      ) : (
        <>
          <Table size="small">
            <TableBody>
              {proximas.map((c, i) => (
                <TableRow key={c.id || i} sx={{ "&:last-child td": { border: 0 } }}>
                  <TableCell sx={{ py: 0.5, pl: 0 }}>
                    <Typography variant="body2" fontWeight={500} noWrap>{c.cliente?.razon_social}</Typography>
                  </TableCell>
                  <TableCell sx={{ py: 0.5 }}>
                    <Typography variant="body2" sx={{ fontFamily: "monospace", fontSize: "0.8rem" }}>{c.factura?.numero}</Typography>
                  </TableCell>
                  <TableCell sx={{ py: 0.5 }}>
                    <Typography variant="caption" color="text.secondary">{c.fecha_vencimiento}</Typography>
                  </TableCell>
                  <TableCell align="right" sx={{ py: 0.5 }}>
                    <Typography variant="body2" fontWeight={600}>₲ {formatMoney(c.saldo_pendiente)}</Typography>
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
          <Box sx={{ display: "flex", justifyContent: "flex-end", mt: 0.5, pt: 0.5, borderTop: "1px solid", borderColor: "divider" }}>
            <Typography variant="body2" fontWeight={700}>
              Total: ₲ {formatMoney(totalProximo)} ({proximas.length} cuota{proximas.length !== 1 ? "s" : ""})
            </Typography>
          </Box>
        </>
      )}
    </Paper>
  );
}

// ==================== ESTADO DE CUENTA - Shared logic ====================
// Icon button para tabla
function EstadoCuentaIconButton({ clienteId, onPreview }) {
  return (
    <IconButton size="small" onClick={() => onPreview({ clienteId })} color="primary">
      <Print sx={{ fontSize: 18 }} />
    </IconButton>
  );
}

// Button para dialog
function EstadoCuentaButton({ clienteId, onPreview }) {
  return (
    <Button variant="outlined" size="small" startIcon={<Print />} sx={{ textTransform: "none", borderRadius: 2 }} onClick={() => onPreview({ clienteId })}>
      Estado de Cuenta
    </Button>
  );
}


// ==================== PAGINATION BAR ====================
function PaginationBar({ page, totalPages, totalItems, rowsPerPage, onPageChange }) {
  const start = (page - 1) * rowsPerPage + 1;
  const end = Math.min(page * rowsPerPage, totalItems);

  return (
    <Box sx={{ display: "flex", alignItems: "center", justifyContent: "space-between", px: 2, py: 1, borderTop: "1px solid", borderColor: "divider" }}>
      <Typography variant="caption" color="text.secondary">
        {start}-{end} de {totalItems}
      </Typography>
      <Box sx={{ display: "flex", alignItems: "center", gap: 0.5 }}>
        <IconButton size="small" disabled={page <= 1} onClick={() => onPageChange(1)}>
          <Icon icon="lucide:chevrons-left" style={{ width: 16, height: 16 }} />
        </IconButton>
        <IconButton size="small" disabled={page <= 1} onClick={() => onPageChange(page - 1)}>
          <Icon icon="lucide:chevron-left" style={{ width: 16, height: 16 }} />
        </IconButton>
        <Typography variant="body2" sx={{ mx: 1, fontWeight: 600, fontSize: "0.8rem" }}>
          {page} / {totalPages}
        </Typography>
        <IconButton size="small" disabled={page >= totalPages} onClick={() => onPageChange(page + 1)}>
          <Icon icon="lucide:chevron-right" style={{ width: 16, height: 16 }} />
        </IconButton>
        <IconButton size="small" disabled={page >= totalPages} onClick={() => onPageChange(totalPages)}>
          <Icon icon="lucide:chevrons-right" style={{ width: 16, height: 16 }} />
        </IconButton>
      </Box>
    </Box>
  );
}

// ==================== EXPORT EXCEL BUTTON ====================
const prioridadLabel = (dias) => {
  if (dias > 90) return "URGENTE";
  if (dias > 60) return "ALTA";
  if (dias > 30) return "MEDIA";
  if (dias > 0)  return "BAJA";
  return "AL DÍA";
};

const fmtFechaExport = (iso) => {
  if (!iso) return "";
  const s = typeof iso === "string" ? iso.split("T")[0] : iso.toISOString?.().split("T")[0];
  if (!s) return "";
  const [y, m, d] = s.split("-");
  return `${d}/${m}/${y}`;
};

function setColWidths(ws, widths) {
  ws["!cols"] = widths.map((w) => ({ wch: w }));
}

function ExportButton({ clientesData, cuotasData }) {
  const handleExport = () => {
    try {
      const wb = XLSX.utils.book_new();
      const hoy = new Date().toLocaleDateString("es-PY").replace(/\//g, "-");

      // ── Hoja 1: Resumen por cliente ──────────────────────────────────
      const clientesRows = [...(clientesData || [])]
        .sort((a, b) => (b.dias_mora || 0) - (a.dias_mora || 0))
        .map((c) => {
          const pct = c.saldo_total > 0 ? Math.round((c.saldo_vencido / c.saldo_total) * 100) : 0;
          const ruc = c.ruc ? `${c.ruc}-${c.dv || ""}` : (c.nro_documento || "");
          return {
            "Prioridad":                prioridadLabel(c.dias_mora || 0),
            "Días Mora":                c.dias_mora || 0,
            "Cliente":                  c.razon_social || "",
            "CI / RUC":                 ruc,
            "Celular":                  c.celular || "",
            "Teléfono":                 c.telefono || "",
            "Email":                    c.email || "",
            "Dirección":                c.direccion || "",
            "Primer Venc. Vencido":     fmtFechaExport(c.primer_vencimiento_vencido),
            "Cuotas Vencidas":          c.cuotas_vencidas,
            "Total Cuotas":             c.cuotas_totales,
            "Facturas Pendientes":      c.facturas_pendientes,
            "Saldo Vencido (Gs)":       Math.round(c.saldo_vencido),
            "Saldo Total (Gs)":         Math.round(c.saldo_total),
            "% Vencido":                `${pct}%`,
          };
        });
      const ws1 = XLSX.utils.json_to_sheet(sanitizeRecords(clientesRows));
      setColWidths(ws1, [10, 10, 36, 14, 14, 14, 28, 30, 18, 14, 12, 14, 18, 18, 10]);
      XLSX.utils.book_append_sheet(wb, ws1, "Clientes");

      // ── Hoja 2: Detalle de cuotas pendientes (vencidas y por vencer) ─
      // Antes sólo iban las vencidas y las que todavía no vencían no figuraban en
      // ningún detalle (Misterhome, oct-2026). Respeta los filtros de la pestaña
      // "Todas las Cuotas": con "Vencidas" sale sólo eso.
      const hoyMs = Date.now();
      const cuotasRows = (cuotasData || [])
        .filter((c) => Number(c.saldo_pendiente) > 0)
        .sort((a, b) => {
          const da = a.fecha_vencimiento ? new Date(a.fecha_vencimiento).getTime() : 0;
          const db = b.fecha_vencimiento ? new Date(b.fecha_vencimiento).getTime() : 0;
          return da - db;
        })
        .map((c) => {
          const vencMs = c.fecha_vencimiento ? new Date(c.fecha_vencimiento).getTime() : hoyMs;
          const dias = Math.max(0, Math.floor((hoyMs - vencMs) / 86400000));
          const ruc = c.cliente?.ruc
            ? `${c.cliente.ruc}-${c.cliente.dv || ""}`
            : (c.cliente?.nro_documento || "");
          return {
            "Cliente":              c.cliente?.razon_social || "",
            "CI / RUC":             ruc,
            "Celular":              c.cliente?.celular || "",
            "Factura":              c.factura?.numero || "",
            "Cuota Nro":            c.nro_cuota,
            "Vencimiento":          fmtFechaExport(c.fecha_vencimiento?.split?.("T")[0]),
            "Estado":               c.estado === "vencida" ? "Vencida" : "Por vencer",
            "Días Mora":            c.estado === "vencida" ? dias : 0,
            "Monto Cuota (Gs)":     Math.round(c.monto_cuota),
            "Saldo Pendiente (Gs)": Math.round(c.saldo_pendiente),
          };
        });
      const ws2 = XLSX.utils.json_to_sheet(sanitizeRecords(cuotasRows));
      setColWidths(ws2, [36, 14, 14, 20, 10, 14, 12, 10, 18, 18]);
      XLSX.utils.book_append_sheet(wb, ws2, "Cuotas pendientes");

      XLSX.writeFile(wb, `cobranza_${hoy}.xlsx`);
      toast.success("Archivo exportado correctamente");
    } catch (e) {
      console.error(e);
      toast.error("Error al exportar");
    }
  };

  return (
    <ExportBtn onClick={handleExport}>
      <Icon icon="lucide:download" style={{ width: 15, height: 15 }} />
      Exportar Excel
    </ExportBtn>
  );
}

// ==================== MAIN COMPONENT ====================
export default function CuentasCobrar() {
  const theme = useTheme();
  const navigate = useNavigate();
  const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
  const isTablet = useMediaQuery(theme.breakpoints.down("md"));
  const { can: canCobranzas } = usePermission("COBRANZAS");
  const canRead = canCobranzas("COB_CC_CUENTA_COBRAR_VER");
  const canExportar = canCobranzas("COB_CC_CUENTA_COBRAR_EXPORTAR");

  const [tabValue, setTabValue] = useState(0);
  const [selectedCliente, setSelectedCliente] = useState(null);
  const [dialogOpen, setDialogOpen] = useState(false);
  const [pdfPreview, setPdfPreview] = useState(null); // { clienteId }
  const [detalleMensualOpen, setDetalleMensualOpen] = useState(false);

  const handlePdfPreview = (preview) => setPdfPreview(preview);
  const handleClosePdfPreview = () => setPdfPreview(null);

  // Filtros - Tab Clientes
  const [searchClientes, setSearchClientes] = useState("");
  const [filtroEstadoClientes, setFiltroEstadoClientes] = useState("todos");
  const [filtroGestionMora, setFiltroGestionMora] = useState("todos"); // todos | sin_gestion | en_gestion
  const [sortField, setSortField] = useState("saldo_vencido");
  const [sortDirection, setSortDirection] = useState("desc");
  const [pageClientes, setPageClientes] = useState(1);

  // Filtros - Tab Cuotas
  const [searchCuotas, setSearchCuotas] = useState("");
  const [filtroEstadoCuotas, setFiltroEstadoCuotas] = useState("todos");
  const [filtroVencimiento, setFiltroVencimiento] = useState("todos"); // todos, manana, 7d, 15d, 30d
  const [pageCuotas, setPageCuotas] = useState(1);

  const ROWS_PER_PAGE = 15;

  const handleClienteClick = (cliente) => {
    setSelectedCliente(cliente);
    setDialogOpen(true);
  };

  const handleCloseDialog = () => {
    setDialogOpen(false);
    setSelectedCliente(null);
  };

  // Datos principales
  const { data: dashboardData, isLoading: loadingDashboard } = useQuery({
    queryKey: ["cxc-dashboard-report"],
    queryFn: getCuentasCobrarDashboard,
    staleTime: 2 * 60 * 1000,
  });

  const { data: resumenData, isLoading: loadingResumen, refetch: refetchResumen } = useQuery({
    queryKey: ["cuentas-cobrar-resumen"],
    queryFn: getCuentasCobrarResumen,
    staleTime: 2 * 60 * 1000,
  });

  const { data: clientesData, isLoading: loadingClientes, refetch: refetchClientes } = useQuery({
    queryKey: ["cuentas-cobrar-clientes"],
    queryFn: getCuentasCobrarPorCliente,
    staleTime: 2 * 60 * 1000,
  });

  const cuotasRaw = useMemo(() => resumenData?.cuotas || [], [resumenData]);
  const clientesRaw = useMemo(() => clientesData || [], [clientesData]);

  // ---- Filtrado & sorting clientes ----
  const clientesFiltrados = useMemo(() => {
    let list = [...clientesRaw];
    if (searchClientes.trim()) {
      const q = searchClientes.toLowerCase();
      list = list.filter(
        (c) =>
          (c.razon_social || "").toLowerCase().includes(q) ||
          (c.ruc || "").includes(q) ||
          (c.nro_documento || "").includes(q) ||
          (c.cod_cliente || "").toLowerCase().includes(q),
      );
    }
    if (filtroEstadoClientes === "vencido") list = list.filter((c) => c.saldo_vencido > 0);
    else if (filtroEstadoClientes === "al_dia") list = list.filter((c) => c.saldo_vencido === 0);

    if (filtroGestionMora === "sin_gestion") list = list.filter((c) => !c.gestion_mora_activa);
    else if (filtroGestionMora === "en_gestion") list = list.filter((c) => !!c.gestion_mora_activa);

    list.sort((a, b) => {
      const aVal = a[sortField] ?? 0;
      const bVal = b[sortField] ?? 0;
      if (typeof aVal === "string") return sortDirection === "asc" ? aVal.localeCompare(bVal) : bVal.localeCompare(aVal);
      return sortDirection === "asc" ? aVal - bVal : bVal - aVal;
    });
    return list;
  }, [clientesRaw, searchClientes, filtroEstadoClientes, filtroGestionMora, sortField, sortDirection]);

  // Paginación clientes
  const totalPagesClientes = Math.ceil(clientesFiltrados.length / ROWS_PER_PAGE) || 1;
  const clientesPaginados = useMemo(() => {
    const start = (pageClientes - 1) * ROWS_PER_PAGE;
    return clientesFiltrados.slice(start, start + ROWS_PER_PAGE);
  }, [clientesFiltrados, pageClientes]);

  // ---- Filtrado cuotas ----
  const cuotasFiltradas = useMemo(() => {
    let list = [...cuotasRaw];
    if (searchCuotas.trim()) {
      const q = searchCuotas.toLowerCase();
      list = list.filter(
        (c) =>
          (c.cliente?.razon_social || "").toLowerCase().includes(q) ||
          (c.factura?.numero || "").includes(q),
      );
    }
    if (filtroEstadoCuotas === "vencida") list = list.filter((c) => c.estado === "vencida");
    else if (filtroEstadoCuotas === "pendiente") list = list.filter((c) => c.estado === "pendiente");

    // Filtro por próximo vencimiento
    if (filtroVencimiento !== "todos") {
      const hoy = new Date();
      hoy.setHours(0, 0, 0, 0);
      const dias = filtroVencimiento === "manana" ? 1 : filtroVencimiento === "7d" ? 7 : filtroVencimiento === "15d" ? 15 : 30;
      const limite = new Date(hoy);
      limite.setDate(limite.getDate() + dias);

      list = list.filter((c) => {
        if (c.estado === "vencida") return false;
        const f = c.fecha_vencimiento;
        if (!f) return false;
        let fecha;
        if (f.includes("/")) { const [d, m, y] = f.split("/"); fecha = new Date(y, m - 1, d); }
        else { fecha = new Date(f); }
        return fecha >= hoy && fecha <= limite;
      });
    }
    return list;
  }, [cuotasRaw, searchCuotas, filtroEstadoCuotas, filtroVencimiento]);

  // Paginación cuotas
  const totalPagesCuotas = Math.ceil(cuotasFiltradas.length / ROWS_PER_PAGE) || 1;
  const cuotasPaginadas = useMemo(() => {
    const start = (pageCuotas - 1) * ROWS_PER_PAGE;
    return cuotasFiltradas.slice(start, start + ROWS_PER_PAGE);
  }, [cuotasFiltradas, pageCuotas]);

  const handleSort = (field) => {
    if (sortField === field) setSortDirection((d) => (d === "asc" ? "desc" : "asc"));
    else { setSortField(field); setSortDirection("desc"); }
    setPageClientes(1);
  };

  const handleRefresh = () => { refetchResumen(); refetchClientes(); };

  const isLoading = loadingResumen || loadingClientes;

  if (!canRead) return <AccesoRestringido modulo="COBRANZAS" />;

  return (
    <Container>
      {/* ========== HEADER ========== */}
      <Header>
        <HeaderContent>
          <BackBtn onClick={() => navigate("/reportes")}>
            <Icon icon="lucide:arrow-left" />
          </BackBtn>
          <TitleSection>
            <MainTitle>
              <Icon icon="lucide:receipt" />
              Cuentas por Cobrar
            </MainTitle>
            <Subtitle>Análisis de cartera, vencimientos y estado de cuenta</Subtitle>
          </TitleSection>
          <HeaderActions>
            {canExportar && (
              <>
                <ExportButton clientesData={clientesFiltrados} cuotasData={cuotasFiltradas} tabValue={tabValue} />
                <Tooltip title="Excel con pagos mes a mes por factura, filtrable por categoría y fecha de corte">
                  <Button size="small" variant="outlined"
                    startIcon={<Icon icon="lucide:file-spreadsheet" />}
                    onClick={() => setDetalleMensualOpen(true)}
                    sx={{ whiteSpace: "nowrap" }}>
                    Detalle mensual
                  </Button>
                </Tooltip>
              </>
            )}
            <Tooltip title="Actualizar datos">
              <IconButton size="small" onClick={handleRefresh} sx={{ color: "inherit" }}>
                <Refresh fontSize="small" />
              </IconButton>
            </Tooltip>
          </HeaderActions>
        </HeaderContent>
        {/* Breadcrumb */}
        <Breadcrumb>
          <BreadcrumbLink onClick={() => navigate("/reportes")}>Reportes</BreadcrumbLink>
          <Icon icon="lucide:chevron-right" style={{ width: 12, height: 12, opacity: 0.5 }} />
          <BreadcrumbCurrent>Cuentas por Cobrar</BreadcrumbCurrent>
        </Breadcrumb>
      </Header>

      <Content>
        {/* ========== AGING BUCKETS ========== */}
        <AgingBucketsPanel data={dashboardData} isLoading={loadingDashboard} totalClientes={clientesRaw.length} />

        {/* ========== PROXIMOS VENCIMIENTOS ========== */}
        {/* ProximosVencimientos eliminado — filtro integrado en tab Cuotas */}

        {/* ========== TABS + CONTENT ========== */}
        <Paper elevation={0} sx={{ borderRadius: 2, border: "1px solid", borderColor: "divider", overflow: "hidden" }}>
          <Box sx={{ display: "flex", alignItems: "center", borderBottom: 1, borderColor: "divider", px: { xs: 1, sm: 2 } }}>
            <Tabs value={tabValue} onChange={(e, v) => setTabValue(v)} sx={{ flex: 1 }} variant={isMobile ? "fullWidth" : "standard"}>
              <Tab icon={<Person sx={{ fontSize: 18 }} />} iconPosition="start" label={isMobile ? "Clientes" : "Por Cliente"} sx={{ textTransform: "none", fontWeight: 600, minHeight: 48 }} />
              <Tab icon={<Receipt sx={{ fontSize: 18 }} />} iconPosition="start" label={isMobile ? "Cuotas" : "Todas las Cuotas"} sx={{ textTransform: "none", fontWeight: 600, minHeight: 48 }} />
            </Tabs>
          </Box>

          {/* ========== TAB: POR CLIENTE ========== */}
          <TabPanel value={tabValue} index={0}>
            <Box sx={{ p: { xs: 1.5, sm: 2 }, display: "flex", gap: 1.5, flexWrap: "wrap", alignItems: "center" }}>
              <TextField size="small" placeholder="Buscar por nombre, RUC o código..." value={searchClientes} onChange={(e) => { setSearchClientes(e.target.value); setPageClientes(1); }} sx={{ flex: 1, minWidth: 200 }}
                InputProps={{ startAdornment: <InputAdornment position="start"><Search fontSize="small" color="action" /></InputAdornment> }} />
              <TextField select size="small" value={filtroEstadoClientes} onChange={(e) => { setFiltroEstadoClientes(e.target.value); setPageClientes(1); }} sx={{ minWidth: 160 }}
                InputProps={{ startAdornment: <InputAdornment position="start"><FilterList fontSize="small" color="action" /></InputAdornment> }}>
                <MenuItem value="todos">Todos los clientes</MenuItem>
                <MenuItem value="vencido">Con deuda vencida</MenuItem>
                <MenuItem value="al_dia">Al día</MenuItem>
              </TextField>
              <TextField
                select
                size="small"
                value={filtroGestionMora}
                onChange={(e) => { setFiltroGestionMora(e.target.value); setPageClientes(1); }}
                sx={{ minWidth: 170 }}
                helperText="Gestión de mora"
                FormHelperTextProps={{ sx: { ml: 0.5, mt: 0, fontSize: 10 } }}
              >
                <MenuItem value="todos">Todos</MenuItem>
                <MenuItem value="sin_gestion">Sin gestión activa</MenuItem>
                <MenuItem value="en_gestion">En gestión activa</MenuItem>
              </TextField>
              <Typography variant="body2" color="text.secondary" sx={{ ml: 1 }}>{clientesFiltrados.length} de {clientesRaw.length}</Typography>
            </Box>

            <TableContainer sx={{ maxHeight: "calc(100vh - 520px)" }}>
              <Table size="small" stickyHeader>
                <TableHead>
                  <TableRow>
                    <TableCell sx={{ fontWeight: 700 }}>
                      <TableSortLabel active={sortField === "razon_social"} direction={sortField === "razon_social" ? sortDirection : "asc"} onClick={() => handleSort("razon_social")}>Cliente</TableSortLabel>
                    </TableCell>
                    {!isMobile && <TableCell sx={{ fontWeight: 700 }}>RUC</TableCell>}
                    <TableCell align="center" sx={{ fontWeight: 700 }}>
                      <Tooltip title="Cuotas vencidas / total cuotas pendientes" arrow>
                        <TableSortLabel active={sortField === "cuotas_vencidas"} direction={sortField === "cuotas_vencidas" ? sortDirection : "asc"} onClick={() => handleSort("cuotas_vencidas")}>Cuotas</TableSortLabel>
                      </Tooltip>
                    </TableCell>
                    <TableCell align="center" sx={{ fontWeight: 700 }}>
                      <Tooltip title="Días desde el primer vencimiento incumplido" arrow>
                        <TableSortLabel active={sortField === "dias_mora"} direction={sortField === "dias_mora" ? sortDirection : "asc"} onClick={() => handleSort("dias_mora")}>Mora</TableSortLabel>
                      </Tooltip>
                    </TableCell>
                    <TableCell align="right" sx={{ fontWeight: 700 }}>
                      <TableSortLabel active={sortField === "saldo_total"} direction={sortField === "saldo_total" ? sortDirection : "asc"} onClick={() => handleSort("saldo_total")}>Saldo Total</TableSortLabel>
                    </TableCell>
                    <TableCell align="right" sx={{ fontWeight: 700 }}>
                      <TableSortLabel active={sortField === "saldo_vencido"} direction={sortField === "saldo_vencido" ? sortDirection : "asc"} onClick={() => handleSort("saldo_vencido")}>Vencido</TableSortLabel>
                    </TableCell>
                    {!isTablet && <TableCell sx={{ fontWeight: 700, minWidth: 120 }} align="center">Salud</TableCell>}
                    {!isMobile && <TableCell sx={{ fontWeight: 700 }} align="center">Acciones</TableCell>}
                  </TableRow>
                </TableHead>
                <TableBody>
                  {clientesPaginados.length === 0 ? (
                    <TableRow><TableCell colSpan={7} align="center" sx={{ py: 4 }}>
                      <Alert severity="info" sx={{ justifyContent: "center" }}>{searchClientes || filtroEstadoClientes !== "todos" ? "No se encontraron clientes con los filtros aplicados" : "No hay cuentas pendientes de cobro"}</Alert>
                    </TableCell></TableRow>
                  ) : (
                    clientesPaginados.map((cliente) => {
                      const healthPct = cliente.saldo_total > 0 ? Math.round((cliente.saldo_vencido / cliente.saldo_total) * 100) : 0;
                      const healthColor = healthPct === 0 ? "success" : healthPct < 50 ? "warning" : "error";
                      return (
                        <TableRow key={cliente.id} onClick={() => handleClienteClick(cliente)} sx={{ cursor: "pointer", "&:hover": { bgcolor: "action.hover" }, borderLeft: 3, borderLeftColor: cliente.saldo_vencido > 0 ? "error.main" : "success.main" }}>
                          <TableCell>
                            <Box sx={{ display: "flex", alignItems: "center", gap: 0.75, flexWrap: "wrap" }}>
                              <Typography variant="body2" fontWeight={600}>{cliente.razon_social}</Typography>
                              {cliente.gestion_mora_activa && (() => {
                                const meta = getCobMoraEstadoChip(cliente.gestion_mora_activa.estado);
                                return (
                                  <Tooltip
                                    title={`En gestión de mora · ${meta.label} desde ${
                                      cliente.gestion_mora_activa.fecha_ingreso
                                        ? new Date(cliente.gestion_mora_activa.fecha_ingreso).toLocaleDateString("es-PY")
                                        : "—"
                                    }`}
                                    arrow
                                  >
                                    <Chip
                                      label={`EN GESTIÓN · ${meta.label}`}
                                      size="small"
                                      color={meta.color}
                                      variant="outlined"
                                      sx={{ fontSize: 10, height: 18, fontWeight: 600 }}
                                    />
                                  </Tooltip>
                                );
                              })()}
                            </Box>
                            <Typography variant="caption" color="text.secondary">{cliente.cod_cliente}{isMobile && cliente.ruc && ` | ${cliente.ruc}-${cliente.dv}`}</Typography>
                          </TableCell>
                          {!isMobile && <TableCell><Typography variant="body2">{cliente.ruc ? `${cliente.ruc}-${cliente.dv}` : "-"}</Typography></TableCell>}
                          <TableCell align="center">
                            <Tooltip title={`${cliente.cuotas_vencidas} cuotas vencidas de ${cliente.cuotas_totales} pendientes`} arrow>
                              <Box sx={{ display: "inline-flex", flexDirection: "column", alignItems: "center", gap: 0 }}>
                                {cliente.cuotas_vencidas > 0 ? (
                                  <Typography variant="body2" fontWeight={700} color="error.main" lineHeight={1.2}>
                                    {cliente.cuotas_vencidas} venc.
                                  </Typography>
                                ) : (
                                  <Typography variant="body2" fontWeight={600} color="success.main" lineHeight={1.2}>Al día</Typography>
                                )}
                                <Typography variant="caption" color="text.secondary" lineHeight={1.2}>
                                  / {cliente.cuotas_totales} total
                                </Typography>
                              </Box>
                            </Tooltip>
                          </TableCell>
                          <TableCell align="center">
                            {(cliente.dias_mora || 0) > 0 ? (
                              <Tooltip title={`${cliente.dias_mora} días desde el primer vencimiento incumplido`} arrow>
                                <Chip
                                  label={`${cliente.dias_mora}d`}
                                  size="small"
                                  sx={{
                                    fontWeight: 700, minWidth: 44,
                                    bgcolor: cliente.dias_mora > 90 ? "error.main" : cliente.dias_mora > 60 ? "#e65100" : cliente.dias_mora > 30 ? "warning.main" : "#f9a825",
                                    color: "white",
                                  }}
                                />
                              </Tooltip>
                            ) : (
                              <Chip label="Al día" size="small" color="success" variant="outlined" sx={{ fontSize: 11 }} />
                            )}
                          </TableCell>
                          <TableCell align="right">
                            <Typography variant="body2" fontWeight={600}>₲ {formatMoney(cliente.saldo_total)}</Typography>
                            <Typography variant="caption" color="text.secondary">{cliente.facturas_pendientes} fact.</Typography>
                          </TableCell>
                          <TableCell align="right">
                            {cliente.saldo_vencido > 0 ? <Typography variant="body2" fontWeight={700} color="error.main">₲ {formatMoney(cliente.saldo_vencido)}</Typography> : <Typography variant="body2" color="success.main" fontWeight={500}>Al día</Typography>}
                          </TableCell>
                          {!isTablet && (
                            <TableCell align="center">
                              <Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
                                <LinearProgress variant="determinate" value={healthPct} color={healthColor} sx={{ flex: 1, height: 6, borderRadius: 3, bgcolor: "action.hover" }} />
                                <Typography variant="caption" fontWeight={600} color={`${healthColor}.main`} sx={{ minWidth: 28 }}>{healthPct}%</Typography>
                              </Box>
                            </TableCell>
                          )}
                          {!isMobile && (
                            <TableCell align="center" onClick={(e) => e.stopPropagation()}>
                              <Tooltip title="Estado de Cuenta PDF">
                                <span><EstadoCuentaIconButton clienteId={cliente.id} onPreview={handlePdfPreview} /></span>
                              </Tooltip>
                            </TableCell>
                          )}
                        </TableRow>
                      );
                    })
                  )}
                </TableBody>
              </Table>
            </TableContainer>
            {/* Paginación Clientes */}
            {clientesFiltrados.length > ROWS_PER_PAGE && (
              <PaginationBar
                page={pageClientes}
                totalPages={totalPagesClientes}
                totalItems={clientesFiltrados.length}
                rowsPerPage={ROWS_PER_PAGE}
                onPageChange={setPageClientes}
              />
            )}
          </TabPanel>

          {/* ========== TAB: TODAS LAS CUOTAS ========== */}
          <TabPanel value={tabValue} index={1}>
            <Box sx={{ p: { xs: 1.5, sm: 2 }, display: "flex", gap: 1.5, flexWrap: "wrap", alignItems: "center" }}>
              <TextField size="small" placeholder="Buscar por cliente o nro factura..." value={searchCuotas} onChange={(e) => { setSearchCuotas(e.target.value); setPageCuotas(1); }} sx={{ flex: 1, minWidth: 200 }}
                InputProps={{ startAdornment: <InputAdornment position="start"><Search fontSize="small" color="action" /></InputAdornment> }} />
              <TextField select size="small" value={filtroEstadoCuotas} onChange={(e) => { setFiltroEstadoCuotas(e.target.value); setFiltroVencimiento("todos"); setPageCuotas(1); }} sx={{ minWidth: 150 }}>
                <MenuItem value="todos">Todas</MenuItem>
                <MenuItem value="vencida">Vencidas</MenuItem>
                <MenuItem value="pendiente">Por vencer</MenuItem>
              </TextField>
              <TextField select size="small" value={filtroVencimiento} onChange={(e) => { setFiltroVencimiento(e.target.value); if (e.target.value !== "todos") setFiltroEstadoCuotas("todos"); setPageCuotas(1); }} sx={{ minWidth: 160 }}>
                <MenuItem value="todos">Todos los plazos</MenuItem>
                <MenuItem value="manana">Vence mañana</MenuItem>
                <MenuItem value="7d">Próximos 7 días</MenuItem>
                <MenuItem value="15d">Próximos 15 días</MenuItem>
                <MenuItem value="30d">Próximos 30 días</MenuItem>
              </TextField>
              <Typography variant="body2" color="text.secondary">{cuotasFiltradas.length} cuotas</Typography>
            </Box>

            <TableContainer sx={{ maxHeight: "calc(100vh - 520px)" }}>
              <Table size="small" stickyHeader>
                <TableHead>
                  <TableRow>
                    <TableCell sx={{ fontWeight: 700 }}>Cliente</TableCell>
                    {!isMobile && <TableCell sx={{ fontWeight: 700 }}>Factura</TableCell>}
                    <TableCell align="center" sx={{ fontWeight: 700 }}>Cuota</TableCell>
                    <TableCell sx={{ fontWeight: 700 }}>Vencimiento</TableCell>
                    <TableCell align="center" sx={{ fontWeight: 700 }}>Estado</TableCell>
                    <TableCell align="right" sx={{ fontWeight: 700 }}>Monto</TableCell>
                    <TableCell align="right" sx={{ fontWeight: 700 }}>Saldo</TableCell>
                  </TableRow>
                </TableHead>
                <TableBody>
                  {cuotasPaginadas.length === 0 ? (
                    <TableRow><TableCell colSpan={7} align="center" sx={{ py: 4 }}>
                      <Alert severity="info" sx={{ justifyContent: "center" }}>{searchCuotas || filtroEstadoCuotas !== "todos" ? "No se encontraron cuotas con los filtros aplicados" : "No hay cuotas pendientes de cobro"}</Alert>
                    </TableCell></TableRow>
                  ) : (
                    cuotasPaginadas.map((cuota) => (
                      <TableRow key={cuota.id} sx={{ borderLeft: 3, borderLeftColor: cuota.estado === "vencida" ? "error.main" : "success.main", "&:hover": { bgcolor: "action.hover" } }}>
                        <TableCell>
                          <Typography variant="body2" fontWeight={500}>{cuota.cliente?.razon_social}</Typography>
                          {isMobile && <Typography variant="caption" color="text.secondary">{cuota.factura?.numero}</Typography>}
                        </TableCell>
                        {!isMobile && <TableCell><Typography variant="body2" sx={{ fontFamily: "monospace", fontSize: "0.8rem" }}>{cuota.factura?.numero}</Typography></TableCell>}
                        <TableCell align="center"><Chip label={`#${cuota.nro_cuota}`} size="small" variant="outlined" sx={{ fontWeight: 600 }} /></TableCell>
                        <TableCell>
                          <Typography variant="body2">{cuota.fecha_vencimiento}</Typography>
                          {cuota.dias_vencido > 0 && <Typography variant="caption" color="error.main" fontWeight={600}>{cuota.dias_vencido} días vencido</Typography>}
                        </TableCell>
                        <TableCell align="center"><Chip label={cuota.estado === "vencida" ? "Vencida" : "Pendiente"} color={cuota.estado === "vencida" ? "error" : "success"} size="small" sx={{ fontWeight: 600, fontSize: "0.7rem" }} /></TableCell>
                        <TableCell align="right"><Typography variant="body2">₲ {formatMoney(cuota.monto_cuota)}</Typography></TableCell>
                        <TableCell align="right"><Typography variant="body2" fontWeight={700}>₲ {formatMoney(cuota.saldo_pendiente)}</Typography></TableCell>
                      </TableRow>
                    ))
                  )}
                </TableBody>
              </Table>
            </TableContainer>
            {/* Paginación Cuotas */}
            {cuotasFiltradas.length > ROWS_PER_PAGE && (
              <PaginationBar
                page={pageCuotas}
                totalPages={totalPagesCuotas}
                totalItems={cuotasFiltradas.length}
                rowsPerPage={ROWS_PER_PAGE}
                onPageChange={setPageCuotas}
              />
            )}
          </TabPanel>
        </Paper>
      </Content>

      {/* ========== DIALOG DETALLE CLIENTE ========== */}
      <Dialog open={dialogOpen} onClose={handleCloseDialog} maxWidth="md" fullWidth fullScreen={isMobile} PaperProps={{ sx: { borderRadius: isMobile ? 0 : 3, maxHeight: "90vh" } }}>
        <DialogTitle sx={{ pb: 1 }}>
          <Box sx={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
            <Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
              <Box sx={{ width: 36, height: 36, borderRadius: 1.5, bgcolor: "primary.main", display: "flex", alignItems: "center", justifyContent: "center" }}>
                <Person sx={{ color: "white", fontSize: 20 }} />
              </Box>
              <Box>
                <Typography variant="h6" fontWeight={700} lineHeight={1.2}>{selectedCliente?.razon_social || "Detalle de Cuenta"}</Typography>
                <Typography variant="caption" color="text.secondary">
                  {selectedCliente?.ruc ? `RUC: ${selectedCliente.ruc}-${selectedCliente.dv}` : ""}
                  {selectedCliente?.cod_cliente ? ` | ${selectedCliente.cod_cliente}` : ""}
                </Typography>
              </Box>
            </Box>
            <IconButton onClick={handleCloseDialog} size="small"><Close /></IconButton>
          </Box>
        </DialogTitle>
        <DialogContent dividers>
          {selectedCliente && <ClienteDetalleContent cliente={selectedCliente} onPreview={handlePdfPreview} />}
        </DialogContent>
      </Dialog>

      {/* ========== PDF PREVIEW MODAL ========== */}
      <EstadoCuentaPdfModal
        open={!!pdfPreview}
        clienteId={pdfPreview?.clienteId}
        onClose={handleClosePdfPreview}
      />

      {/* ========== EXPORT DETALLE MENSUAL POR CATEGORÍA ========== */}
      <DetalleMensualExportDialog
        open={detalleMensualOpen}
        onClose={() => setDetalleMensualOpen(false)}
      />
    </Container>
  );
}

// ==================== DETALLE CLIENTE ====================
function ClienteDetalleContent({ cliente, onPreview }) {
  const { data: cuotasData, isLoading } = useQuery({
    queryKey: ["cuotas-cliente", cliente.id],
    queryFn: () => getCuotasPendientes(cliente.id),
    enabled: !!cliente.id,
  });

  const { data: cobrosData, isLoading: loadingCobros } = useQuery({
    queryKey: ["cobros-historial-cliente", cliente.id],
    queryFn: () => getCobrosHistorialCliente(cliente.id),
    enabled: !!cliente.id,
  });

  const cuotas = cuotasData || [];
  const cobros = cobrosData || [];
  const healthPct = cliente.saldo_total > 0 ? Math.round((cliente.saldo_vencido / cliente.saldo_total) * 100) : 0;

  return (
    <Box>
      {/* Resumen rápido */}
      <Box sx={{ display: "grid", gridTemplateColumns: { xs: "1fr 1fr", sm: "repeat(4, 1fr)" }, gap: 1.5, mb: 2.5 }}>
        <Paper elevation={0} sx={{ p: 2, borderRadius: 2, border: "1px solid", borderColor: "divider", textAlign: "center" }}>
          <Typography variant="caption" color="text.secondary">Saldo Total</Typography>
          <Typography variant="h6" fontWeight={700} color="primary.main">₲ {formatMoney(cliente.saldo_total)}</Typography>
        </Paper>
        <Paper elevation={0} sx={{ p: 2, borderRadius: 2, border: "1px solid", borderColor: cliente.saldo_vencido > 0 ? "error.main" : "divider", textAlign: "center", bgcolor: cliente.saldo_vencido > 0 ? "error.main" : "transparent" }}>
          <Typography variant="caption" sx={{ color: cliente.saldo_vencido > 0 ? "white" : "text.secondary" }}>Saldo Vencido</Typography>
          <Typography variant="h6" fontWeight={700} sx={{ color: cliente.saldo_vencido > 0 ? "white" : "success.main" }}>
            {cliente.saldo_vencido > 0 ? `₲ ${formatMoney(cliente.saldo_vencido)}` : "Al día"}
          </Typography>
        </Paper>
        <Paper elevation={0} sx={{ p: 2, borderRadius: 2, border: "1px solid", borderColor: "divider", textAlign: "center" }}>
          <Typography variant="caption" color="text.secondary">Facturas</Typography>
          <Typography variant="h6" fontWeight={700}>{cliente.facturas_pendientes}</Typography>
        </Paper>
        <Paper elevation={0} sx={{ p: 2, borderRadius: 2, border: "1px solid", borderColor: "divider", textAlign: "center" }}>
          <Typography variant="caption" color="text.secondary">Cuotas</Typography>
          <Typography variant="h6" fontWeight={700}>
            {cliente.cuotas_totales}
            {cliente.cuotas_vencidas > 0 && <Typography component="span" variant="body2" color="error.main" fontWeight={700} sx={{ ml: 0.5 }}>({cliente.cuotas_vencidas} vencidas)</Typography>}
          </Typography>
        </Paper>
      </Box>

      {/* Barra de salud */}
      <Paper elevation={0} sx={{ p: 1.5, mb: 2.5, borderRadius: 2, border: "1px solid", borderColor: "divider" }}>
        <Box sx={{ display: "flex", justifyContent: "space-between", mb: 0.5 }}>
          <Typography variant="caption" color="text.secondary">Estado de cuenta</Typography>
          <Typography variant="caption" fontWeight={600} color={healthPct === 0 ? "success.main" : healthPct < 50 ? "warning.main" : "error.main"}>
            {healthPct === 0 ? "Excelente" : healthPct < 30 ? "Bueno" : healthPct < 60 ? "Atención" : "Crítico"} — {healthPct}% vencido
          </Typography>
        </Box>
        <LinearProgress variant="determinate" value={healthPct} color={healthPct === 0 ? "success" : healthPct < 50 ? "warning" : "error"} sx={{ height: 8, borderRadius: 4, bgcolor: "action.hover" }} />
      </Paper>

      {/* Acciones rápidas */}
      <Box sx={{ display: "flex", gap: 1, mb: 2.5, flexWrap: "wrap" }}>
        <Button variant="contained" size="small" startIcon={<AttachMoney />} sx={{ textTransform: "none", borderRadius: 2 }} onClick={() => window.open(`/cobros?cliente=${cliente.id}`, "_blank")}>
          Registrar Cobro
        </Button>
        <EstadoCuentaButton clienteId={cliente.id} onPreview={onPreview} />
      </Box>

      {/* Lista de cuotas */}
      <Typography variant="subtitle2" fontWeight={700} sx={{ mb: 1, display: "flex", alignItems: "center", gap: 0.5, textTransform: "uppercase", letterSpacing: 0.5, color: "text.secondary", fontSize: "0.7rem" }}>
        <Receipt sx={{ fontSize: 16 }} /> Detalle de Cuotas
      </Typography>

      {isLoading ? (
        <Box sx={{ py: 2 }}>{[1, 2, 3].map((i) => <Skeleton key={i} variant="rectangular" height={40} sx={{ mb: 0.5, borderRadius: 1 }} />)}</Box>
      ) : cuotas.length === 0 ? (
        <Alert severity="info" sx={{ borderRadius: 2 }}>No hay cuotas pendientes para este cliente</Alert>
      ) : (
        <TableContainer component={Paper} elevation={0} sx={{ maxHeight: 300, borderRadius: 2, border: "1px solid", borderColor: "divider" }}>
          <Table size="small" stickyHeader>
            <TableHead>
              <TableRow>
                <TableCell sx={{ fontWeight: 700, fontSize: "0.75rem" }}>Factura</TableCell>
                <TableCell align="center" sx={{ fontWeight: 700, fontSize: "0.75rem" }}>Cuota</TableCell>
                <TableCell sx={{ fontWeight: 700, fontSize: "0.75rem" }}>Vencimiento</TableCell>
                <TableCell align="center" sx={{ fontWeight: 700, fontSize: "0.75rem" }}>Estado</TableCell>
                <TableCell align="right" sx={{ fontWeight: 700, fontSize: "0.75rem" }}>Monto</TableCell>
                <TableCell align="right" sx={{ fontWeight: 700, fontSize: "0.75rem" }}>Saldo</TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {cuotas.map((cuota) => {
                const hoy = new Date();
                const vencimiento = new Date(cuota.dvenccuo);
                const vencida = vencimiento < hoy;
                const diasVencido = vencida ? Math.floor((hoy - vencimiento) / (1000 * 60 * 60 * 24)) : 0;
                const diasRestantes = !vencida ? Math.floor((vencimiento - hoy) / (1000 * 60 * 60 * 24)) : 0;
                return (
                  <TableRow key={cuota.id} sx={{ borderLeft: 3, borderLeftColor: vencida ? "error.main" : "success.main", "&:hover": { bgcolor: "action.hover" } }}>
                    <TableCell><Typography variant="body2" fontWeight={500} sx={{ fontFamily: "monospace", fontSize: "0.8rem" }}>{cuota.factura_cab?.dest || ""}-{cuota.factura_cab?.dpunexp || ""}-{cuota.factura_cab?.dnumdoc || ""}</Typography></TableCell>
                    <TableCell align="center"><Chip label={`#${cuota.nro_cuota}`} size="small" variant="outlined" sx={{ fontWeight: 600, fontSize: "0.75rem" }} /></TableCell>
                    <TableCell>
                      <Typography variant="body2">{cuota.dvenccuo ? new Date(cuota.dvenccuo).toLocaleDateString("es-PY") : "-"}</Typography>
                      {vencida ? <Typography variant="caption" color="error.main" fontWeight={600}>{diasVencido} días vencido</Typography>
                        : diasRestantes <= 7 ? <Typography variant="caption" color="warning.main" fontWeight={500}>Vence en {diasRestantes} días</Typography> : null}
                    </TableCell>
                    <TableCell align="center"><Chip label={vencida ? "Vencida" : "Pendiente"} color={vencida ? "error" : "success"} size="small" sx={{ fontWeight: 600, fontSize: "0.7rem" }} /></TableCell>
                    <TableCell align="right"><Typography variant="body2">₲ {formatMoney(cuota.dmoncuota)}</Typography></TableCell>
                    <TableCell align="right"><Typography variant="body2" fontWeight={700}>₲ {formatMoney(cuota.saldo_pendiente)}</Typography></TableCell>
                  </TableRow>
                );
              })}
            </TableBody>
          </Table>
        </TableContainer>
      )}

      {/* ── Historial de Cobros ── */}
      <Box sx={{ mt: 3 }}>
        <Typography variant="subtitle2" fontWeight={700} sx={{ mb: 1, display: "flex", alignItems: "center", gap: 0.5, textTransform: "uppercase", letterSpacing: 0.5, color: "text.secondary", fontSize: "0.7rem" }}>
          <CheckCircle sx={{ fontSize: 16, color: "success.main" }} /> Cobros Registrados
        </Typography>
        {loadingCobros ? (
          <Box sx={{ py: 1 }}>{[1, 2].map((i) => <Skeleton key={i} variant="rectangular" height={36} sx={{ mb: 0.5, borderRadius: 1 }} />)}</Box>
        ) : cobros.length === 0 ? (
          <Alert severity="info" sx={{ borderRadius: 2, py: 0.5 }}>Sin cobros registrados para este cliente</Alert>
        ) : (
          <>
            {/* KPI total cobrado */}
            <Box sx={{ display: "flex", gap: 1.5, mb: 1.5, flexWrap: "wrap" }}>
              <Paper elevation={0} sx={{ px: 2, py: 1, borderRadius: 2, border: "1px solid", borderColor: "success.main", borderLeftWidth: 3 }}>
                <Typography variant="caption" color="text.secondary">Total Cobrado</Typography>
                <Typography variant="body1" fontWeight={700} color="success.dark">
                  ₲ {formatMoney(cobros.reduce((s, r) => s + r.monto_total, 0))}
                </Typography>
              </Paper>
              <Paper elevation={0} sx={{ px: 2, py: 1, borderRadius: 2, border: "1px solid", borderColor: "divider" }}>
                <Typography variant="caption" color="text.secondary">Recibos emitidos</Typography>
                <Typography variant="body1" fontWeight={700}>{cobros.length}</Typography>
              </Paper>
            </Box>
            {/* Lista de recibos */}
            <TableContainer component={Paper} elevation={0} sx={{ maxHeight: 260, borderRadius: 2, border: "1px solid", borderColor: "divider" }}>
              <Table size="small" stickyHeader>
                <TableHead>
                  <TableRow>
                    <TableCell sx={{ fontWeight: 700, fontSize: "0.75rem" }}>Recibo</TableCell>
                    <TableCell sx={{ fontWeight: 700, fontSize: "0.75rem" }}>Fecha</TableCell>
                    <TableCell sx={{ fontWeight: 700, fontSize: "0.75rem" }}>Factura / Cuota</TableCell>
                    <TableCell sx={{ fontWeight: 700, fontSize: "0.75rem" }}>Medio</TableCell>
                    <TableCell align="right" sx={{ fontWeight: 700, fontSize: "0.75rem" }}>Monto</TableCell>
                  </TableRow>
                </TableHead>
                <TableBody>
                  {cobros.map((recibo) =>
                    recibo.detalles.length > 0 ? recibo.detalles.map((det, i) => (
                      <TableRow key={`${recibo.id}-${i}`} sx={{ "&:hover": { bgcolor: "action.hover" } }}>
                        <TableCell>
                          {i === 0 && (
                            <Typography variant="body2" fontWeight={600} sx={{ fontFamily: "monospace", fontSize: "0.78rem", color: "success.dark" }}>
                              {recibo.numero_recibo || "Sin número"}
                            </Typography>
                          )}
                        </TableCell>
                        <TableCell>
                          {i === 0 && <Typography variant="caption" color="text.secondary">{recibo.fecha}</Typography>}
                        </TableCell>
                        <TableCell>
                          <Typography variant="body2" sx={{ fontFamily: "monospace", fontSize: "0.78rem" }}>
                            {det.factura}{det.nro_cuota != null ? ` #${det.nro_cuota}` : ""}
                          </Typography>
                        </TableCell>
                        <TableCell>
                          <Chip label={det.medio_pago} size="small" variant="outlined" sx={{ fontSize: "0.68rem", height: 20 }} />
                        </TableCell>
                        <TableCell align="right">
                          <Typography variant="body2" fontWeight={700} color="success.dark">
                            ₲ {formatMoney(det.monto_pagado)}
                          </Typography>
                          {det.descuento_aplicado > 0 && (
                            <Typography variant="caption" color="warning.main" display="block">
                              Desc: ₲ {formatMoney(det.descuento_aplicado)}
                            </Typography>
                          )}
                        </TableCell>
                      </TableRow>
                    )) : (
                      <TableRow key={recibo.id}>
                        <TableCell colSpan={5}>
                          <Typography variant="caption" color="text.secondary">
                            Recibo {recibo.numero_recibo} — {recibo.fecha} — ₲ {formatMoney(recibo.monto_total)}
                          </Typography>
                        </TableCell>
                      </TableRow>
                    )
                  )}
                </TableBody>
              </Table>
            </TableContainer>
          </>
        )}
      </Box>
    </Box>
  );
}

// ===== Styled Components =====
const Container = styled.div`
  background: ${({ theme }) => theme.body};
  min-height: 100%;
`;

const Header = styled.div`
  background: linear-gradient(135deg, ${({ theme }) => theme.bg3} 0%, ${({ theme }) => theme.bg4} 100%);
  border-bottom: 1px solid ${({ theme }) => theme.bg4};
  padding: 0.6rem 1.5rem 0.4rem;
  @media (max-width: 768px) { padding: 0.5rem 1rem 0.3rem; }
`;

const HeaderContent = styled.div`
  max-width: 1200px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 0.75rem;
`;

const BackBtn = styled.button`
  background: ${({ theme }) => theme.bg4}60;
  border: 1px solid ${({ theme }) => theme.bg4};
  border-radius: 8px;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: ${({ theme }) => theme.text};
  transition: all 0.15s;
  flex-shrink: 0;
  &:hover { background: ${({ theme }) => theme.bg4}; }
  svg { width: 1rem; height: 1rem; }
`;

const TitleSection = styled.div`
  flex: 1;
`;

const MainTitle = styled.h1`
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 1.3rem;
  font-weight: 700;
  color: ${({ theme }) => theme.text};
  margin: 0 0 0.1rem 0;
  svg { color: #f88533; width: 1.3rem; height: 1.3rem; }
  @media (max-width: 768px) { font-size: 1.1rem; svg { width: 1.1rem; height: 1.1rem; } }
`;

const Subtitle = styled.p`
  font-size: 0.78rem;
  color: ${({ theme }) => theme.text}cc;
  margin: 0;
  @media (max-width: 768px) { font-size: 0.7rem; }
`;

const HeaderActions = styled.div`
  display: flex;
  gap: 0.5rem;
  align-items: center;
`;

const ExportBtn = styled.button`
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.4rem 0.9rem;
  border-radius: 8px;
  border: 1px solid #22d3ee40;
  background: transparent;
  color: #22d3ee;
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.15s;
  white-space: nowrap;
  &:hover {
    background: #22d3ee15;
    border-color: #22d3ee;
  }
`;

const Breadcrumb = styled.div`
  max-width: 1200px;
  margin: 0.3rem auto 0;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.7rem;
`;

const BreadcrumbLink = styled.span`
  color: #22d3ee;
  cursor: pointer;
  &:hover { text-decoration: underline; }
`;

const BreadcrumbCurrent = styled.span`
  color: ${({ theme }) => theme.text}80;
`;

const Content = styled.div`
  max-width: 1200px;
  margin: 0 auto;
  padding: 1rem 1.5rem;
  @media (max-width: 768px) { padding: 0.75rem 1rem; }
`;

