import { Icon } from "@iconify/react";
import { useCallback, useEffect, useMemo, useState } from "react";
import { usePermission } from "../../hooks/usePermission";
import { useSubmodulo } from "../../hooks/useSubmodulo";
import { RingLoader } from "react-spinners";
import { toast } from "sonner";
import styled from "styled-components";
import { Link } from "react-router-dom";
import { searchClientes } from "../../api/clientes.service";
import {
  createCobroFromDistribucion,
  getCuotasPorFactura,
  getFacturasCreditoPendientes,
  getReciboPdf,
  previewDistribucion,
  verificarNumeracionRecibo,
} from "../../api/cobros.service";
import { getActivaParaFactura, getExoneracionesActivasPorCuotas, getPromesasVigentesCliente, marcarUsadaDescuento } from "../../api/cobranzas.service";
import { fmtMoneda } from "../_standards/enums/monedas";
import { BancoDatalist, buscarBanco, useBancosCatalogo } from "../_standards";
import { fmtFechaCalendario, fmtFechaHora, toFechaCalendarioISO } from "../../utils/fecha";
import { PromesaPagoFormModal } from "../cobranzas/promesas/PromesaPagoFormModal";
import { getCobradoresActivos, getMiCobrador } from "../../api/vendedores-cobradores.service";
import { getMediosPagoActivos } from "../../api/pagos.service";
import { printReciboWithFallback } from "../../services/printAgentService";
import { Device } from "../../styles/breakpoints";
import { useQuery } from "@tanstack/react-query";
import { getSucursales } from "../../api/sucursales.service";
import { usePosConfigQuery } from "../../tanstack/PosConfigStack";
import { useSesionActivaQuery } from "../../tanstack/TesoreriaStack";
import { BancardPagoModal } from "../bancard/BancardPagoModal";
import { getUltimoPagoFactura } from "../../api/recibos-multi.service";
import { SearchableSelect } from "../ui/SearchableSelect";

// Helper para obtener icono según tipo de medio de pago
const getMedioPagoIcon = (descripcion) => {
  if (!descripcion) return "lucide:credit-card";
  const desc = descripcion.toLowerCase();
  if (desc.includes("efectivo")) return "lucide:banknote";
  if (
    desc.includes("tarjeta") ||
    desc.includes("credito") ||
    desc.includes("debito")
  )
    return "lucide:credit-card";
  if (desc.includes("transferencia") || desc.includes("banco"))
    return "lucide:send";
  if (desc.includes("cheque")) return "lucide:file-text";
  return "lucide:wallet";
};

// Formatear moneda
/** Extrae solo dígitos de un string (para inputs numéricos) */
const cleanDigits = (v) => String(v).replace(/\D/g, "");
/** Formatea dígitos con separador de miles para mostrar en input */
const fmtInputNum = (v) => {
  const digits = cleanDigits(v);
  if (!digits) return "";
  return parseInt(digits, 10).toLocaleString("es-PY");
};

const formatMoney = (value, moneda = null) => {
  if (value === null || value === undefined) return "0";
  const num = Number(value);
  if (isNaN(num)) return "0";

  // El backend devuelve 'codigo' no 'codigo_iso'
  const iso = moneda?.codigo || moneda?.codigo_iso || "PYG";
  const symbol =
    moneda?.simbolo || (iso === "PYG" ? "Gs." : iso === "USD" ? "US$" : iso);

  if (iso === "PYG") {
    return `${symbol} ${num.toLocaleString("es-PY", { maximumFractionDigits: 0 })}`;
  }
  return `${symbol} ${num.toLocaleString("es-PY", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
};

// Convertir a Gs usando cotización
const convertToGs = (value, cotizacion) => {
  if (!cotizacion || !value) return null;
  const resul = Number(value) * Number(cotizacion);
  return resul;
};

export function CobrosTemplate() {
  const { can: canTesoreria } = usePermission("TESORERIA");
  const { data: sesionCaja } = useSesionActivaQuery(null, { enabled: canTesoreria("TES_CAJ_CAJA_VER") });
  const { data: posConfig } = usePosConfigQuery(sesionCaja?.caja_id);

  // Cachear config de impresora en localStorage para usarla sin sesión activa
  useEffect(() => {
    if (posConfig?.printer_name) {
      localStorage.setItem("pos_printer_name", posConfig.printer_name);
      localStorage.setItem("pos_paper_width", String(posConfig.printer_paper_width || 80));
    }
  }, [posConfig]);

  // Sucursal: viene de la caja activa, o la selecciona el usuario si no hay caja
  const [sucursalIdManual, setSucursalIdManual] = useState(null);
  const sucursalId = sesionCaja?.sucursal_id || sucursalIdManual;
  const sinCaja = !sesionCaja;

  const { data: sucursalesData } = useQuery({
    queryKey: ["sucursales-cobros"],
    queryFn: () => getSucursales(),
    enabled: sinCaja,
    staleTime: 60_000,
  });
  const sucursales = useMemo(() => {
    const raw = sucursalesData?.data || sucursalesData || [];
    return Array.isArray(raw) ? raw : [];
  }, [sucursalesData]);

  // Auto-seleccionar primera sucursal cuando no hay caja
  useEffect(() => {
    if (sinCaja && sucursales.length > 0 && !sucursalIdManual) {
      setSucursalIdManual(sucursales[0].id);
    }
  }, [sinCaja, sucursales, sucursalIdManual]);

  // Cargar al montar el cobrador vinculado al usuario logueado (si lo hay).
  useEffect(() => {
    let cancel = false;
    getMiCobrador()
      .then((data) => {
        if (cancel) return;
        const c = data?.data ?? data ?? null;
        setMiCobrador(c && c.id ? c : null);
      })
      .catch(() => {});
    return () => {
      cancel = true;
    };
  }, []);
  const { can: canCobranzas } = usePermission("COBRANZAS");
  const puedeAsignarCobrador = canCobranzas("COB_ASG_ASIGNACION_CREAR");
  const puedeVerPromesas = canCobranzas("COB_PRM_PROMESA_VER");
  // Si no tiene COB_REC_DESCUENTO_APLICAR solo puede usar descuentos pre-autorizados por el admin
  const puedeDescuentoLibre = canCobranzas("COB_REC_DESCUENTO_APLICAR");
  // Submódulo ADM_INTERES_MORA: si la empresa no lo tiene habilitado, no se muestra mora en cobros
  const { hasAccess: tieneModuloMora } = useSubmodulo("ADM_INTERES_MORA");
  const { hasAccess: tienePrintMobile } = useSubmodulo("COB_PRINT_MOBILE");

  // Estados principales
  const [searchQuery, setSearchQuery] = useState("");
  const [searchResults, setSearchResults] = useState([]);
  const [selectedCliente, setSelectedCliente] = useState(null);
  const [promesasVigentes, setPromesasVigentes] = useState([]);

  // Flujo jerárquico: Facturas -> Cuotas
  const [facturasCredito, setFacturasCredito] = useState([]);
  const [selectedFactura, setSelectedFactura] = useState(null);
  const [cuotasFactura, setCuotasFactura] = useState([]);
  const [selectedCuotas, setSelectedCuotas] = useState([]);

  // Medios de pago
  const [mediosPago, setMediosPago] = useState([]);
  const [selectedMedioPago, setSelectedMedioPago] = useState(null);
  const [numeroCheque, setNumeroCheque] = useState("");
  const [bancoEmisor, setBancoEmisor] = useState("");
  // El texto del banco es lo que exige SIFEN (dBcoEmi, 20 caracteres). El id se
  // resuelve contra el catálogo para poder agrupar y filtrar después sin
  // depender de cómo se escribió el nombre; si el usuario tipeó algo que no
  // está en el catálogo, queda en null y sólo se guarda el texto.
  const bancosCatalogo = useBancosCatalogo();

  // UI states
  const [loading, setLoading] = useState(false);
  const [loadingFacturas, setLoadingFacturas] = useState(false);
  const [loadingCuotas, setLoadingCuotas] = useState(false);
  const [procesando, setProcesando] = useState(false);
  const [showFacturaDetail, setShowFacturaDetail] = useState(null);

  const { data: ultimoPago, isLoading: loadingUltimoPago } = useQuery({
    queryKey: ["ultimoPagoFactura", showFacturaDetail?.id],
    queryFn: () => getUltimoPagoFactura(showFacturaDetail.id),
    enabled: !!showFacturaDetail?.id,
    staleTime: 60_000,
  });

  // Numeración de recibo
  const [numeracionRecibo, setNumeracionRecibo] = useState(null); // { existe, numeracion }
  const [loadingNumeracion, setLoadingNumeracion] = useState(false);

  // Diálogo de confirmación de cobro
  const [showConfirmDialog, setShowConfirmDialog] = useState(false);
  const [bancardModalOpen, setBancardModalOpen] = useState(false);
  const [montoEntregado, setMontoEntregado] = useState("");
  const [cobroExitoso, setCobroExitoso] = useState(null); // { numero_recibo, monto_total, vuelto }
  const [cobradorManual, setCobradorManual] = useState("");
  const [fechaRegistroManual, setFechaRegistroManual] = useState("");
  const [cobradores, setCobradores] = useState([]);
  const [miCobrador, setMiCobrador] = useState(null); // vendedor_cobrador vinculado al usuario logueado

  // Promesa de pago desde cobros — usa modal compartido
  const [promesaDialog, setPromesaDialog] = useState(null); // { cuota }

  // PDF Preview/Print
  const [pdfPreview, setPdfPreview] = useState(null); // { url, formato, cobroId }
  const [loadingPdf, setLoadingPdf] = useState(null); // cobroId being loaded
  const [printingAfterCobro, setPrintingAfterCobro] = useState(false);

  // Distribución y descuentos
  const [montoAPagar, setMontoAPagar] = useState("");
  const [descuentoTipo, setDescuentoTipo] = useState("none"); // none, porcentaje, monto
  const [descuentoValor, setDescuentoValor] = useState("");
  const [motivoDescuento, setMotivoDescuento] = useState("");
  const [distribucionPreview, setDistribucionPreview] = useState(null);
  // Al cambiar la distribución vuelve al default "cobrar todo el interés".
  const [loadingPreview, setLoadingPreview] = useState(false);
  // Descuento autorizado por admin (autorizaciones_descuento)
  const [descuentoAutorizado, setDescuentoAutorizado] = useState(null);
  // A.3.7: exoneraciones de mora vigentes por cuota (Map: factura_cuota_id → autorización)
  const [exoneracionesMora, setExoneracionesMora] = useState({});

  // A.3.7: monto exonerado calculado para una cuota (porcentaje sobre mora o monto fijo topeado)
  const getExoneracionPorCuota = (factura_cuota_id, mora_calculada) => {
    const auth = exoneracionesMora[factura_cuota_id];
    if (!auth || !mora_calculada || mora_calculada <= 0) return null;
    const monto = auth.descuento_porcentaje
      ? Math.round((Number(mora_calculada) * Number(auth.descuento_porcentaje)) / 100)
      : Math.min(Number(auth.descuento_monto ?? 0), Number(mora_calculada));
    if (monto <= 0) return null;
    return { auth, monto };
  };

  // Interés cargado a mano desde Cuentas por Cobrar. Acá no se edita ni se
  // exonera: el backend imputa capital primero y le da al interés lo que sobra
  // del monto que el cliente entregó. La pantalla solo muestra el resultado.
  const interesPendiente = Number(distribucionPreview?.resumen?.interes_manual_pendiente || 0);
  const totalInteresManual = Number(distribucionPreview?.resumen?.interes_manual_imputado || 0);
  const interesRestante = Number(distribucionPreview?.resumen?.interes_manual_restante || 0);
  const capitalImputado = Number(distribucionPreview?.resumen?.total_pagado || 0);

  // A.3.7: total exonerado en la distribución actual
  const totalExoneradoMora = (() => {
    if (!distribucionPreview?.distribucion) return 0;
    return distribucionPreview.distribucion.reduce((sum, d) => {
      const exo = getExoneracionPorCuota(d.factura_cuota_id, d.mora_calculada);
      return sum + (exo?.monto ?? 0);
    }, 0);
  })();

  // Buscar clientes
  const handleSearch = useCallback(async (query) => {
    if (query.length < 2) {
      setSearchResults([]);
      return;
    }
    setLoading(true);
    try {
      const results = await searchClientes(query, 10);
      console.log({ results });
      setSearchResults(results);
    } catch (error) {
      console.error("Error buscando clientes:", error);
    } finally {
      setLoading(false);
    }
  }, []);

  // Cargar medios de pago al montar
  useEffect(() => {
    const loadMediosPago = async () => {
      try {
        const medios = await getMediosPagoActivos();
        setMediosPago(medios || []);
        const efectivo = medios?.find((m) =>
          m.descripcion?.toLowerCase().includes("efectivo"),
        );
        if (efectivo) {
          setSelectedMedioPago(efectivo.id);
        } else if (medios?.length > 0) {
          setSelectedMedioPago(medios[0].id);
        }
      } catch (error) {
        console.error("Error cargando medios de pago:", error);
      }
    };
    loadMediosPago();
  }, []);

  // Verificar numeración de recibo cuando haya sucursal definida
  useEffect(() => {
    const checkNumeracion = async () => {
      if (!sucursalId) return;
      setLoadingNumeracion(true);
      try {
        const result = await verificarNumeracionRecibo(sucursalId);
        setNumeracionRecibo(result);
      } catch (error) {
        console.error("Error verificando numeración de recibo:", error);
        setNumeracionRecibo({ existe: false, numeracion: null });
      } finally {
        setLoadingNumeracion(false);
      }
    };
    checkNumeracion();
  }, [sucursalId]);

  // Debounce para búsqueda
  useEffect(() => {
    const timer = setTimeout(() => {
      handleSearch(searchQuery);
    }, 300);
    return () => clearTimeout(timer);
  }, [searchQuery, handleSearch]);

  // Seleccionar cliente -> cargar facturas crédito
  const handleSelectCliente = async (cliente) => {
    console.log({ cliente });
    setSelectedCliente(cliente);
    setSearchQuery("");
    setSearchResults([]);
    setSelectedFactura(null);
    setCuotasFactura([]);
    setSelectedCuotas([]);
    setLoadingFacturas(true);

    try {
      const facturas = await getFacturasCreditoPendientes(cliente.id);
      setFacturasCredito(facturas || []);
    } catch (error) {
      console.error("Error cargando facturas del cliente:", error);
      toast.error("Error al cargar facturas del cliente");
    } finally {
      setLoadingFacturas(false);
    }

    if (puedeVerPromesas) {
      getPromesasVigentesCliente(cliente.id)
        .then((data) => {
          const list = Array.isArray(data) ? data : data?.promesas || data?.data || [];
          setPromesasVigentes(list);
        })
        .catch(() => setPromesasVigentes([]));
    } else {
      setPromesasVigentes([]);
    }
  };

  // Seleccionar factura -> cargar cuotas + verificar descuento autorizado
  const handleSelectFactura = async (factura) => {
    setSelectedFactura(factura);
    setSelectedCuotas([]);
    setLoadingCuotas(true);
    setDescuentoAutorizado(null);

    try {
      const [cuotas, descAuth] = await Promise.all([
        getCuotasPorFactura(factura.id),
        getActivaParaFactura(factura.id).catch(() => ({ data: null })),
      ]);
      setCuotasFactura(cuotas || []);
      if (descAuth?.data) setDescuentoAutorizado(descAuth.data);
    } catch (error) {
      console.error("Error cargando cuotas:", error);
      toast.error("Error al cargar cuotas de la factura");
    } finally {
      setLoadingCuotas(false);
    }
  };

  // Toggle selección de cuota
  const toggleCuotaSelection = (cuota) => {
    setSelectedCuotas((prev) => {
      const exists = prev.find((c) => c.id === cuota.id);
      if (exists) {
        return prev.filter((c) => c.id !== cuota.id);
      }
      return [...prev, cuota];
    });
  };

  // Seleccionar todas las cuotas
  const handleSelectAllCuotas = () => {
    if (selectedCuotas.length === cuotasFactura.length) {
      setSelectedCuotas([]);
    } else {
      setSelectedCuotas([...cuotasFactura]);
    }
  };

  // Calcular total seleccionado
  const totalSeleccionado = selectedCuotas.reduce(
    (sum, c) => sum + Number(c.saldo_pendiente || c.dmoncuota),
    0,
  );

  // Factura con el capital saldado que todavía debe interés manual de la
  // cuenta: se cobra sin cuotas, solo el interés.
  const interesFacturaSoloInteres = Number(selectedFactura?.interes_manual_pendiente || 0);
  const soloInteres =
    !!selectedFactura &&
    Number(selectedFactura.cuotas_pendientes) === 0 &&
    interesFacturaSoloInteres > 0;
  const haySeleccion = selectedCuotas.length > 0 || soloInteres;

  // Tope del campo de monto: el capital de las cuotas más el interés pendiente.
  // El excedente sobre el capital es, justamente, lo que paga el interés; con
  // el tope viejo (solo capital) el interés nunca podría imputarse.
  const totalACobrarMaximo = totalSeleccionado + (soloInteres ? interesFacturaSoloInteres : interesPendiente);
  // Lo que se precarga en el monto (y a lo que vuelve el botón de reinicio).
  const montoSugerido = soloInteres ? interesFacturaSoloInteres : totalSeleccionado;

  // Moneda de la factura seleccionada
  const monedaFactura = selectedFactura?.moneda;
  const cotizacionFactura = selectedFactura?.dticam;
  const esMonedaExtranjera = monedaFactura && monedaFactura.codigo !== "PYG";

  // Inicializar monto cuando cambian cuotas seleccionadas
  useEffect(() => {
    if (selectedCuotas.length > 0) {
      const total = selectedCuotas.reduce(
        (sum, c) => sum + Number(c.saldo_pendiente || c.dmoncuota),
        0,
      );
      setMontoAPagar(String(Math.round(total)));
    } else if (soloInteres) {
      setMontoAPagar(String(Math.round(interesFacturaSoloInteres)));
      setDistribucionPreview(null);
      setDescuentoTipo("none");
      setDescuentoValor("");
      setMotivoDescuento("");
    } else {
      setMontoAPagar("");
      setDistribucionPreview(null);
      setDescuentoTipo("none");
      setDescuentoValor("");
      setMotivoDescuento("");
    }
  }, [selectedCuotas, soloInteres, interesFacturaSoloInteres]);

  // Fetch preview de distribución
  const fetchPreview = useCallback(async () => {
    if (!haySeleccion || !selectedMedioPago) return;
    const monto = Number(montoAPagar);
    if (!monto || monto <= 0) {
      setDistribucionPreview(null);
      return;
    }

    setLoadingPreview(true);
    try {
      const dto = {
        cuota_ids: selectedCuotas.map((c) => c.id),
        ...(soloInteres && { factura_ids: [selectedFactura.id] }),
        monto_recibido: monto,
        medio_pago_id: selectedMedioPago,
        moneda_id: monedaFactura?.id || undefined,
        cotizacion: cotizacionFactura || undefined,
      };

      if (descuentoTipo === "porcentaje" && Number(descuentoValor) > 0) {
        dto.descuento_porcentaje = Number(descuentoValor);
      } else if (descuentoTipo === "monto" && Number(descuentoValor) > 0) {
        dto.descuento_monto = Number(descuentoValor);
      }
      if (motivoDescuento) dto.motivo_descuento = motivoDescuento;

      const preview = await previewDistribucion(dto);
      setDistribucionPreview(preview);

      // A.3.7: traer exoneraciones de mora vigentes para las cuotas con mora > 0
      try {
        const cuotasConMora = (preview?.distribucion ?? [])
          .filter((d) => (d.mora_calculada ?? 0) > 0)
          .map((d) => d.factura_cuota_id);
        if (cuotasConMora.length > 0) {
          const exos = await getExoneracionesActivasPorCuotas(cuotasConMora);
          const map = {};
          for (const a of exos ?? []) {
            if (a.factura_cuota_id) map[a.factura_cuota_id] = a;
          }
          setExoneracionesMora(map);
        } else {
          setExoneracionesMora({});
        }
      } catch {
        setExoneracionesMora({});
      }
    } catch (error) {
      console.error("Error en preview:", error);
      setDistribucionPreview(null);
    } finally {
      setLoadingPreview(false);
    }
  }, [
    selectedCuotas,
    haySeleccion,
    soloInteres,
    selectedFactura,
    montoAPagar,
    selectedMedioPago,
    descuentoTipo,
    descuentoValor,
    motivoDescuento,
    monedaFactura,
    cotizacionFactura,
  ]);

  // Auto-fetch preview con debounce
  useEffect(() => {
    if (!haySeleccion) return;
    const timer = setTimeout(() => {
      fetchPreview();
    }, 500);
    return () => clearTimeout(timer);
  }, [fetchPreview, haySeleccion]);

  // Abrir diálogo de confirmación (validación previa)
  const esChequeSeleccionado = Number(mediosPago.find((m) => m.id === selectedMedioPago)?.codigo) === 2;

  const handleProcesarCobro = async () => {
    if (!haySeleccion) {
      toast.error("Seleccione al menos una cuota para cobrar");
      return;
    }
    if (!selectedMedioPago) {
      toast.error("Seleccione un medio de pago");
      return;
    }
    if (esChequeSeleccionado) {
      if (!numeroCheque.trim() || numeroCheque.trim().length !== 8) {
        toast.error("El número de cheque debe tener exactamente 8 caracteres");
        return;
      }
      if (!bancoEmisor.trim() || bancoEmisor.trim().length < 4 || bancoEmisor.trim().length > 20) {
        toast.error("El banco emisor debe tener entre 4 y 20 caracteres");
        return;
      }
    }
    const monto = Number(montoAPagar);
    if (!monto || monto <= 0) {
      toast.error("Ingrese un monto válido a pagar");
      return;
    }
    const moraNetaTotal = tieneModuloMora
      ? Math.max(0, Math.round((distribucionPreview?.resumen.total_mora || 0) - totalExoneradoMora))
      : 0;
    const totalACobrar = distribucionPreview
      ? Math.round(distribucionPreview.resumen.total_pagado) + moraNetaTotal + totalInteresManual
      : Number(montoAPagar);
    setMontoEntregado(String(totalACobrar));
    setCobroExitoso(null);
    // Fecha de hoy por defecto (local, no UTC)
    const d = new Date();
    const y = d.getFullYear();
    const m = String(d.getMonth() + 1).padStart(2, "0");
    const day = String(d.getDate()).padStart(2, "0");
    setFechaRegistroManual(`${y}-${m}-${day}`);
    // Orden de pre-selección (mismo que el backend):
    //   1. Cobrador vinculado al usuario logueado
    //   2. Cobrador asignado a la factura (factura_cab.cobrador_id)
    //   3. vacío → backend cae a null
    const defaultCobrador = miCobrador?.id || selectedFactura?.cobrador_id || "";
    setCobradorManual(defaultCobrador);
    // Cargar cobradores si tiene permiso para reasignar.
    if (puedeAsignarCobrador && cobradores.length === 0) {
      getCobradoresActivos()
        .then((data) => setCobradores(Array.isArray(data) ? data : data?.data || []))
        .catch(() => {});
    }
    setShowConfirmDialog(true);
  };

  // Confirmar cobro desde el diálogo
  const handleConfirmarCobroFinal = async () => {
    setProcesando(true);
    try {
      const monto = Number(montoAPagar);
      const distribucionDto = {
        cuota_ids: selectedCuotas.map((c) => c.id),
        ...(soloInteres && { factura_ids: [selectedFactura.id] }),
        monto_recibido: monto,
        medio_pago_id: selectedMedioPago,
        moneda_id: monedaFactura?.id || undefined,
        cotizacion: cotizacionFactura || undefined,
      };

      if (descuentoTipo === "porcentaje" && Number(descuentoValor) > 0) {
        distribucionDto.descuento_porcentaje = Number(descuentoValor);
      } else if (descuentoTipo === "monto" && Number(descuentoValor) > 0) {
        distribucionDto.descuento_monto = Number(descuentoValor);
      }
      if (motivoDescuento) distribucionDto.motivo_descuento = motivoDescuento;
      // El interés no se manda: lo imputa el backend después del capital, con
      // lo que sobra de monto_recibido. Mandarlo sería dejar que la ventanilla
      // decida cuánto interés paga el cliente.

      // A.3.7: armar payload de exoneraciones de mora a partir de las autorizaciones vigentes
      const exoneracionesPayload = tieneModuloMora
        ? (distribucionPreview?.distribucion ?? []).reduce((acc, d) => {
            const exo = getExoneracionPorCuota(d.factura_cuota_id, d.mora_calculada);
            if (exo && exo.monto > 0) {
              acc.push({
                factura_cuota_id: d.factura_cuota_id,
                monto_exonerado: exo.monto,
                autorizacion_descuento_id: exo.auth?.id ?? null,
              });
            }
            return acc;
          }, [])
        : [];

      const resultado = await createCobroFromDistribucion({
        distribucion: distribucionDto,
        sucursal_id: sucursalId,
        sesion_caja_id: sesionCaja?.id || null,
        cliente_id: selectedCliente.id,
        cobrador_id: cobradorManual || undefined,
        fecha_emision: fechaRegistroManual || undefined,
        ...(esChequeSeleccionado && {
          numero_cheque: numeroCheque.trim(),
          banco_emisor: bancoEmisor.trim(),
          banco_id: buscarBanco(bancoEmisor, bancosCatalogo)?.id || undefined,
        }),
        ...(exoneracionesPayload.length > 0 && { exoneraciones_intereses: exoneracionesPayload }),
      });

      const moraNetaTotalConfirm = tieneModuloMora
        ? Math.max(0, (distribucionPreview?.resumen.total_mora || 0) - totalExoneradoMora)
        : 0;
      const totalPagado = distribucionPreview
        ? distribucionPreview.resumen.total_pagado + moraNetaTotalConfirm + totalInteresManual
        : monto;
      const entregado = Number(montoEntregado) || 0;
      const vuelto = entregado > totalPagado ? entregado - totalPagado : 0;

      const reciboId = resultado?.id || resultado?.data?.id;
      setCobroExitoso({
        id: reciboId,
        numero_recibo:
          resultado?.numero_recibo || resultado?.data?.numero_recibo || "—",
        monto_total: totalPagado,
        monto_entregado: entregado,
        vuelto,
      });

      // Marcar descuento autorizado como usado
      if (descuentoAutorizado && descuentoTipo !== "none") {
        marcarUsadaDescuento(descuentoAutorizado.id, reciboId).catch(() => {});
        setDescuentoAutorizado(null);
      }

      // Auto-print ticket si está configurado
      if (posConfig?.auto_print_ticket && reciboId) {
        setPrintingAfterCobro(true);
        handlePrintTicket(reciboId).finally(() => setPrintingAfterCobro(false));
      }

      // Recargar datos
      const facturas = await getFacturasCreditoPendientes(selectedCliente.id);
      setFacturasCredito(facturas || []);

      // Refrescar numeración
      if (sucursalId) {
        verificarNumeracionRecibo(sucursalId)
          .then((r) => setNumeracionRecibo(r))
          .catch(() => {});
      }

      // Si la factura ya no tiene cuotas pendientes, deseleccionarla
      const facturaActualizada = facturas?.find(
        (f) => f.id === selectedFactura?.id,
      );
      if (!facturaActualizada) {
        setSelectedFactura(null);
        setCuotasFactura([]);
      } else {
        const cuotas = await getCuotasPorFactura(selectedFactura.id);
        setCuotasFactura(cuotas || []);
      }
      setSelectedCuotas([]);
      setDistribucionPreview(null);
      setDescuentoTipo("none");
      setDescuentoValor("");
      setMotivoDescuento("");
    } catch (error) {
      console.error("Error procesando cobro:", error);
      setShowConfirmDialog(false);
      const msg = error?.response?.data?.message || error?.message || "Error al procesar el cobro";
      setTimeout(() => toast.error(msg, { duration: 6000 }), 100);
    } finally {
      setProcesando(false);
    }
  };

  // Cerrar diálogo de confirmación
  const handleCerrarConfirmDialog = () => {
    setShowConfirmDialog(false);
    setCobroExitoso(null);
    setMontoEntregado("");
    setCobradorManual("");
    setFechaRegistroManual("");
  };

  // Abre el modal compartido para la cuota seleccionada
  const handleAbrirPromesa = (cuota) => {
    setPromesaDialog({ cuota });
  };

  const handlePreviewRecibo = async (cobroId, formato = "a4") => {
    setLoadingPdf(cobroId);
    try {
      const paperWidth = posConfig?.printer_paper_width || Number(localStorage.getItem("pos_paper_width")) || 80;
      const blob = await getReciboPdf(cobroId, { formato, paper_width: paperWidth });
      const url = URL.createObjectURL(blob);
      setPdfPreview({ url, formato, cobroId });
    } catch (error) {
      console.error("Error obteniendo PDF:", error);
      toast.error("Error al obtener el recibo PDF");
    } finally {
      setLoadingPdf(null);
    }
  };

  // Imprimir ticket — cascade: Novasis Print agent → QZ Tray → browser
  const handlePrintTicket = async (cobroId) => {
    setLoadingPdf(cobroId);
    try {
      const printerName = posConfig?.printer_name || localStorage.getItem("pos_printer_name") || null;
      const paperWidth = posConfig?.printer_paper_width || Number(localStorage.getItem("pos_paper_width")) || 80;
      const mobileEnabled = tienePrintMobile && !!posConfig?.print_mobile_enabled;

      const { method } = await printReciboWithFallback({
        cobroId,
        printerName,
        paperWidth,
        mobileEnabled,
        agentRetries: 1,
        getPdfBlob: (anchoOverride) =>
          getReciboPdf(cobroId, { formato: "ticket", paper_width: anchoOverride || paperWidth }),
      });

      if (method === "agent") {
        toast.success("Ticket enviado a la impresora Bluetooth");
      } else if (method === "qz") {
        toast.success("Ticket enviado a la impresora");
      } else {
        // Browser fallback — siempre abre el PDF
        toast.info("Ticket abierto en el navegador para imprimir.", { duration: 4000 });
      }
    } catch (error) {
      console.error("Error imprimiendo ticket:", error);
      toast.error(`Error al imprimir: ${error?.message || "Error desconocido"}`, { duration: 6000 });
    } finally {
      setLoadingPdf(null);
    }
  };

  // Cerrar preview PDF
  const handleClosePdfPreview = () => {
    if (pdfPreview?.url) {
      URL.revokeObjectURL(pdfPreview.url);
    }
    setPdfPreview(null);
  };

  // Limpiar selección
  const handleLimpiar = () => {
    setSelectedCliente(null);
    setFacturasCredito([]);
    setSelectedFactura(null);
    setCuotasFactura([]);
    setSelectedCuotas([]);
    setSearchQuery("");
    setPromesasVigentes([]);
  };

  // Volver a lista de facturas
  const handleVolverFacturas = () => {
    setSelectedFactura(null);
    setCuotasFactura([]);
    setSelectedCuotas([]);
  };

  // Determinar estado de cuota
  const getCuotaEstado = (cuota) => {
    const hoy = new Date();
    const vencimiento = new Date(cuota.dvenccuo);
    const diffDays = Math.ceil((vencimiento - hoy) / (1000 * 60 * 60 * 24));

    if (diffDays < 0) {
      const diasAtraso = Math.abs(diffDays);
      return {
        label: `Vencida · ${diasAtraso} ${diasAtraso === 1 ? "día" : "días"}`,
        color: "#ef4444",
        icon: "lucide:alert-circle",
        diasAtraso,
      };
    }
    if (diffDays <= 7)
      return {
        label: `Por vencer · ${diffDays}d`,
        color: "#f59e0b",
        icon: "lucide:clock",
        diasRestantes: diffDays,
      };
    return { label: "Al día", color: "#22c55e", icon: "lucide:check-circle" };
  };

  return (
    <Container>
      <Header>
        <HeaderTitle>
          <Icon icon="lucide:receipt" />
          Gestión de Cobros
        </HeaderTitle>
        {sesionCaja ? (
          <CajaInfo title={`Sesión abierta el ${fmtFechaHora(sesionCaja.fecha_apertura)}`}>
            <Icon icon="lucide:check-circle" />
            {sesionCaja.cajas?.descripcion || "Caja"}
            {sesionCaja.empresas_sucursales?.descripcion
              ? ` · ${sesionCaja.empresas_sucursales.descripcion}`
              : ""}
            {" · "}
            {fmtFechaHora(sesionCaja.fecha_apertura)}
          </CajaInfo>
        ) : (
          <SucursalSelector>
            <Icon icon="lucide:building-2" style={{ flexShrink: 0 }} />
            <select
              value={sucursalIdManual || ""}
              onChange={(e) => setSucursalIdManual(e.target.value)}
              style={{
                background: "transparent",
                border: "none",
                color: "inherit",
                fontSize: "0.8rem",
                cursor: "pointer",
                outline: "none",
                maxWidth: 160,
              }}
            >
              {sucursales.map((s) => (
                <option key={s.id} value={s.id} style={{ background: "#1f2937", color: "#f9fafb" }}>
                  {s.descripcion || s.nombre}
                </option>
              ))}
            </select>
          </SucursalSelector>
        )}
      </Header>

      <MainContent>
        {/* Panel de búsqueda de cliente */}
        <SearchPanel>
          <PanelHeader>
            <PanelTitle>
              <Icon icon="lucide:search" />
              Buscar Cliente
            </PanelTitle>
            {selectedCliente && (
              <ClearButton onClick={handleLimpiar}>
                <Icon icon="lucide:x" />
              </ClearButton>
            )}
          </PanelHeader>

          {!selectedCliente ? (
            <SearchContainer>
              <SearchInput
                type="text"
                placeholder="RUC, nombre o teléfono..."
                value={searchQuery}
                onChange={(e) => setSearchQuery(e.target.value)}
              />
              {loading && <RingLoader color="#f88533" size={20} />}

              {searchResults.length > 0 && (
                <SearchResultsList>
                  {searchResults.map((cliente) => (
                    <SearchResultItem
                      key={cliente.id}
                      onClick={() => handleSelectCliente(cliente)}
                    >
                      <ClienteAvatar>
                        {cliente.personas?.razon_social
                          ?.charAt(0)
                          ?.toUpperCase() || "C"}
                      </ClienteAvatar>
                      <ClienteInfo>
                        <ClienteNombre>
                          {cliente.personas?.razon_social}
                        </ClienteNombre>
                        <ClienteRuc>
                          RUC:{" "}
                          {cliente.personas?.ruc ||
                            cliente.personas?.nro_documento}
                        </ClienteRuc>
                      </ClienteInfo>
                    </SearchResultItem>
                  ))}
                </SearchResultsList>
              )}
            </SearchContainer>
          ) : (
            <SelectedClienteCard>
              <ClienteAvatar $large>
                {selectedCliente.personas?.razon_social
                  ?.charAt(0)
                  ?.toUpperCase() || "C"}
              </ClienteAvatar>
              <ClienteInfo>
                <ClienteNombre>
                  {selectedCliente.personas?.razon_social}
                </ClienteNombre>
                <ClienteRuc>
                  RUC:{" "}
                  {selectedCliente.personas?.ruc ||
                    selectedCliente.personas?.nro_documento}
                </ClienteRuc>
              </ClienteInfo>
              <ClearButton onClick={handleLimpiar}>
                <Icon icon="lucide:x" />
              </ClearButton>
            </SelectedClienteCard>
          )}
        </SearchPanel>

        {/* Banner de promesas vigentes del cliente */}
        {selectedCliente && puedeVerPromesas && promesasVigentes.length > 0 && (() => {
          const hoyISO = toFechaCalendarioISO(new Date());
          const enriched = promesasVigentes.map((p) => {
            const promISO = toFechaCalendarioISO(p.fecha_prometida);
            return { ...p, _vencida: promISO && hoyISO && promISO < hoyISO };
          });
          const vencidasCount = enriched.filter((p) => p._vencida).length;
          const totalPorMoneda = new Map();
          enriched.forEach((p) => {
            const code = p.factura?.moneda?.codigo || "PYG";
            totalPorMoneda.set(code, (totalPorMoneda.get(code) || 0) + Number(p.monto_prometido || 0));
          });
          const ordenadas = [...enriched].sort((a, b) => {
            if (a._vencida !== b._vencida) return a._vencida ? -1 : 1;
            return (a.fecha_prometida || "").localeCompare(b.fecha_prometida || "");
          });
          return (
            <PromesasBanner $alerta={vencidasCount > 0}>
              <PromesasBannerHeader>
                <PromesasBannerHeaderLeft>
                  <PromesasBannerIcon $alerta={vencidasCount > 0}>
                    <Icon icon="mdi:handshake" width={18} />
                  </PromesasBannerIcon>
                  <PromesasBannerStats>
                    <PromesasBannerStatLabel>Promesas vigentes</PromesasBannerStatLabel>
                    <PromesasBannerStatValue>
                      {enriched.length}
                      {vencidasCount > 0 && (
                        <PromesasBannerVencidasBadge>
                          <Icon icon="mdi:alert-circle" width={12} />
                          {vencidasCount} vencida{vencidasCount === 1 ? "" : "s"}
                        </PromesasBannerVencidasBadge>
                      )}
                    </PromesasBannerStatValue>
                    <PromesasBannerTotals>
                      {Array.from(totalPorMoneda.entries()).map(([code, total]) => (
                        <span key={code}>{fmtMoneda(total, code)}</span>
                      ))}
                    </PromesasBannerTotals>
                  </PromesasBannerStats>
                </PromesasBannerHeaderLeft>
                <PromesasBannerLink
                  to={`/cobranzas/promesas?cliente_id=${selectedCliente.id}`}
                  title="Ver detalle de promesas del cliente"
                >
                  Ver detalle
                  <Icon icon="mdi:arrow-right" width={14} />
                </PromesasBannerLink>
              </PromesasBannerHeader>
              <PromesasBannerList>
                {ordenadas.slice(0, 4).map((p) => {
                  const code = p.factura?.moneda?.codigo || "PYG";
                  return (
                    <PromesasBannerChip key={p.id} $vencida={p._vencida}>
                      <Icon icon={p._vencida ? "mdi:alert-circle" : "mdi:calendar-clock"} width={13} />
                      <span>{fmtFechaCalendario(p.fecha_prometida)}</span>
                      <PromesasBannerChipMonto>{fmtMoneda(p.monto_prometido, code)}</PromesasBannerChipMonto>
                    </PromesasBannerChip>
                  );
                })}
                {ordenadas.length > 4 && (
                  <PromesasBannerMore>+{ordenadas.length - 4} más</PromesasBannerMore>
                )}
              </PromesasBannerList>
            </PromesasBanner>
          );
        })()}

        {/* Panel de Facturas Crédito */}
        {selectedCliente && !selectedFactura && (
          <FacturasPanel>
            <PanelHeader>
              <PanelTitle>
                <Icon icon="lucide:file-text" />
                Facturas Crédito Pendientes ({facturasCredito.length})
              </PanelTitle>
            </PanelHeader>

            {loadingFacturas ? (
              <LoadingContainer>
                <RingLoader color="#f88533" size={40} />
              </LoadingContainer>
            ) : facturasCredito.length === 0 ? (
              <EmptyState>
                <Icon icon="lucide:file-x" />
                <span>No hay facturas crédito pendientes</span>
              </EmptyState>
            ) : (
              <FacturasList>
                {facturasCredito.map((factura) => (
                  <FacturaCard key={factura.id}>
                    <FacturaHeader>
                      <FacturaNumero>
                        <Icon icon="lucide:file-text" />
                        {factura.numero_factura}
                      </FacturaNumero>
                      <MonedaBadge
                        $extranjera={factura.moneda?.codigo !== "PYG"}
                      >
                        {factura.moneda?.codigo || "PYG"}
                      </MonedaBadge>
                    </FacturaHeader>

                    <FacturaBody>
                      <FacturaInfo>
                        <InfoRow>
                          <span>Fecha:</span>
                          <strong>{factura.fecha_emision}</strong>
                        </InfoRow>
                        <InfoRow>
                          <span>Total:</span>
                          <strong>
                            {formatMoney(factura.total_factura, factura.moneda)}
                          </strong>
                        </InfoRow>
                        <InfoRow $highlight>
                          <span>Saldo pendiente:</span>
                          <SaldoPendiente>
                            {formatMoney(
                              factura.saldo_pendiente,
                              factura.moneda,
                            )}
                          </SaldoPendiente>
                        </InfoRow>
                        {Number(factura.interes_manual_pendiente) > 0 && (
                          <InfoRow $highlight>
                            <span>Interés manual pendiente:</span>
                            <SaldoPendiente>
                              {formatMoney(
                                factura.interes_manual_pendiente,
                                factura.moneda,
                              )}
                            </SaldoPendiente>
                          </InfoRow>
                        )}
                        {factura.moneda?.codigo !== "PYG" && factura.dticam && (
                          <InfoRow $secondary>
                            <span>≈ en Gs:</span>
                            <span>
                              Gs.{" "}
                              {convertToGs(
                                factura.saldo_pendiente,
                                factura.dticam,
                              )?.toLocaleString("es-PY", {
                                maximumFractionDigits: 0,
                              })}
                            </span>
                          </InfoRow>
                        )}
                      </FacturaInfo>

                      <CuotasProgress>
                        <ProgressLabel>
                          {factura.cuotas_pagadas}/{factura.cuotas_total} cuotas
                          pagadas
                        </ProgressLabel>
                        <ProgressBar>
                          <ProgressFill
                            style={{
                              width: `${(factura.cuotas_pagadas / factura.cuotas_total) * 100}%`,
                            }}
                          />
                        </ProgressBar>
                      </CuotasProgress>
                    </FacturaBody>

                    <FacturaActions>
                      <ActionButton
                        onClick={() => setShowFacturaDetail(factura)}
                      >
                        <Icon icon="lucide:eye" />
                        Ver detalle
                      </ActionButton>
                      <ActionButton
                        $primary
                        onClick={() => handleSelectFactura(factura)}
                      >
                        <Icon icon="lucide:credit-card" />
                        Cobrar
                      </ActionButton>
                    </FacturaActions>
                  </FacturaCard>
                ))}
              </FacturasList>
            )}
          </FacturasPanel>
        )}

        {/* Panel de Cuotas de Factura Seleccionada */}
        {selectedFactura && (
          <CuotasPanel>
            <PanelHeader>
              <BackButton onClick={handleVolverFacturas}>
                <Icon icon="lucide:arrow-left" />
              </BackButton>
              <PanelTitle>
                <Icon icon="lucide:list" />
                Cuotas - {selectedFactura.numero_factura}
                <MonedaBadge
                  $extranjera={esMonedaExtranjera}
                  style={{ marginLeft: 8 }}
                >
                  {monedaFactura?.codigo || "PYG"}
                </MonedaBadge>
              </PanelTitle>
              {cuotasFactura.length > 0 && (
                <SelectAllButton onClick={handleSelectAllCuotas}>
                  {selectedCuotas.length === cuotasFactura.length
                    ? "Deseleccionar"
                    : "Seleccionar todo"}
                </SelectAllButton>
              )}
            </PanelHeader>

            {loadingCuotas ? (
              <LoadingContainer>
                <RingLoader color="#f88533" size={40} />
              </LoadingContainer>
            ) : cuotasFactura.length === 0 ? (
              <EmptyState>
                <Icon icon="lucide:check-circle" />
                <span>
                  {soloInteres
                    ? `El capital está saldado. Queda ${formatMoney(interesFacturaSoloInteres, monedaFactura)} de interés por cobrar.`
                    : "No hay cuotas pendientes"}
                </span>
              </EmptyState>
            ) : (
              <CuotasList>
                {cuotasFactura.map((cuota) => {
                  const estado = getCuotaEstado(cuota);
                  const isSelected = selectedCuotas.some(
                    (c) => c.id === cuota.id,
                  );
                  const montoGs =
                    esMonedaExtranjera && cotizacionFactura
                      ? convertToGs(cuota.saldo_pendiente, cotizacionFactura)
                      : null;

                  return (
                    <CuotaItem
                      key={cuota.id}
                      $selected={isSelected}
                      onClick={() => toggleCuotaSelection(cuota)}
                    >
                      <CuotaCheckbox $checked={isSelected}>
                        {isSelected && <Icon icon="lucide:check" />}
                      </CuotaCheckbox>
                      <CuotaContent>
                        <CuotaNumero>Cuota {cuota.nro_cuota}</CuotaNumero>
                        <CuotaVencimiento>
                          Vence: {cuota.dvenccuo}
                        </CuotaVencimiento>
                      </CuotaContent>
                      <CuotaMontos>
                        <CuotaMontoOriginal>
                          {formatMoney(cuota.saldo_pendiente, monedaFactura)}
                        </CuotaMontoOriginal>
                        {montoGs && (
                          <CuotaMontoGs>
                            ≈ Gs.{" "}
                            {montoGs.toLocaleString("es-PY", {
                              maximumFractionDigits: 0,
                            })}
                          </CuotaMontoGs>
                        )}
                      </CuotaMontos>
                      <CuotaEstadoBadge
                        style={{
                          background: `${estado.color}15`,
                          color: estado.color,
                        }}
                      >
                        <Icon icon={estado.icon} />
                        {estado.label}
                      </CuotaEstadoBadge>
                      <PromesaBtn
                        title="Registrar promesa de pago"
                        onClick={(e) => {
                          e.stopPropagation();
                          handleAbrirPromesa(cuota);
                        }}
                      >
                        <Icon icon="lucide:calendar-plus" />
                      </PromesaBtn>
                    </CuotaItem>
                  );
                })}
              </CuotasList>
            )}
          </CuotasPanel>
        )}

        {/* Panel de Cobro */}
        {haySeleccion && (
          <CobroPanel>
            <PanelHeader>
              <PanelTitle>
                <Icon icon="lucide:credit-card" />
                Registrar Cobro
              </PanelTitle>
              {numeracionRecibo?.existe && numeracionRecibo?.numeracion && (
                <NumeracionBadge>
                  <Icon icon="lucide:hash" />
                  Sig: {numeracionRecibo.numeracion.siguiente_numero}
                </NumeracionBadge>
              )}
            </PanelHeader>

            {loadingNumeracion && (
              <NumeracionWarning>
                <Icon icon="lucide:loader" />
                Verificando numeración de recibos...
              </NumeracionWarning>
            )}

            {!loadingNumeracion &&
              numeracionRecibo &&
              !numeracionRecibo.existe && (
                <NumeracionWarning $error>
                  <Icon icon="lucide:alert-triangle" />
                  <div>
                    <strong>Sin numeración de recibo</strong>
                    <p>
                      No se encontró una numeración activa para &quot;Recibo de
                      pago&quot; en esta sucursal. Configure una numeración con
                      tipo de documento código 100 antes de continuar.
                    </p>
                  </div>
                </NumeracionWarning>
              )}

            {(numeracionRecibo?.existe || numeracionRecibo === null) &&
              !loadingNumeracion && (
                <>
                  <CobroResumen>
                    {soloInteres ? (
                      <ResumenItem>
                        <span>Interés manual pendiente:</span>
                        <strong>
                          {formatMoney(interesFacturaSoloInteres, monedaFactura)}
                        </strong>
                      </ResumenItem>
                    ) : (
                      <>
                        <ResumenItem>
                          <span>Cuotas seleccionadas:</span>
                          <strong>{selectedCuotas.length}</strong>
                        </ResumenItem>
                        <ResumenItem>
                          <span>Total de cuotas:</span>
                          <strong>
                            {formatMoney(totalSeleccionado, monedaFactura)}
                          </strong>
                        </ResumenItem>
                      </>
                    )}
                    {!soloInteres && esMonedaExtranjera && cotizacionFactura && (
                      <ResumenItem $secondary>
                        <span>≈ en Guaraníes:</span>
                        <span>
                          Gs.{" "}
                          {convertToGs(
                            totalSeleccionado,
                            cotizacionFactura,
                          )?.toLocaleString("es-PY", {
                            maximumFractionDigits: 0,
                          })}
                        </span>
                      </ResumenItem>
                    )}
                  </CobroResumen>

                  {/* Monto a pagar editable */}
                  <CobroFieldSection>
                    <CobroFieldLabel>
                      <Icon icon="lucide:banknote" />
                      Monto a pagar
                    </CobroFieldLabel>
                    <MontoInputWrapper>
                      <MontoPrefix>{monedaFactura?.simbolo || "₲"}</MontoPrefix>
                      <MontoInput
                        type="text"
                        inputMode="numeric"
                        value={fmtInputNum(montoAPagar)}
                        onChange={(e) => {
                          const digits = cleanDigits(e.target.value);
                          const num = Number(digits) || 0;
                          if (digits === "" || num <= totalACobrarMaximo) {
                            setMontoAPagar(digits);
                          } else {
                            setMontoAPagar(
                              String(Math.round(totalACobrarMaximo)),
                            );
                          }
                        }}
                        placeholder="0"
                      />
                      {montoAPagar &&
                        Number(montoAPagar) !== montoSugerido && (
                          <MontoResetButton
                            onClick={() =>
                              setMontoAPagar(
                                String(Math.round(montoSugerido)),
                              )
                            }
                          >
                            <Icon icon="lucide:rotate-ccw" />
                          </MontoResetButton>
                        )}
                    </MontoInputWrapper>
                    {Number(montoAPagar) < totalSeleccionado &&
                      Number(montoAPagar) > 0 && (
                        <MontoHint $warning>
                          <Icon icon="lucide:info" />
                          Pago parcial — se distribuirá entre las cuotas más
                          antiguas
                        </MontoHint>
                      )}
                  </CobroFieldSection>

                  {/* Descuento: va sobre el capital, no hay en un cobro solo de interés */}
                  {!soloInteres && (puedeDescuentoLibre || descuentoAutorizado) && (
                  <CobroFieldSection>
                    <CobroFieldLabel>
                      <Icon icon="lucide:percent" />
                      Descuento
                      {/* Botón Aplicar/Quitar: siempre visible si tiene permiso libre;
                          si no, solo si hay descuento autorizado */}
                      {(puedeDescuentoLibre || descuentoAutorizado) && (
                        <DescuentoToggle
                          $active={descuentoTipo !== "none"}
                          onClick={() => {
                            if (descuentoTipo === "none") {
                              if (descuentoAutorizado) {
                                if (descuentoAutorizado.descuento_monto) {
                                  setDescuentoTipo("monto");
                                  setDescuentoValor(String(descuentoAutorizado.descuento_monto));
                                } else if (descuentoAutorizado.descuento_porcentaje) {
                                  setDescuentoTipo("porcentaje");
                                  setDescuentoValor(String(descuentoAutorizado.descuento_porcentaje));
                                } else {
                                  setDescuentoTipo("porcentaje");
                                }
                                if (descuentoAutorizado.motivo) setMotivoDescuento(descuentoAutorizado.motivo);
                              } else {
                                setDescuentoTipo("porcentaje");
                              }
                            } else {
                              setDescuentoTipo("none");
                              setDescuentoValor("");
                              setMotivoDescuento("");
                            }
                          }}
                        >
                          {descuentoTipo !== "none" ? "Quitar" : "Aplicar"}
                        </DescuentoToggle>
                      )}
                    </CobroFieldLabel>

                    {descuentoAutorizado && descuentoTipo === "none" && (
                      <DescuentoAutorizadoBadge>
                        <Icon icon="lucide:shield-check" />
                        Descuento autorizado:{" "}
                        {descuentoAutorizado.descuento_monto
                          ? `${formatMoney(descuentoAutorizado.descuento_monto, monedaFactura)}`
                          : `${descuentoAutorizado.descuento_porcentaje}%`}
                        {" — "}
                        <span>Presione "Aplicar" para usar</span>
                      </DescuentoAutorizadoBadge>
                    )}

                    {descuentoTipo !== "none" && (
                      <DescuentoControls>
                        {/* Selectores de tipo solo si puede descuento libre o no hay autorización fija */}
                        {puedeDescuentoLibre && (
                          <DescuentoTipoSelector>
                            <DescuentoTipoBtn
                              $active={descuentoTipo === "porcentaje"}
                              onClick={() => {
                                setDescuentoTipo("porcentaje");
                                setDescuentoValor("");
                              }}
                            >
                              %
                            </DescuentoTipoBtn>
                            <DescuentoTipoBtn
                              $active={descuentoTipo === "monto"}
                              onClick={() => {
                                setDescuentoTipo("monto");
                                setDescuentoValor("");
                              }}
                            >
                              {monedaFactura?.simbolo || "₲"}
                            </DescuentoTipoBtn>
                          </DescuentoTipoSelector>
                        )}
                        <DescuentoInput
                          type="text"
                          inputMode="numeric"
                          value={
                            descuentoTipo === "monto"
                              ? fmtInputNum(descuentoValor)
                              : descuentoValor
                          }
                          onChange={(e) => {
                            if (!puedeDescuentoLibre) return;
                            if (descuentoTipo === "monto") {
                              setDescuentoValor(cleanDigits(e.target.value));
                            } else {
                              // porcentaje: permitir solo números y punto
                              const val = e.target.value.replace(/[^0-9.]/g, "");
                              if (val === "" || Number(val) <= 100) setDescuentoValor(val);
                            }
                          }}
                          readOnly={!puedeDescuentoLibre}
                          placeholder={
                            descuentoTipo === "porcentaje" ? "Ej: 10" : "Ej: 50.000"
                          }
                        />
                        <DescuentoMotivoInput
                          type="text"
                          value={motivoDescuento}
                          onChange={(e) => puedeDescuentoLibre && setMotivoDescuento(e.target.value)}
                          readOnly={!puedeDescuentoLibre}
                          placeholder="Motivo del descuento..."
                        />
                        {!puedeDescuentoLibre && (
                          <DescuentoAutorizadoBadge style={{ marginTop: 4 }}>
                            <Icon icon="lucide:lock" />
                            Descuento autorizado por administrador
                          </DescuentoAutorizadoBadge>
                        )}
                      </DescuentoControls>
                    )}
                  </CobroFieldSection>
                  )}

                  {/* Preview de distribución */}
                  {distribucionPreview && (
                    <DistribucionSection>
                      <CobroFieldLabel>
                        <Icon icon="lucide:split" />
                        Distribución del pago
                      </CobroFieldLabel>
                      <DistribucionList>
                        {distribucionPreview.distribucion.map((d, idx) => (
                          <DistribucionItem
                            key={idx}
                            $parcial={d.es_pago_parcial}
                          >
                            <DistribucionCuota>
                              <span>Cuota {d.nro_cuota}</span>
                              <DistribucionFactura>
                                {d.factura_numero}
                              </DistribucionFactura>
                            </DistribucionCuota>
                            <DistribucionMontos>
                              {d.descuento_aplicado > 0 && (
                                <DistribucionDescuento>
                                  -{formatMoney(d.descuento_aplicado, monedaFactura)}
                                </DistribucionDescuento>
                              )}
                              {tieneModuloMora && d.mora_calculada > 0 && (() => {
                                const exo = getExoneracionPorCuota(d.factura_cuota_id, d.mora_calculada);
                                const moraNeta = Number(d.mora_calculada) - (exo?.monto ?? 0);
                                return (
                                  <>
                                    {exo && (
                                      <DistribucionMora style={{ color: "#10b981" }} title={exo.auth?.motivo || ""}>
                                        <Icon icon="lucide:eraser" />
                                        {" "}Mora exonerada {formatMoney(exo.monto, monedaFactura)}
                                      </DistribucionMora>
                                    )}
                                    {moraNeta > 0 && (
                                      <DistribucionMora>
                                        +{formatMoney(moraNeta, monedaFactura)} mora
                                      </DistribucionMora>
                                    )}
                                  </>
                                );
                              })()}
                              {Number(d.interes_manual || 0) > 0 && (
                                <DistribucionMora title="Interés cargado desde Cuentas por Cobrar">
                                  +{formatMoney(d.interes_manual, monedaFactura)} interés
                                </DistribucionMora>
                              )}
                              <DistribucionMontoPagado>
                                {formatMoney(d.monto_pagado, monedaFactura)}
                              </DistribucionMontoPagado>
                            </DistribucionMontos>
                            <DistribucionEstado $parcial={d.es_pago_parcial}>
                              {d.es_pago_parcial
                                ? `Parcial (resta ${formatMoney(d.saldo_restante, monedaFactura)})`
                                : "Completo"}
                            </DistribucionEstado>
                          </DistribucionItem>
                        ))}
                        {distribucionPreview.resumen.cuotas_sin_pago > 0 && (
                          <DistribucionItem $sinPago>
                            <span>
                              {distribucionPreview.resumen.cuotas_sin_pago}{" "}
                              cuota(s) sin cobertura
                            </span>
                          </DistribucionItem>
                        )}
                      </DistribucionList>

                      {distribucionPreview.resumen.descuento_monto_total > 0 && (
                        <DistribucionResumen>
                          <span>Descuento total:</span>
                          <DistribucionDescuento>
                            -{formatMoney(distribucionPreview.resumen.descuento_monto_total, monedaFactura)}
                          </DistribucionDescuento>
                        </DistribucionResumen>
                      )}
                      {tieneModuloMora && totalExoneradoMora > 0 && (
                        <DistribucionResumen>
                          <span>Mora exonerada:</span>
                          <DistribucionMora style={{ color: "#10b981" }}>
                            -{formatMoney(totalExoneradoMora, monedaFactura)}
                          </DistribucionMora>
                        </DistribucionResumen>
                      )}
                      {tieneModuloMora && (distribucionPreview.resumen.total_mora - totalExoneradoMora) > 0 && (
                        <DistribucionResumen>
                          <span>Mora a cobrar:</span>
                          <DistribucionMora>
                            +{formatMoney(distribucionPreview.resumen.total_mora - totalExoneradoMora, monedaFactura)}
                          </DistribucionMora>
                        </DistribucionResumen>
                      )}
                      {interesPendiente > 0 && (
                        <>
                          <DistribucionResumen>
                            <span>Capital imputado:</span>
                            <strong>{formatMoney(capitalImputado, monedaFactura)}</strong>
                          </DistribucionResumen>
                          <DistribucionResumen>
                            <span>Interés imputado:</span>
                            <DistribucionMora title="Se imputa después del capital, con lo que sobra de lo entregado">
                              {formatMoney(totalInteresManual, monedaFactura)}
                              <InteresPendienteHint>
                                de {formatMoney(interesPendiente, monedaFactura)}
                              </InteresPendienteHint>
                            </DistribucionMora>
                          </DistribucionResumen>
                          {interesRestante > 0 && (
                            <DistribucionResumen>
                              <InteresRestanteHint>
                                <Icon icon="lucide:info" />
                                Quedan {formatMoney(interesRestante, monedaFactura)} de interés
                                pendientes: pasan a la cuenta y se cobran en el próximo cobro.
                              </InteresRestanteHint>
                              <BtnInteresTodo
                                type="button"
                                onClick={() =>
                                  setMontoAPagar(String(Math.round(totalACobrarMaximo)))
                                }
                              >
                                Cobrar todo
                              </BtnInteresTodo>
                            </DistribucionResumen>
                          )}
                        </>
                      )}
                      <DistribucionResumen $total>
                        <span>Total a pagar:</span>
                        <TotalMonto>
                          {formatMoney(
                            distribucionPreview.resumen.total_pagado +
                              totalInteresManual +
                              (tieneModuloMora
                                ? (distribucionPreview.resumen.total_mora || 0) - totalExoneradoMora
                                : 0),
                            monedaFactura,
                          )}
                        </TotalMonto>
                      </DistribucionResumen>
                    </DistribucionSection>
                  )}

                  {loadingPreview && (
                    <LoadingContainer style={{ padding: "16px" }}>
                      <RingLoader color="#f88533" size={24} />
                    </LoadingContainer>
                  )}

                  <MedioPagoSection>
                    <MedioPagoLabel>Medio de Pago</MedioPagoLabel>
                    <MedioPagoOptions>
                      {mediosPago.map((mp) => (
                        <MedioPagoOption
                          key={mp.id}
                          $selected={selectedMedioPago === mp.id}
                          onClick={() => { setSelectedMedioPago(mp.id); setNumeroCheque(""); setBancoEmisor(""); }}
                        >
                          <Icon icon={getMedioPagoIcon(mp.descripcion)} />
                          {mp.descripcion}
                        </MedioPagoOption>
                      ))}
                    </MedioPagoOptions>
                    {esChequeSeleccionado && (
                      <ChequeFields>
                        <input
                          type="text"
                          placeholder="Nro. Cheque (8 caracteres)"
                          maxLength={8}
                          value={numeroCheque}
                          onChange={(e) => setNumeroCheque(e.target.value.replace(/[^a-zA-Z0-9]/g, ""))}
                        />
                        {/* datalist en vez de un Autocomplete de MUI: mantiene
                            el input nativo con el estilo de la pantalla y suma
                            las sugerencias del catálogo. Se puede escribir un
                            banco que no esté en la lista. */}
                        <input
                          type="text"
                          list="bancos-cobro"
                          placeholder="Banco emisor (elegí o escribí)"
                          maxLength={20}
                          value={bancoEmisor}
                          onChange={(e) => setBancoEmisor(e.target.value)}
                        />
                        <BancoDatalist id="bancos-cobro" />
                      </ChequeFields>
                    )}
                  </MedioPagoSection>

                  <CobroButton
                    onClick={handleProcesarCobro}
                    disabled={procesando}
                  >
                    {procesando ? (
                      <>
                        <RingLoader color="#ffffff" size={20} />
                        Procesando...
                      </>
                    ) : (
                      <>
                        <Icon icon="lucide:check-circle" />
                        Confirmar Cobro
                      </>
                    )}
                  </CobroButton>
                </>
              )}
          </CobroPanel>
        )}

        {/* Modal de detalle de factura */}
        {showFacturaDetail && (
          <ModalOverlay onClick={() => setShowFacturaDetail(null)}>
            <ModalContent onClick={(e) => e.stopPropagation()}>
              <ModalHeader>
                <ModalTitle>
                  <Icon icon="lucide:file-text" />
                  Factura {showFacturaDetail.numero_factura}
                </ModalTitle>
                <CloseButton onClick={() => setShowFacturaDetail(null)}>
                  <Icon icon="lucide:x" />
                </CloseButton>
              </ModalHeader>
              <ModalBody>
                <ReciboInfo>
                  <ReciboInfoRow>
                    <span>Fecha de emisión:</span>
                    <strong>{showFacturaDetail.fecha_emision}</strong>
                  </ReciboInfoRow>
                  <ReciboInfoRow>
                    <span>Moneda:</span>
                    <strong>{showFacturaDetail.moneda?.codigo || "PYG"}</strong>
                  </ReciboInfoRow>
                  {showFacturaDetail.dticam && (
                    <ReciboInfoRow>
                      <span>Cotización:</span>
                      <strong>
                        Gs.{" "}
                        {Number(showFacturaDetail.dticam).toLocaleString(
                          "es-PY",
                        )}
                      </strong>
                    </ReciboInfoRow>
                  )}
                  <ReciboInfoRow>
                    <span>Total factura:</span>
                    <strong>
                      {formatMoney(
                        showFacturaDetail.total_factura,
                        showFacturaDetail.moneda,
                      )}
                    </strong>
                  </ReciboInfoRow>
                  <ReciboInfoRow>
                    <span>Saldo pendiente:</span>
                    <SaldoPendiente>
                      {formatMoney(
                        showFacturaDetail.saldo_pendiente,
                        showFacturaDetail.moneda,
                      )}
                    </SaldoPendiente>
                  </ReciboInfoRow>
                </ReciboInfo>

                {/* Política de cobranza acordada */}
                {(() => {
                  const p = showFacturaDetail.politica_cobranza;
                  if (!p) return null;
                  const {
                    intervalo_dias,
                    dia_fijo_pago_1,
                    dia_fijo_pago_2,
                    dia_cobro_semana,
                    dias_gracia_override,
                  } = p;
                  if (
                    intervalo_dias == null &&
                    dia_fijo_pago_1 == null &&
                    dia_fijo_pago_2 == null &&
                    dia_cobro_semana == null &&
                    dias_gracia_override == null
                  ) {
                    return null;
                  }
                  const diasSemana = ["", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado", "Domingo"];
                  const frecuenciaLabel =
                    intervalo_dias === 7 ? "Semanal" :
                    intervalo_dias === 15 ? "Quincenal" :
                    intervalo_dias === 30 ? "Mensual" :
                    intervalo_dias ? `Cada ${intervalo_dias} días` : "—";
                  const diaLabel = dia_fijo_pago_1
                    ? dia_fijo_pago_2
                      ? `Días ${dia_fijo_pago_1} y ${dia_fijo_pago_2} de cada mes`
                      : `Día ${dia_fijo_pago_1} de cada mes`
                    : dia_cobro_semana
                      ? `${diasSemana[dia_cobro_semana]} de cada semana`
                      : null;
                  return (
                    <DetalleSection>
                      <DetalleTitulo>Política de cobranza</DetalleTitulo>
                      <ReciboInfo>
                        <ReciboInfoRow>
                          <span>Frecuencia:</span>
                          <strong>{frecuenciaLabel}</strong>
                        </ReciboInfoRow>
                        {diaLabel && (
                          <ReciboInfoRow>
                            <span>Vencimientos:</span>
                            <strong>{diaLabel}</strong>
                          </ReciboInfoRow>
                        )}
                        {dias_gracia_override != null && (
                          <ReciboInfoRow>
                            <span>Gracia acordada:</span>
                            <strong style={{ color: "var(--pos-amber, #f59e0b)" }}>
                              {dias_gracia_override} días
                            </strong>
                          </ReciboInfoRow>
                        )}
                      </ReciboInfo>
                    </DetalleSection>
                  );
                })()}

                <DetalleSection>
                  <DetalleTitulo>Último pago</DetalleTitulo>
                  {loadingUltimoPago ? (
                    <ReciboInfoRow>
                      <span style={{ opacity: 0.6 }}>Cargando…</span>
                    </ReciboInfoRow>
                  ) : !ultimoPago ? (
                    <ReciboInfoRow>
                      <span style={{ opacity: 0.6 }}>Sin pagos registrados aún</span>
                    </ReciboInfoRow>
                  ) : (
                    <>
                      <ReciboInfo>
                        <ReciboInfoRow>
                          <span>Recibo:</span>
                          <strong>{ultimoPago.numero_recibo}</strong>
                        </ReciboInfoRow>
                        <ReciboInfoRow>
                          <span>Fecha:</span>
                          <strong>{fmtFechaCalendario(toFechaCalendarioISO(ultimoPago.fecha_emision))}</strong>
                        </ReciboInfoRow>
                        <ReciboInfoRow>
                          <span>Monto aplicado a esta factura:</span>
                          <strong style={{ color: "var(--pos-green, #22c55e)" }}>
                            {fmtMoneda(
                              Number(ultimoPago.monto_aplicado_factura || 0),
                              ultimoPago.moneda_codigo || showFacturaDetail.moneda?.codigo,
                            )}
                          </strong>
                        </ReciboInfoRow>
                        <ReciboInfoRow>
                          <span>Total del recibo:</span>
                          <strong>
                            {fmtMoneda(
                              Number(ultimoPago.monto_total || 0),
                              ultimoPago.moneda_codigo || showFacturaDetail.moneda?.codigo,
                            )}
                          </strong>
                        </ReciboInfoRow>
                        {ultimoPago.cobrador_nombre && (
                          <ReciboInfoRow>
                            <span>Cobrador:</span>
                            <strong>{ultimoPago.cobrador_nombre}</strong>
                          </ReciboInfoRow>
                        )}
                        {(ultimoPago.usuario_nombres || ultimoPago.usuario_apellidos || ultimoPago.usuario_username) && (
                          <ReciboInfoRow>
                            <span>Registrado por:</span>
                            <strong>
                              {[ultimoPago.usuario_nombres, ultimoPago.usuario_apellidos]
                                .filter(Boolean).join(" ") || ultimoPago.usuario_username}
                            </strong>
                          </ReciboInfoRow>
                        )}
                        {ultimoPago.observacion && (
                          <ReciboInfoRow>
                            <span>Observación:</span>
                            <strong style={{ textAlign: "right", maxWidth: "60%" }}>
                              {ultimoPago.observacion}
                            </strong>
                          </ReciboInfoRow>
                        )}
                      </ReciboInfo>
                      {ultimoPago.medios_pago?.length > 0 && (
                        <DetalleList style={{ marginTop: 8 }}>
                          {ultimoPago.medios_pago.map((mp, idx) => (
                            <DetalleItem key={idx}>
                              <DetalleInfo>
                                <span>
                                  <Icon icon={getMedioPagoIcon(mp.medio)} style={{ marginRight: 6, verticalAlign: "middle" }} />
                                  {mp.medio || "—"}
                                </span>
                                {(mp.cheque_numero || mp.cheque_banco || mp.referencia || mp.cuenta_tesoreria_nombre) && (
                                  <DetalleMedioPago>
                                    {[
                                      mp.cheque_numero && `Cheque N° ${mp.cheque_numero}`,
                                      mp.cheque_banco,
                                      mp.referencia && `Ref: ${mp.referencia}`,
                                      mp.cuenta_tesoreria_nombre,
                                    ].filter(Boolean).join(" · ")}
                                  </DetalleMedioPago>
                                )}
                              </DetalleInfo>
                              <DetalleMonto>
                                {fmtMoneda(
                                  Number(mp.monto || 0),
                                  mp.moneda_codigo || ultimoPago.moneda_codigo || showFacturaDetail.moneda?.codigo,
                                )}
                              </DetalleMonto>
                            </DetalleItem>
                          ))}
                        </DetalleList>
                      )}
                    </>
                  )}
                </DetalleSection>

                {showFacturaDetail.items?.length > 0 && (
                  <DetalleSection>
                    <DetalleTitulo>Items de la factura</DetalleTitulo>
                    <DetalleList>
                      {showFacturaDetail.items.map((item, idx) => (
                        <DetalleItem key={item.id || idx}>
                          <DetalleInfo>
                            <span>{item.ddesproser}</span>
                            <DetalleMedioPago>
                              Cant: {item.dcantproser} x{" "}
                              {formatMoney(
                                item.duniproser,
                                showFacturaDetail.moneda,
                              )}
                            </DetalleMedioPago>
                          </DetalleInfo>
                          <DetalleMonto>
                            {formatMoney(
                              item.dtotbruopeitem,
                              showFacturaDetail.moneda,
                            )}
                          </DetalleMonto>
                        </DetalleItem>
                      ))}
                    </DetalleList>
                  </DetalleSection>
                )}
              </ModalBody>
            </ModalContent>
          </ModalOverlay>
        )}

        {pdfPreview && (
          <ModalOverlay onClick={handleClosePdfPreview}>
            <PdfPreviewModalContent onClick={(e) => e.stopPropagation()}>
              <ModalHeader>
                <ModalTitle>
                  <Icon
                    icon={
                      pdfPreview.formato === "ticket"
                        ? "lucide:receipt"
                        : "lucide:file-text"
                    }
                  />
                  Recibo - {pdfPreview.formato === "ticket" ? "Ticket" : "A4"}
                </ModalTitle>
                <PdfPreviewActions>
                  <SmallActionBtn
                    title="Imprimir"
                    $accent
                    onClick={() => {
                      const link = document.createElement("a");
                      link.href = pdfPreview.url;
                      link.target = "_blank";
                      link.click();
                    }}
                  >
                    <Icon icon="lucide:external-link" />
                  </SmallActionBtn>
                  <CloseButton onClick={handleClosePdfPreview}>
                    <Icon icon="lucide:x" />
                  </CloseButton>
                </PdfPreviewActions>
              </ModalHeader>
              <PdfIframeContainer>
                <iframe
                  src={pdfPreview.url}
                  title="Recibo PDF"
                  style={{
                    width: "100%",
                    height: "100%",
                    border: "none",
                  }}
                />
              </PdfIframeContainer>
            </PdfPreviewModalContent>
          </ModalOverlay>
        )}

        {/* Modal Promesa de Pago — componente compartido */}
        <PromesaPagoFormModal
          open={!!promesaDialog}
          onClose={() => setPromesaDialog(null)}
          onSuccess={() => setPromesaDialog(null)}
          cliente={selectedCliente}
          cuotaFija={
            promesaDialog
              ? { cuota: { ...promesaDialog.cuota, factura_cab_id: selectedFactura?.id } }
              : null
          }
        />

        {showConfirmDialog && (
          <ModalOverlay
            onClick={() =>
              !procesando && !cobroExitoso && handleCerrarConfirmDialog()
            }
          >
            <ConfirmModalContent onClick={(e) => e.stopPropagation()}>
              {!cobroExitoso ? (
                <>
                  <ModalHeader>
                    <ModalTitle>
                      <Icon icon="lucide:clipboard-check" />
                      Confirmar Cobro
                    </ModalTitle>
                    <CloseButton
                      onClick={() => !procesando && handleCerrarConfirmDialog()}
                    >
                      <Icon icon="lucide:x" />
                    </CloseButton>
                  </ModalHeader>
                  <ConfirmModalBody>
                    <ConfirmSection>
                      <ConfirmSectionTitle>
                        <Icon icon="lucide:user" />
                        Cliente
                      </ConfirmSectionTitle>
                      <ConfirmClienteInfo>
                        <strong>
                          {selectedCliente?.personas?.razon_social}
                        </strong>
                        <span>
                          {selectedCliente?.personas?.ruc ||
                            selectedCliente?.personas?.documento}
                        </span>
                      </ConfirmClienteInfo>
                    </ConfirmSection>

                    <ConfirmSection>
                      <ConfirmSectionTitle>
                        <Icon icon="lucide:list" />
                        {soloInteres
                          ? "Interés de la cuenta (capital ya saldado)"
                          : `Cuotas a cobrar (${selectedCuotas.length})`}
                      </ConfirmSectionTitle>
                      <ConfirmCuotasList>
                        {(console.log(
                          "distribucionPreview",
                          distribucionPreview,
                        ),
                        distribucionPreview?.distribucion ||
                          selectedCuotas).map((item, idx) => {
                          const cuota = distribucionPreview
                            ? selectedCuotas.find(
                                (c) => c.id === item.factura_cuota_id,
                              ) || item
                            : item;
                          const montoPago = distribucionPreview
                            ? item.monto_pagado
                            : Number(cuota.saldo_pendiente || cuota.dmoncuota);
                          const descuento = distribucionPreview
                            ? item.descuento_aplicado
                            : 0;
                          return (
                            <ConfirmCuotaItem key={cuota.id || idx}>
                              <ConfirmCuotaLeft>
                                <span>
                                  Cuota{" "}
                                  {cuota.nro_cuota ||
                                    cuota.factura_cuotas?.nro_cuota ||
                                    idx + 1}
                                </span>
                                {distribucionPreview &&
                                  item.es_pago_parcial && (
                                    <ReciboBadge $color="#f59e0b">
                                      Parcial
                                    </ReciboBadge>
                                  )}
                              </ConfirmCuotaLeft>
                              <ConfirmCuotaRight>
                                {descuento > 0 && (
                                  <ConfirmCuotaDescuento>
                                    -{formatMoney(descuento, monedaFactura)}
                                  </ConfirmCuotaDescuento>
                                )}
                                <strong>
                                  {formatMoney(montoPago, monedaFactura)}
                                </strong>
                              </ConfirmCuotaRight>
                            </ConfirmCuotaItem>
                          );
                        })}
                      </ConfirmCuotasList>
                    </ConfirmSection>

                    <ConfirmSection>
                      <ConfirmSectionTitle>
                        <Icon icon="lucide:credit-card" />
                        Detalle del pago
                      </ConfirmSectionTitle>
                      <ConfirmResumenList>
                        <ConfirmResumenRow>
                          <span>Medio de pago:</span>
                          <strong>
                            {mediosPago.find((m) => m.id === selectedMedioPago)
                              ?.descripcion || "—"}
                          </strong>
                        </ConfirmResumenRow>
                        {distribucionPreview?.resumen.descuento_monto_total > 0 && (
                          <ConfirmResumenRow>
                            <span>Descuento:</span>
                            <ConfirmCuotaDescuento>
                              -{formatMoney(distribucionPreview.resumen.descuento_monto_total, monedaFactura)}
                              {descuentoTipo === "porcentaje" && ` (${descuentoValor}%)`}
                            </ConfirmCuotaDescuento>
                          </ConfirmResumenRow>
                        )}
                        {tieneModuloMora && totalExoneradoMora > 0 && (
                          <ConfirmResumenRow>
                            <span>Mora exonerada:</span>
                            <DistribucionMora style={{ color: "#10b981" }}>
                              -{formatMoney(totalExoneradoMora, monedaFactura)}
                            </DistribucionMora>
                          </ConfirmResumenRow>
                        )}
                        {tieneModuloMora && (distribucionPreview?.resumen.total_mora - totalExoneradoMora) > 0 && (
                          <ConfirmResumenRow>
                            <span>Mora a cobrar:</span>
                            <DistribucionMora>
                              +{formatMoney(distribucionPreview.resumen.total_mora - totalExoneradoMora, monedaFactura)}
                            </DistribucionMora>
                          </ConfirmResumenRow>
                        )}
                        {totalInteresManual > 0 && (
                          <ConfirmResumenRow>
                            <span>Interés imputado:</span>
                            <DistribucionMora>
                              {formatMoney(totalInteresManual, monedaFactura)}
                            </DistribucionMora>
                          </ConfirmResumenRow>
                        )}
                        {interesRestante > 0 && (
                          <ConfirmResumenRow>
                            <span>Interés que queda pendiente:</span>
                            <DistribucionMora style={{ color: "#f59e0b" }}>
                              {formatMoney(interesRestante, monedaFactura)}
                            </DistribucionMora>
                          </ConfirmResumenRow>
                        )}
                        <ConfirmResumenRow $total>
                          <span>Total a cobrar:</span>
                          <ConfirmTotalMonto>
                            {formatMoney(
                              distribucionPreview
                                ? distribucionPreview.resumen.total_pagado + (tieneModuloMora ? ((distribucionPreview.resumen.total_mora || 0) - totalExoneradoMora) : 0) + totalInteresManual
                                : Number(montoAPagar),
                              monedaFactura,
                            )}
                          </ConfirmTotalMonto>
                        </ConfirmResumenRow>
                      </ConfirmResumenList>
                    </ConfirmSection>

                    <ConfirmSection>
                      <ConfirmSectionTitle>
                        <Icon icon="lucide:banknote" />
                        Monto entregado por el cliente
                      </ConfirmSectionTitle>
                      <ConfirmMontoEntregadoRow>
                        <ConfirmMontoInput
                          type="text"
                          inputMode="numeric"
                          placeholder="Ingrese monto entregado"
                          value={fmtInputNum(montoEntregado)}
                          onChange={(e) => setMontoEntregado(cleanDigits(e.target.value))}
                          autoFocus
                        />
                      </ConfirmMontoEntregadoRow>
                      {montoEntregado &&
                        (() => {
                          const totalCobrar = distribucionPreview
                            ? distribucionPreview.resumen.total_pagado + (tieneModuloMora ? ((distribucionPreview.resumen.total_mora || 0) - totalExoneradoMora) : 0) + totalInteresManual
                            : Number(montoAPagar);
                          const entregado = Number(montoEntregado);
                          const vuelto = entregado - totalCobrar;
                          if (entregado < totalCobrar) {
                            return (
                              <ConfirmVueltoBox $warning>
                                <Icon icon="lucide:alert-circle" />
                                <span>
                                  Monto insuficiente (faltan{" "}
                                  {formatMoney(Math.abs(vuelto), monedaFactura)}
                                  )
                                </span>
                              </ConfirmVueltoBox>
                            );
                          }
                          return (
                            <ConfirmVueltoBox>
                              <Icon icon="lucide:arrow-down-left" />
                              <span>
                                Vuelto:{" "}
                                <strong>
                                  {formatMoney(vuelto, monedaFactura)}
                                </strong>
                              </span>
                            </ConfirmVueltoBox>
                          );
                        })()}
                    </ConfirmSection>

                    <ConfirmSection>
                      <ConfirmSectionTitle>
                        <Icon icon="lucide:calendar" />
                        Fecha del cobro
                      </ConfirmSectionTitle>
                      <ConfirmMontoEntregadoRow>
                        <ConfirmMontoInput
                          type="date"
                          value={fechaRegistroManual}
                          onChange={(e) => setFechaRegistroManual(e.target.value)}
                          style={{ cursor: "pointer" }}
                        />
                      </ConfirmMontoEntregadoRow>
                    </ConfirmSection>

                    {puedeAsignarCobrador && (
                      <ConfirmSection>
                        <ConfirmSectionTitle>
                          <Icon icon="lucide:user-check" />
                          Cobrador
                        </ConfirmSectionTitle>
                        <ConfirmMontoEntregadoRow>
                          {(() => {
                            const opciones = [...cobradores];
                            if (
                              cobradorManual &&
                              !opciones.some((c) => c.id === cobradorManual)
                            ) {
                              if (miCobrador?.id === cobradorManual) {
                                opciones.unshift(miCobrador);
                              } else {
                                opciones.unshift({
                                  id: cobradorManual,
                                  nombre: "Cobrador asignado a la factura",
                                });
                              }
                            }
                            const placeholder = miCobrador?.id
                              ? "Vinculado al usuario"
                              : selectedFactura?.cobrador_id
                              ? "Cobrador de la factura"
                              : "Sin asignar";
                            return (
                              <SearchableSelect
                                options={opciones}
                                value={cobradorManual || null}
                                onChange={(id) => setCobradorManual(id || "")}
                                placeholder={placeholder}
                                getOptionLabel={(c) =>
                                  c?.personas?.razon_social ||
                                  `${c?.nombre ?? ""} ${c?.apellido ?? ""}`.trim() ||
                                  c?.codigo ||
                                  ""
                                }
                              />
                            );
                          })()}
                        </ConfirmMontoEntregadoRow>
                      </ConfirmSection>
                    )}

                    <ConfirmActions>
                      <ConfirmCancelButton
                        onClick={() =>
                          !procesando && handleCerrarConfirmDialog()
                        }
                        disabled={procesando}
                      >
                        Cancelar
                      </ConfirmCancelButton>
                      <ConfirmCancelButton
                        onClick={() => setBancardModalOpen(true)}
                        disabled={procesando}
                        style={{ background: "#1565c022", color: "#1565c0", border: "1px solid #1565c044" }}
                        title="Cobrar con tarjeta Bancard"
                      >
                        <Icon icon="mdi:credit-card-outline" />
                        Bancard
                      </ConfirmCancelButton>
                      <ConfirmOkButton
                        onClick={handleConfirmarCobroFinal}
                        disabled={procesando}
                      >
                        {procesando ? (
                          <>
                            <RingLoader color="#ffffff" size={18} />
                            Procesando...
                          </>
                        ) : (
                          <>
                            <Icon icon="lucide:check" />
                            Confirmar y Cobrar
                          </>
                        )}
                      </ConfirmOkButton>
                    </ConfirmActions>
                  </ConfirmModalBody>
                </>
              ) : (
                <>
                  <ConfirmModalBody>
                    <ConfirmSuccessContainer>
                      <ConfirmSuccessIcon>
                        <Icon icon="lucide:check-circle-2" />
                      </ConfirmSuccessIcon>
                      <ConfirmSuccessTitle>
                        Cobro registrado exitosamente
                      </ConfirmSuccessTitle>
                      <ConfirmSuccessRecibo>
                        Recibo #{cobroExitoso.numero_recibo}
                      </ConfirmSuccessRecibo>

                      <ConfirmResumenList>
                        <ConfirmResumenRow>
                          <span>Total cobrado:</span>
                          <strong>
                            {formatMoney(
                              cobroExitoso.monto_total,
                              monedaFactura,
                            )}
                          </strong>
                        </ConfirmResumenRow>
                        {cobroExitoso.monto_entregado > 0 && (
                          <ConfirmResumenRow>
                            <span>Monto entregado:</span>
                            <strong>
                              {formatMoney(
                                cobroExitoso.monto_entregado,
                                monedaFactura,
                              )}
                            </strong>
                          </ConfirmResumenRow>
                        )}
                        {cobroExitoso.vuelto > 0 && (
                          <ConfirmResumenRow $total>
                            <span>Vuelto a entregar:</span>
                            <ConfirmVueltoGrande>
                              {formatMoney(cobroExitoso.vuelto, monedaFactura)}
                            </ConfirmVueltoGrande>
                          </ConfirmResumenRow>
                        )}
                      </ConfirmResumenList>

                      {printingAfterCobro && (
                        <MontoHint>
                          <RingLoader color="#3b82f6" size={14} />
                          Enviando ticket a la impresora...
                        </MontoHint>
                      )}

                      <SuccessActionsRow>
                        {cobroExitoso.id && (
                          <>
                            <SuccessActionBtn
                              onClick={() =>
                                handlePreviewRecibo(cobroExitoso.id, "a4")
                              }
                              disabled={!!loadingPdf}
                            >
                              <Icon icon="lucide:file-text" />
                              Ver A4
                            </SuccessActionBtn>
                            <SuccessActionBtn
                              onClick={() =>
                                handlePreviewRecibo(cobroExitoso.id, "ticket")
                              }
                              disabled={!!loadingPdf}
                            >
                              <Icon icon="lucide:receipt" />
                              Ver Ticket
                            </SuccessActionBtn>
                            <SuccessActionBtn
                              $accent
                              onClick={() => handlePrintTicket(cobroExitoso.id)}
                              disabled={!!loadingPdf}
                            >
                              {loadingPdf === cobroExitoso.id ? (
                                <RingLoader color="#f88533" size={14} />
                              ) : (
                                <Icon icon="lucide:printer" />
                              )}
                              Imprimir
                            </SuccessActionBtn>
                          </>
                        )}
                      </SuccessActionsRow>

                      <ConfirmOkButton
                        onClick={handleCerrarConfirmDialog}
                        style={{ marginTop: "8px", width: "100%" }}
                      >
                        <Icon icon="lucide:check" />
                        Cerrar
                      </ConfirmOkButton>
                    </ConfirmSuccessContainer>
                  </ConfirmModalBody>
                </>
              )}
            </ConfirmModalContent>
          </ModalOverlay>
        )}
      </MainContent>

      {bancardModalOpen && distribucionPreview && (
        <BancardPagoModal
          open={bancardModalOpen}
          onClose={() => setBancardModalOpen(false)}
          onSuccess={() => {
            setBancardModalOpen(false);
            toast.success("Pago Bancard recibido. Registra el cobro manualmente o espera la confirmación del webhook.");
          }}
          monto={Math.round(
            distribucionPreview.resumen.total_pagado +
              Math.max(0, (distribucionPreview.resumen.total_mora || 0) - totalExoneradoMora)
          )}
          moneda="PYG"
          descripcion={`Cobro factura ${selectedFactura?.numero_factura ?? ""}`}
          origenModulo="cobro"
          origenId={selectedFactura?.id}
          clienteId={selectedCliente?.id}
        />
      )}
    </Container>
  );
}

// Styled Components
const Container = styled.div`
  display: flex;
  flex-direction: column;
  min-height: 100%;
  padding: 20px;
  gap: 20px;
`;

const Header = styled.div`
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 16px;
`;

const HeaderTitle = styled.h1`
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 1.5rem;
  font-weight: 700;
  color: ${({ theme }) => theme.text};
  margin: 0;

  svg {
    width: 28px;
    height: 28px;
    color: #f88533;
  }
`;

const CajaInfo = styled.div`
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  background: linear-gradient(135deg, #22c55e15 0%, #16a34a15 100%);
  border: 1px solid #22c55e40;
  border-radius: 8px;
  font-size: 0.875rem;
  color: #22c55e;

  svg {
    width: 16px;
    height: 16px;
  }
`;

const SucursalSelector = styled.div`
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  background: linear-gradient(135deg, #3b82f615 0%, #2563eb15 100%);
  border: 1px solid #3b82f640;
  border-radius: 8px;
  font-size: 0.875rem;
  color: #93c5fd;
  svg { width: 16px; height: 16px; }
`;

const MainContent = styled.div`
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;

  @media ${Device.tablet} {
    grid-template-columns: repeat(2, 1fr);
  }

  @media ${Device.desktop} {
    grid-template-columns: repeat(3, 1fr);
  }
`;

const SearchPanel = styled.div`
  background: ${({ theme }) => theme.body};
  border: 1px solid ${({ theme }) => theme.bg4};
  border-radius: 16px;
  overflow: visible;
  position: relative;
  z-index: 10;
  isolation: auto;

  @media ${Device.tablet} {
    grid-column: span 2;
  }

  @media ${Device.desktop} {
    grid-column: span 1;
  }
`;

const PanelHeader = styled.div`
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 20px;
  border-bottom: 1px solid ${({ theme }) => theme.bg4};
`;

const PanelTitle = styled.h2`
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 1rem;
  font-weight: 600;
  color: ${({ theme }) => theme.text};
  margin: 0;
  flex: 1;

  svg {
    width: 20px;
    height: 20px;
    color: #f88533;
  }
`;

const ClearButton = styled.button`
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  background: ${({ theme }) => theme.bg3};
  border: none;
  border-radius: 6px;
  cursor: pointer;
  color: ${({ theme }) => theme.text};
  transition: all 0.2s;

  &:hover {
    background: #ef444420;
    color: #ef4444;
  }
`;

const SearchContainer = styled.div`
  padding: 16px 20px;
  padding-bottom: 8px;
`;

const SearchInput = styled.input`
  width: 100%;
  padding: 12px 16px;
  background: ${({ theme }) => theme.bg3};
  border: 2px solid transparent;
  border-radius: 10px;
  font-size: 0.95rem;
  color: ${({ theme }) => theme.text};
  transition: all 0.2s;

  &:focus {
    outline: none;
    border-color: #f88533;
    background: ${({ theme }) => theme.body};
  }

  &::placeholder {
    color: ${({ theme }) => theme.text}60;
  }
`;

const SearchResultsList = styled.div`
  margin-top: 8px;
  background: ${({ theme }) => theme.bg3};
  border: 1px solid ${({ theme }) => theme.bg4};
  border-radius: 10px;
  max-height: 300px;
  overflow-y: auto;
`;

const SearchResultItem = styled.div`
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  cursor: pointer;
  transition: background 0.2s;

  &:hover {
    background: ${({ theme }) => theme.bg3};
  }

  &:not(:last-child) {
    border-bottom: 1px solid ${({ theme }) => theme.bg4};
  }
`;

const ClienteAvatar = styled.div`
  width: ${({ $large }) => ($large ? "48px" : "36px")};
  height: ${({ $large }) => ($large ? "48px" : "36px")};
  background: linear-gradient(135deg, #f88533 0%, #ff6b6b 100%);
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: 700;
  font-size: ${({ $large }) => ($large ? "1.2rem" : "0.9rem")};
`;

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

const ClienteNombre = styled.div`
  font-weight: 600;
  color: ${({ theme }) => theme.text};
`;

const ClienteRuc = styled.div`
  font-size: 0.8rem;
  color: ${({ theme }) => theme.text}80;
`;

const SelectedClienteCard = styled.div`
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 20px;
`;

const PromesasBanner = styled.div`
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px 14px;
  background: ${({ theme }) => theme.bg2};
  border: 1px solid ${({ $alerta }) => ($alerta ? "#ef444455" : "#f59e0b55")};
  border-left: 3px solid ${({ $alerta }) => ($alerta ? "#ef4444" : "#f59e0b")};
  border-radius: 10px;

  @media ${Device.tablet} {
    grid-column: span 2;
  }
`;

const PromesasBannerHeader = styled.div`
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
`;

const PromesasBannerHeaderLeft = styled.div`
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
`;

const PromesasBannerIcon = styled.div`
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: ${({ $alerta }) => ($alerta ? "#ef444422" : "#f59e0b22")};
  color: ${({ $alerta }) => ($alerta ? "#ef4444" : "#f59e0b")};
  flex-shrink: 0;
`;

const PromesasBannerStats = styled.div`
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
`;

const PromesasBannerStatLabel = styled.div`
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: ${({ theme }) => theme.textSecondary || theme.text};
  opacity: 0.7;
`;

const PromesasBannerStatValue = styled.div`
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 16px;
  font-weight: 700;
  color: ${({ theme }) => theme.text};
  line-height: 1.1;
`;

const PromesasBannerVencidasBadge = styled.span`
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 2px 6px;
  border-radius: 999px;
  background: #ef444422;
  color: #ef4444;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
`;

const PromesasBannerTotals = styled.div`
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  font-size: 12px;
  font-weight: 500;
  color: ${({ theme }) => theme.textSecondary || theme.text};
  opacity: 0.85;
  margin-top: 2px;
`;

const PromesasBannerLink = styled(Link)`
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px 10px;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 600;
  color: ${({ theme }) => theme.primary || "#3b82f6"};
  text-decoration: none;
  transition: background 0.15s;
  &:hover {
    background: ${({ theme }) => theme.bgAlpha || "rgba(255,255,255,0.05)"};
  }
`;

const PromesasBannerList = styled.div`
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
`;

const PromesasBannerChip = styled.span`
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 9px;
  font-size: 11.5px;
  font-weight: 500;
  border-radius: 6px;
  background: ${({ $vencida }) => ($vencida ? "#ef444415" : "transparent")};
  color: ${({ theme, $vencida }) => ($vencida ? "#ef4444" : theme.text)};
  border: 1px solid ${({ theme, $vencida }) =>
    $vencida ? "#ef444455" : theme.borderColor || "rgba(255,255,255,0.1)"};
`;

const PromesasBannerChipMonto = styled.span`
  font-weight: 700;
  font-variant-numeric: tabular-nums;
`;

const PromesasBannerMore = styled.span`
  display: inline-flex;
  align-items: center;
  font-size: 11.5px;
  font-weight: 500;
  color: ${({ theme }) => theme.textSecondary || theme.text};
  opacity: 0.7;
  padding: 4px 6px;
`;

const FacturasPanel = styled.div`
  background: ${({ theme }) => theme.body};
  border: 1px solid ${({ theme }) => theme.bg4};
  border-radius: 16px;
  overflow: hidden;

  @media ${Device.tablet} {
    grid-column: span 2;
  }
`;

const LoadingContainer = styled.div`
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 40px;
`;

const EmptyState = styled.div`
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 40px;
  color: ${({ theme }) => theme.text}60;

  svg {
    width: 48px;
    height: 48px;
  }
`;

const FacturasList = styled.div`
  display: grid;
  gap: 16px;
  padding: 16px;

  @media ${Device.tablet} {
    grid-template-columns: repeat(2, 1fr);
  }
`;

const FacturaCard = styled.div`
  background: ${({ theme }) => theme.bg3};
  border-radius: 12px;
  overflow: hidden;
`;

const FacturaHeader = styled.div`
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  background: ${({ theme }) => theme.bg4}40;
`;

const FacturaNumero = styled.div`
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  color: ${({ theme }) => theme.text};

  svg {
    color: #f88533;
  }
`;

const MonedaBadge = styled.span`
  padding: 4px 8px;
  border-radius: 6px;
  font-size: 0.75rem;
  font-weight: 600;
  background: ${({ $extranjera }) => ($extranjera ? "#3b82f615" : "#22c55e15")};
  color: ${({ $extranjera }) => ($extranjera ? "#3b82f6" : "#22c55e")};
`;

const FacturaBody = styled.div`
  padding: 16px;
`;

const FacturaInfo = styled.div`
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 12px;
`;

const InfoRow = styled.div`
  display: flex;
  justify-content: space-between;
  font-size: 0.85rem;
  color: ${({ $secondary }) => ($secondary ? "#6b7280" : "inherit")};

  span {
    color: ${({ theme, $highlight }) =>
      $highlight ? theme.text : `${theme.text}80`};
  }

  strong {
    color: ${({ theme }) => theme.text};
  }
`;

const SaldoPendiente = styled.strong`
  color: #f88533 !important;
`;

const CuotasProgress = styled.div`
  margin-top: 8px;
`;

const ProgressLabel = styled.div`
  font-size: 0.75rem;
  color: ${({ theme }) => theme.text}80;
  margin-bottom: 4px;
`;

const ProgressBar = styled.div`
  height: 6px;
  background: ${({ theme }) => theme.bg4};
  border-radius: 3px;
  overflow: hidden;
`;

const ProgressFill = styled.div`
  height: 100%;
  background: linear-gradient(90deg, #22c55e 0%, #16a34a 100%);
  border-radius: 3px;
  transition: width 0.3s;
`;

const FacturaActions = styled.div`
  display: flex;
  gap: 8px;
  padding: 12px 16px;
  border-top: 1px solid ${({ theme }) => theme.bg4};
`;

const ActionButton = styled.button`
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 10px;
  background: ${({ $primary }) => ($primary ? "#f88533" : "transparent")};
  border: 1px solid ${({ $primary }) => ($primary ? "#f88533" : "#6b7280")};
  border-radius: 8px;
  font-size: 0.85rem;
  font-weight: 500;
  color: ${({ $primary }) => ($primary ? "white" : "#6b7280")};
  cursor: pointer;
  transition: all 0.2s;

  &:hover {
    background: ${({ $primary }) => ($primary ? "#e67422" : "#6b728010")};
  }
`;

const CuotasPanel = styled.div`
  background: ${({ theme }) => theme.body};
  border: 1px solid ${({ theme }) => theme.bg4};
  border-radius: 16px;
  overflow: hidden;

  @media ${Device.tablet} {
    grid-column: span 2;
  }
`;

const BackButton = styled.button`
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  background: ${({ theme }) => theme.bg3};
  border: none;
  border-radius: 8px;
  cursor: pointer;
  color: ${({ theme }) => theme.text};
  transition: all 0.2s;

  &:hover {
    background: ${({ theme }) => theme.bg4};
  }
`;

const SelectAllButton = styled.button`
  padding: 6px 12px;
  background: transparent;
  border: 1px solid #f88533;
  border-radius: 6px;
  font-size: 0.8rem;
  color: #f88533;
  cursor: pointer;
  transition: all 0.2s;

  &:hover {
    background: #f8853310;
  }
`;

const CuotasList = styled.div`
  max-height: 400px;
  overflow-y: auto;
`;

const CuotaItem = styled.div`
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 20px;
  cursor: pointer;
  background: ${({ $selected }) => ($selected ? "#f8853310" : "transparent")};
  border-left: 3px solid
    ${({ $selected }) => ($selected ? "#f88533" : "transparent")};
  transition: all 0.2s;

  &:hover {
    background: ${({ $selected, theme }) =>
      $selected ? "#f8853315" : theme.bg3};
  }

  &:not(:last-child) {
    border-bottom: 1px solid ${({ theme }) => theme.bg4};
  }
`;

const PromesaBtn = styled.button`
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  background: transparent;
  border: 1px solid #3b82f640;
  border-radius: 6px;
  color: #3b82f6;
  cursor: pointer;
  font-size: 1rem;
  transition: all 0.15s;

  &:hover {
    background: #3b82f615;
    border-color: #3b82f6;
  }
`;

const CuotaCheckbox = styled.div`
  width: 24px;
  height: 24px;
  border: 2px solid ${({ $checked }) => ($checked ? "#f88533" : "#6b7280")};
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: ${({ $checked }) => ($checked ? "#f88533" : "transparent")};
  color: white;
  transition: all 0.2s;

  svg {
    width: 14px;
    height: 14px;
  }
`;

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

const CuotaNumero = styled.div`
  font-weight: 600;
  color: ${({ theme }) => theme.text};
`;

const CuotaVencimiento = styled.div`
  font-size: 0.8rem;
  color: ${({ theme }) => theme.text}80;
`;

const CuotaMontos = styled.div`
  text-align: right;
`;

const CuotaMontoOriginal = styled.div`
  font-weight: 700;
  color: ${({ theme }) => theme.text};
`;

const CuotaMontoGs = styled.div`
  font-size: 0.75rem;
  color: ${({ theme }) => theme.text}60;
`;

const CuotaEstadoBadge = styled.div`
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  border-radius: 6px;
  font-size: 0.7rem;
  font-weight: 600;

  svg {
    width: 12px;
    height: 12px;
  }
`;

const CobroPanel = styled.div`
  background: ${({ theme }) => theme.body};
  border: 2px solid #f88533;
  border-radius: 16px;
  overflow: hidden;
`;

const CobroResumen = styled.div`
  padding: 16px 20px;
  border-bottom: 1px solid ${({ theme }) => theme.bg4};
`;

const ResumenItem = styled.div`
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 0;
  font-size: ${({ $total }) => ($total ? "1.1rem" : "0.9rem")};
  color: ${({ $secondary }) => ($secondary ? "#6b7280" : "inherit")};

  &:not(:last-child) {
    border-bottom: 1px dashed ${({ theme }) => theme.bg4};
  }
`;

const TotalMonto = styled.strong`
  color: #f88533;
  font-size: 1.2rem;
`;

const MedioPagoSection = styled.div`
  padding: 0 20px 20px;
`;

const MedioPagoLabel = styled.label`
  display: block;
  font-size: 0.875rem;
  font-weight: 600;
  color: ${({ theme }) => theme.text};
  margin-bottom: 12px;
`;

const MedioPagoOptions = styled.div`
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
`;

const MedioPagoOption = styled.button`
  flex: 1;
  min-width: 80px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 12px;
  background: ${({ $selected, theme }) =>
    $selected ? "#f8853320" : theme.bg3};
  border: 2px solid
    ${({ $selected }) => ($selected ? "#f88533" : "transparent")};
  border-radius: 10px;
  cursor: pointer;
  transition: all 0.2s;
  color: ${({ $selected, theme }) => ($selected ? "#f88533" : theme.text)};
  font-size: 0.8rem;
  font-weight: 500;

  svg {
    width: 20px;
    height: 20px;
  }

  &:hover {
    background: ${({ $selected }) => ($selected ? "#f8853320" : "#f8853310")};
  }
`;

const ChequeFields = styled.div`
  display: flex;
  gap: 8px;
  margin-top: 10px;

  input {
    flex: 1;
    min-width: 0;
    padding: 10px 12px;
    border: 1px solid ${({ theme }) => theme.color2};
    border-radius: 8px;
    background: ${({ theme }) => theme.bg3};
    color: ${({ theme }) => theme.text};
    font-size: 0.85rem;

    &::placeholder {
      color: ${({ theme }) => theme.text}66;
    }

    &:focus {
      outline: none;
      border-color: #f88533;
    }
  }
`;

const CobroButton = styled.button`
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: calc(100% - 40px);
  margin: 0 20px 20px;
  padding: 16px;
  background: linear-gradient(135deg, #f88533 0%, #ff6b6b 100%);
  border: none;
  border-radius: 12px;
  font-size: 1rem;
  font-weight: 700;
  color: white;
  cursor: pointer;
  transition: all 0.2s;

  &:hover:not(:disabled) {
    transform: translateY(-2px);
    box-shadow: 0 8px 20px rgba(248, 133, 51, 0.4);
  }

  &:disabled {
    opacity: 0.7;
    cursor: not-allowed;
  }

  svg {
    width: 20px;
    height: 20px;
  }
`;









// Modal styles
const ModalOverlay = styled.div`
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: 20px;
`;

const ModalContent = styled.div`
  background: ${({ theme }) => theme.body};
  border-radius: 16px;
  width: 100%;
  max-width: 500px;
  max-height: 80vh;
  overflow: hidden;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
`;

const ModalHeader = styled.div`
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px;
  border-bottom: 1px solid ${({ theme }) => theme.bg4};
`;

const ModalTitle = styled.h3`
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  font-size: 1.1rem;
  color: ${({ theme }) => theme.text};

  svg {
    color: #f88533;
  }
`;

const CloseButton = styled.button`
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  background: ${({ theme }) => theme.bg3};
  border: none;
  border-radius: 8px;
  cursor: pointer;
  color: ${({ theme }) => theme.text};
  transition: all 0.2s;

  &:hover {
    background: ${({ theme }) => theme.bg4};
  }
`;

const ModalBody = styled.div`
  padding: 20px;
  overflow-y: auto;
  max-height: calc(80vh - 80px);
`;

const ReciboInfo = styled.div`
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding-bottom: 16px;
  border-bottom: 1px solid ${({ theme }) => theme.bg4};
  margin-bottom: 16px;
`;

const ReciboInfoRow = styled.div`
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 0.9rem;

  span {
    color: ${({ theme }) => theme.text}90;
  }

  strong {
    color: ${({ theme }) => theme.text};
  }
`;

const DetalleSection = styled.div`
  margin-bottom: 16px;
`;

const DetalleTitulo = styled.h4`
  font-size: 0.85rem;
  font-weight: 600;
  color: ${({ theme }) => theme.text};
  margin: 0 0 12px 0;
`;

const DetalleList = styled.div`
  display: flex;
  flex-direction: column;
  gap: 8px;
`;

const DetalleItem = styled.div`
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px;
  background: ${({ theme }) => theme.bg3};
  border-radius: 8px;
`;

const DetalleInfo = styled.div`
  display: flex;
  flex-direction: column;
  gap: 4px;

  span {
    font-size: 0.85rem;
    font-weight: 500;
    color: ${({ theme }) => theme.text};
  }
`;

const DetalleMedioPago = styled.div`
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.75rem;
  color: ${({ theme }) => theme.text}80;

  svg {
    width: 14px;
    height: 14px;
  }
`;

const DetalleMonto = styled.div`
  font-weight: 700;
  color: #22c55e;
`;


// Historial Modal Components












// ==================== Cobro: Monto editable, Descuento, Distribución ====================

const CobroFieldSection = styled.div`
  padding: 12px 20px;
  border-bottom: 1px solid ${({ theme }) => theme.bg4};
`;

const CobroFieldLabel = styled.div`
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.85rem;
  font-weight: 600;
  color: ${({ theme }) => theme.text};
  margin-bottom: 10px;

  svg {
    width: 16px;
    height: 16px;
    color: #f88533;
  }
`;

const MontoInputWrapper = styled.div`
  display: flex;
  align-items: center;
  gap: 0;
  background: ${({ theme }) => theme.bg3};
  border: 2px solid transparent;
  border-radius: 10px;
  overflow: hidden;
  transition: border-color 0.2s;

  &:focus-within {
    border-color: #f88533;
  }
`;

const MontoPrefix = styled.span`
  padding: 10px 12px;
  font-size: 1rem;
  font-weight: 700;
  color: #f88533;
  background: ${({ theme }) => theme.bg4}40;
  user-select: none;
`;

const MontoInput = styled.input`
  flex: 1;
  padding: 10px 12px;
  background: transparent;
  border: none;
  font-size: 1.1rem;
  font-weight: 700;
  color: ${({ theme }) => theme.text};
  outline: none;
  min-width: 0;

  &::placeholder {
    color: ${({ theme }) => theme.text}40;
  }

  &::-webkit-inner-spin-button,
  &::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
  }
  -moz-appearance: textfield;
`;

const MontoResetButton = styled.button`
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px 12px;
  background: transparent;
  border: none;
  color: ${({ theme }) => theme.text}60;
  cursor: pointer;
  transition: color 0.2s;

  &:hover {
    color: #f88533;
  }

  svg {
    width: 16px;
    height: 16px;
  }
`;

const MontoHint = styled.div`
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
  padding: 6px 10px;
  border-radius: 6px;
  font-size: 0.75rem;
  background: ${({ $warning }) => ($warning ? "#f59e0b12" : "#3b82f612")};
  color: ${({ $warning }) => ($warning ? "#f59e0b" : "#3b82f6")};

  svg {
    width: 14px;
    height: 14px;
    flex-shrink: 0;
  }
`;

const DescuentoToggle = styled.button`
  margin-left: auto;
  padding: 4px 10px;
  border-radius: 4px;
  font-size: 0.7rem;
  font-weight: 600;
  border: 1px solid ${({ $active }) => ($active ? "#ef4444" : "#f88533")};
  background: ${({ $active }) => ($active ? "#ef444415" : "transparent")};
  color: ${({ $active }) => ($active ? "#ef4444" : "#f88533")};
  cursor: pointer;
  transition: all 0.2s;
`;

const DescuentoControls = styled.div`
  display: flex;
  flex-direction: column;
  gap: 8px;
`;

const DescuentoTipoSelector = styled.div`
  display: flex;
  gap: 4px;
`;

const DescuentoTipoBtn = styled.button`
  flex: 1;
  padding: 8px;
  border: 2px solid ${({ $active }) => ($active ? "#f88533" : "transparent")};
  background: ${({ $active, theme }) => ($active ? "#f8853320" : theme.bg3)};
  color: ${({ $active, theme }) => ($active ? "#f88533" : theme.text)};
  border-radius: 6px;
  font-size: 0.85rem;
  font-weight: 700;
  cursor: pointer;
  transition: all 0.2s;
`;

const DescuentoInput = styled.input`
  width: 100%;
  padding: 10px 12px;
  background: ${({ theme }) => theme.bg3};
  border: 2px solid transparent;
  border-radius: 8px;
  font-size: 0.9rem;
  color: ${({ theme }) => theme.text};
  outline: none;
  transition: border-color 0.2s;

  &:focus {
    border-color: #f88533;
  }

  &::placeholder {
    color: ${({ theme }) => theme.text}40;
  }

  &::-webkit-inner-spin-button,
  &::-webkit-outer-spin-button {
    -webkit-appearance: none;
  }
  -moz-appearance: textfield;
`;

const DescuentoAutorizadoBadge = styled.div`
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  padding: 7px 12px;
  background: ${({ theme }) => theme.success || "#22c55e"}18;
  border: 1px solid ${({ theme }) => theme.success || "#22c55e"}50;
  border-radius: 8px;
  font-size: 0.78rem;
  color: ${({ theme }) => theme.success || "#22c55e"};

  svg {
    flex-shrink: 0;
    font-size: 0.9rem;
  }

  span {
    opacity: 0.7;
    font-style: italic;
  }
`;

const DescuentoMotivoInput = styled.input`
  width: 100%;
  padding: 8px 12px;
  background: ${({ theme }) => theme.bg3};
  border: 1px solid transparent;
  border-radius: 8px;
  font-size: 0.8rem;
  color: ${({ theme }) => theme.text};
  outline: none;
  transition: border-color 0.2s;

  &:focus {
    border-color: ${({ theme }) => theme.bg5};
  }

  &::placeholder {
    color: ${({ theme }) => theme.text}40;
  }
`;

const DistribucionSection = styled.div`
  padding: 12px 20px;
  border-bottom: 1px solid ${({ theme }) => theme.bg4};
`;

const DistribucionList = styled.div`
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 8px;
`;

const DistribucionItem = styled.div`
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 8px;
  background: ${({ $parcial, $sinPago, theme }) =>
    $sinPago ? "#ef444410" : $parcial ? "#f59e0b10" : `${theme.bg3}`};
  border-left: 3px solid
    ${({ $parcial, $sinPago }) =>
      $sinPago ? "#ef4444" : $parcial ? "#f59e0b" : "#22c55e"};
  font-size: 0.8rem;
`;

// ==================== Numeración ====================

const NumeracionBadge = styled.span`
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 0.7rem;
  color: ${({ theme }) => theme.textSecondary};
  background: ${({ theme }) => theme.bg3};
  padding: 3px 8px;
  border-radius: 4px;

  svg {
    width: 12px;
    height: 12px;
  }
`;

const NumeracionWarning = styled.div`
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px;
  border-radius: 8px;
  font-size: 0.8rem;
  background: ${({ $error }) => ($error ? "#ef444415" : "#f59e0b15")};
  border: 1px solid ${({ $error }) => ($error ? "#ef4444" : "#f59e0b")};
  color: ${({ $error }) => ($error ? "#ef4444" : "#f59e0b")};

  > svg {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
    margin-top: 2px;
  }

  strong {
    display: block;
    margin-bottom: 4px;
  }

  p {
    margin: 0;
    font-size: 0.75rem;
    opacity: 0.85;
    line-height: 1.4;
  }
`;

const DistribucionCuota = styled.div`
  flex: 1;
  min-width: 0;

  span {
    font-weight: 600;
    color: ${({ theme }) => theme.text};
  }
`;

const DistribucionFactura = styled.div`
  font-size: 0.7rem;
  color: ${({ theme }) => theme.text}60;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
`;

const DistribucionMontos = styled.div`
  text-align: right;
  flex-shrink: 0;
`;

const DistribucionDescuento = styled.div`
  font-size: 0.7rem;
  color: #ef4444;
  font-weight: 500;
`;

const DistribucionMontoPagado = styled.div`
  font-weight: 700;
  color: #22c55e;
`;

const DistribucionEstado = styled.div`
  font-size: 0.65rem;
  font-weight: 600;
  padding: 3px 6px;
  border-radius: 4px;
  white-space: nowrap;
  flex-shrink: 0;
  background: ${({ $parcial }) => ($parcial ? "#f59e0b15" : "#22c55e15")};
  color: ${({ $parcial }) => ($parcial ? "#f59e0b" : "#22c55e")};
`;

// ==================== Recibo Detail: badges & rows ====================

const ReciboBadge = styled.span`
  padding: 3px 8px;
  border-radius: 4px;
  font-size: 0.7rem;
  font-weight: 600;
  background: ${({ $color }) => `${$color}15`};
  color: ${({ $color }) => $color};
`;



const DistribucionResumen = styled.div`
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 6px 0;
  font-size: ${({ $total }) => ($total ? "1rem" : "0.85rem")};
  font-weight: ${({ $total }) => ($total ? "700" : "500")};
  color: ${({ theme }) => theme.text};

  &:not(:last-child) {
    border-bottom: 1px dashed ${({ theme }) => theme.bg4};
  }
`;

const DistribucionMora = styled.div`
  font-size: 0.75rem;
  font-weight: 600;
  color: #ef4444;
`;

const InteresPendienteHint = styled.span`
  display: block;
  font-size: 0.7rem;
  font-weight: 500;
  opacity: 0.6;
`;

const BtnInteresTodo = styled.button`
  border: 1px solid ${({ theme }) => theme.bg4};
  background: transparent;
  color: ${({ theme }) => theme.text};
  border-radius: 6px;
  padding: 6px 10px;
  font-size: 0.72rem;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;

  &:hover {
    background: ${({ theme }) => theme.bg3};
  }
`;

const InteresRestanteHint = styled.div`
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.72rem;
  font-weight: 500;
  color: #f59e0b;
`;

// ==================== Confirmación de Cobro ====================

const ConfirmModalContent = styled.div`
  background: ${({ theme }) => theme.bg};
  border-radius: 16px;
  width: 95%;
  max-width: 520px;
  max-height: 90vh;
  overflow-y: auto;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
  border: 1px solid ${({ theme }) => theme.bg3};
`;

const ConfirmModalBody = styled.div`
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 16px;
`;

const ConfirmSection = styled.div`
  display: flex;
  flex-direction: column;
  gap: 8px;
`;

const ConfirmSectionTitle = styled.div`
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.8rem;
  font-weight: 600;
  color: ${({ theme }) => theme.text}90;
  text-transform: uppercase;
  letter-spacing: 0.5px;

  svg {
    width: 14px;
    height: 14px;
    color: #f88533;
  }
`;

const ConfirmClienteInfo = styled.div`
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px 12px;
  background: ${({ theme }) => theme.bg3};
  border-radius: 8px;

  strong {
    font-size: 0.9rem;
    color: ${({ theme }) => theme.text};
  }

  span {
    font-size: 0.75rem;
    color: ${({ theme }) => theme.text}70;
  }
`;

const ConfirmCuotasList = styled.div`
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-height: 200px;
  overflow-y: auto;
`;

const ConfirmCuotaItem = styled.div`
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 12px;
  background: ${({ theme }) => theme.bg3};
  border-radius: 8px;
  font-size: 0.8rem;
`;

const ConfirmCuotaLeft = styled.div`
  display: flex;
  align-items: center;
  gap: 8px;

  span {
    font-weight: 500;
    color: ${({ theme }) => theme.text};
  }
`;

const ConfirmCuotaRight = styled.div`
  display: flex;
  align-items: center;
  gap: 8px;

  strong {
    color: ${({ theme }) => theme.text};
  }
`;

const ConfirmCuotaDescuento = styled.span`
  font-size: 0.75rem;
  color: #ef4444;
  font-weight: 600;
`;

const ConfirmResumenList = styled.div`
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px 12px;
  background: ${({ theme }) => theme.bg3};
  border-radius: 8px;
`;

const ConfirmResumenRow = styled.div`
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: ${({ $total }) => ($total ? "1rem" : "0.85rem")};
  font-weight: ${({ $total }) => ($total ? "700" : "400")};
  color: ${({ theme }) => theme.text};
  ${({ $total }) =>
    $total && "padding-top: 8px; border-top: 1px dashed #ffffff20;"}
`;

const ConfirmTotalMonto = styled.strong`
  color: #22c55e;
  font-size: 1.1rem;
`;

const ConfirmMontoEntregadoRow = styled.div`
  display: flex;
  gap: 8px;
`;

const ConfirmMontoInput = styled.input`
  width: 100%;
  padding: 12px 14px;
  background: ${({ theme }) => theme.bg3};
  border: 2px solid transparent;
  border-radius: 10px;
  font-size: 1.1rem;
  font-weight: 600;
  color: ${({ theme }) => theme.text};
  outline: none;
  transition: border-color 0.2s;

  &:focus {
    border-color: #f88533;
  }

  &::placeholder {
    color: ${({ theme }) => theme.text}30;
    font-weight: 400;
    font-size: 0.9rem;
  }

  &::-webkit-inner-spin-button,
  &::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
  }
  -moz-appearance: textfield;
`;

const ConfirmVueltoBox = styled.div`
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  border-radius: 8px;
  font-size: 0.85rem;
  background: ${({ $warning }) => ($warning ? "#f59e0b15" : "#22c55e15")};
  border: 1px solid ${({ $warning }) => ($warning ? "#f59e0b40" : "#22c55e40")};
  color: ${({ $warning }) => ($warning ? "#f59e0b" : "#22c55e")};

  svg {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
  }

  strong {
    font-size: 1rem;
  }
`;

const ConfirmActions = styled.div`
  display: flex;
  gap: 10px;
  margin-top: 4px;
`;

const ConfirmCancelButton = styled.button`
  flex: 1;
  padding: 12px;
  border: 1px solid ${({ theme }) => theme.bg4};
  border-radius: 10px;
  background: transparent;
  color: ${({ theme }) => theme.text};
  font-size: 0.9rem;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s;

  &:hover:not(:disabled) {
    background: ${({ theme }) => theme.bg3};
  }

  &:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }
`;

const ConfirmOkButton = styled.button`
  flex: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px;
  border: none;
  border-radius: 10px;
  background: linear-gradient(135deg, #f88533, #e07020);
  color: white;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s;

  &:hover:not(:disabled) {
    filter: brightness(1.1);
    transform: translateY(-1px);
  }

  &:disabled {
    opacity: 0.7;
    cursor: not-allowed;
    transform: none;
  }

  svg {
    width: 18px;
    height: 18px;
  }
`;

const ConfirmSuccessContainer = styled.div`
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 20px 0;
  gap: 8px;
  width: 100%;
`;

const ConfirmSuccessIcon = styled.div`
  color: #22c55e;
  svg {
    width: 56px;
    height: 56px;
  }
`;

const ConfirmSuccessTitle = styled.h3`
  margin: 0;
  font-size: 1.1rem;
  color: #22c55e;
  font-weight: 700;
`;

const ConfirmSuccessRecibo = styled.div`
  font-size: 0.9rem;
  color: ${({ theme }) => theme.text}90;
  font-weight: 500;
  margin-bottom: 12px;
`;

const ConfirmVueltoGrande = styled.strong`
  color: #22c55e;
  font-size: 1.3rem;
`;

// ==================== Historial Actions & PDF Preview ====================


const SmallActionBtn = styled.button`
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  background: ${({ $accent, $danger }) =>
    $accent ? "#f8853315" : $danger ? "#ef444415" : "transparent"};
  border: 1px solid
    ${({ $accent, $danger, theme }) =>
      $accent ? "#f8853340" : $danger ? "#ef444440" : theme.bg4 || "#ffffff20"};
  border-radius: 6px;
  cursor: pointer;
  color: ${({ $accent, $danger, theme }) =>
    $accent ? "#f88533" : $danger ? "#ef4444" : theme.text + "80"};
  transition: all 0.2s;

  svg {
    width: 14px;
    height: 14px;
  }

  &:hover:not(:disabled) {
    background: ${({ $accent, $danger }) =>
      $accent ? "#f8853325" : $danger ? "#ef444425" : "#ffffff10"};
    color: ${({ $accent, $danger }) =>
      $accent ? "#f88533" : $danger ? "#ef4444" : "#ffffff"};
  }

  &:disabled {
    opacity: 0.4;
    cursor: not-allowed;
  }
`;



const PdfPreviewModalContent = styled.div`
  background: ${({ theme }) => theme.body};
  border-radius: 16px;
  width: 95%;
  max-width: 900px;
  height: 85vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4);

  @media (max-width: 768px) {
    width: 100%;
    height: 100vh;
    max-width: 100%;
    border-radius: 0;
  }
`;

const PdfPreviewActions = styled.div`
  display: flex;
  align-items: center;
  gap: 8px;
`;

const PdfIframeContainer = styled.div`
  flex: 1;
  overflow: hidden;
  background: #1a1a1a;
`;

const SuccessActionsRow = styled.div`
  display: flex;
  gap: 8px;
  width: 100%;
  margin-top: 8px;
`;

const SuccessActionBtn = styled.button`
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 10px 12px;
  background: ${({ $accent }) => ($accent ? "#f8853318" : "transparent")};
  border: 1px solid
    ${({ $accent, theme }) =>
      $accent ? "#f8853350" : theme.bg4 || "#ffffff20"};
  border-radius: 8px;
  cursor: pointer;
  color: ${({ $accent, theme }) => ($accent ? "#f88533" : theme.text)};
  font-size: 0.8rem;
  font-weight: 500;
  transition: all 0.2s;

  svg {
    width: 16px;
    height: 16px;
  }

  &:hover:not(:disabled) {
    background: ${({ $accent }) => ($accent ? "#f8853328" : "#ffffff08")};
  }

  &:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }
`;
