import { Icon } from "@iconify/react";
import { useEffect, useState } from "react";
import * as XLSX from "xlsx";
import { toast } from "sonner";
import styled from "styled-components";
import {
  getReporteCobradorDetalle,
  getReporteCobradorPorCobrador,
  getReporteCobradorProductividad,
} from "../api/cobros.service";
import { AccesoRestringido } from "../components/common/AccesoRestringido";
import { usePermission } from "../hooks/usePermission";
import { Device } from "../styles/breakpoints";
import { sanitizeRows } from "../components/_standards";

// ─── Helpers ──────────────────────────────────────────────────────────────────
const fmtGs = (n) =>
  `Gs. ${Number(n || 0).toLocaleString("es-PY", { maximumFractionDigits: 0 })}`;
const fmtPct = (n) => `${n}%`;
const fmtNum = (n) => Number(n || 0).toLocaleString("es-PY", { maximumFractionDigits: 0 });

const hoy = new Date();
const primerDiaMes = new Date(hoy.getFullYear(), hoy.getMonth(), 1)
  .toISOString()
  .split("T")[0];
const hoyStr = hoy.toISOString().split("T")[0];

// ─── Export Excel (resumen) ───────────────────────────────────────────────────
function exportarExcel(cobradores, periodo) {
  const rows = [
    ["Cobrador", "Total cobrado", "Intereses cobrados", "Descuentos", "Cantidad cobros", "Promedio/cobro", "Días activos", "Cuotas pendientes", "Cuotas vencidas", "Monto pendiente", "Tasa morosidad"],
  ];
  for (const r of cobradores) {
    rows.push([
      `${r.cobrador.nombre} ${r.cobrador.apellido}`,
      r.cobros.total_cobrado,
      r.cobros.total_mora_cobrada || 0,
      r.cobros.total_descuentos,
      r.cobros.cantidad_cobros,
      r.cobros.promedio_por_cobro,
      r.cobros.dias_activos,
      r.pendientes.total_pendientes,
      r.pendientes.total_vencidas,
      r.pendientes.monto_pendiente,
      `${r.pendientes.tasa_morosidad}%`,
    ]);
  }
  const ws = XLSX.utils.aoa_to_sheet(sanitizeRows(rows));
  const wb = XLSX.utils.book_new();
  XLSX.utils.book_append_sheet(wb, ws, "Resumen");
  XLSX.writeFile(wb, `reporte-cobrador-${periodo.desde.slice(0, 10)}-${periodo.hasta.slice(0, 10)}.xlsx`);
}

// ─── Export Excel (detalle) ───────────────────────────────────────────────────
function exportarDetalleExcel(detalles, cobradorNombre, fechaDesde, fechaHasta) {
  const rows = [
    ["Fecha", "N° Recibo", "Cliente", "Teléfono", "Factura", "N° Cuota", "Vencimiento", "Monto cuota", "Monto pagado", "Descuento", "Mora", "Parcial", "Estado"],
  ];
  for (const r of detalles) {
    if (r.detalles.length === 0) {
      rows.push([r.fecha, r.numero_recibo, r.cliente.nombre, r.cliente.telefono || "", "", "", "", "", r.monto_total, r.descuento_monto, r.mora_total, "", r.estado]);
    } else {
      for (const d of r.detalles) {
        rows.push([r.fecha, r.numero_recibo, r.cliente.nombre, r.cliente.telefono || "", d.factura, d.nro_cuota, d.vencimiento, d.monto_cuota, d.monto_pagado, d.descuento, d.mora, d.parcial ? "Sí" : "No", r.estado]);
      }
    }
  }
  const ws = XLSX.utils.aoa_to_sheet(sanitizeRows(rows));
  const wb = XLSX.utils.book_new();
  XLSX.utils.book_append_sheet(wb, ws, "Detalle");
  XLSX.writeFile(wb, `detalle-cobrador-${cobradorNombre.replace(/\s+/g, "_")}-${fechaDesde}-${fechaHasta}.xlsx`);
}

// ─── Componente principal ─────────────────────────────────────────────────────
export function ReporteCobrador() {
  const { can: canCobranzas } = usePermission("COBRANZAS");
  const canRead = canCobranzas("COB_REP_REPORTE_VER");

  const [fechaDesde, setFechaDesde] = useState(primerDiaMes);
  const [fechaHasta, setFechaHasta] = useState(hoyStr);
  const [cobradoresData, setCobradoresData] = useState(null);
  const [productividad, setProductividad] = useState(null);
  const [cobradorSeleccionado, setCobradorSeleccionado] = useState(null);
  const [loading, setLoading] = useState(false);
  const [loadingProd, setLoadingProd] = useState(false);

  // Detalle
  const [detalleOpen, setDetalleOpen] = useState(false);
  const [detalleData, setDetalleData] = useState([]);
  const [detalleCobrador, setDetalleCobrador] = useState(null);
  const [loadingDetalle, setLoadingDetalle] = useState(false);
  const [detallePage, setDetallePage] = useState(1);
  const [detalleTotalPages, setDetalleTotalPages] = useState(1);

  const cargarDatos = async () => {
    setLoading(true);
    try {
      const data = await getReporteCobradorPorCobrador({ fecha_desde: fechaDesde, fecha_hasta: fechaHasta });
      setCobradoresData(data);
    } catch {
      toast.error("Error al cargar el reporte");
    } finally {
      setLoading(false);
    }
  };

  const cargarProductividad = async (cobradorId) => {
    setLoadingProd(true);
    try {
      const data = await getReporteCobradorProductividad({
        fecha_desde: fechaDesde,
        fecha_hasta: fechaHasta,
        ...(cobradorId ? { cobrador_id: cobradorId } : {}),
      });
      setProductividad(data);
    } catch {
      /* silencioso */
    } finally {
      setLoadingProd(false);
    }
  };

  const abrirDetalle = async (cobrador, page = 1) => {
    setDetalleCobrador(cobrador);
    setDetalleOpen(true);
    setDetallePage(page);
    setLoadingDetalle(true);
    try {
      const data = await getReporteCobradorDetalle({
        cobrador_id: cobrador.id,
        fecha_desde: fechaDesde,
        fecha_hasta: fechaHasta,
        page,
        pageSize: 20,
      });
      setDetalleData(data.data || []);
      setDetalleTotalPages(data.totalPages || 1);
    } catch {
      toast.error("Error al cargar el detalle");
    } finally {
      setLoadingDetalle(false);
    }
  };

  const cargarDetalleExport = async () => {
    if (!detalleCobrador) return;
    try {
      // Cargar todas las páginas para exportar
      const first = await getReporteCobradorDetalle({ cobrador_id: detalleCobrador.id, fecha_desde: fechaDesde, fecha_hasta: fechaHasta, page: 1, pageSize: 500 });
      exportarDetalleExcel(first.data || [], `${detalleCobrador.nombre} ${detalleCobrador.apellido}`, fechaDesde, fechaHasta);
    } catch {
      toast.error("Error al exportar");
    }
  };

  useEffect(() => {
    cargarDatos();
    cargarProductividad(null);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

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

  const aplicarFiltros = () => {
    cargarDatos();
    cargarProductividad(cobradorSeleccionado);
    if (detalleOpen && detalleCobrador) abrirDetalle(detalleCobrador, 1);
  };

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

  const { cobradores = [], totales = {}, periodo } = cobradoresData || {};
  const maxMonto = productividad?.max_dia || 1;

  return (
    <PageWrap>
      {/* Cabecera */}
      <PageHeader>
        <HeaderTitle>
          <Icon icon="lucide:users" width={22} />
          <div>
            <h1>Reporte por Cobrador</h1>
            <p>Rendimiento, morosidad y productividad de cobradores</p>
          </div>
        </HeaderTitle>
        <ExportBtn onClick={() => cobradoresData && exportarExcel(cobradores, periodo)} disabled={!cobradoresData || loading}>
          <Icon icon="lucide:file-spreadsheet" width={15} />
          Exportar Excel
        </ExportBtn>
      </PageHeader>

      {/* Filtros */}
      <FiltersCard>
        <FilterRow>
          <FilterGroup>
            <FilterLabel>Desde</FilterLabel>
            <FilterInput type="date" value={fechaDesde} onChange={(e) => setFechaDesde(e.target.value)} />
          </FilterGroup>
          <FilterGroup>
            <FilterLabel>Hasta</FilterLabel>
            <FilterInput type="date" value={fechaHasta} onChange={(e) => setFechaHasta(e.target.value)} />
          </FilterGroup>
          <ApplyBtn onClick={aplicarFiltros} disabled={loading}>
            <Icon icon="lucide:search" width={15} />
            Consultar
          </ApplyBtn>
        </FilterRow>
      </FiltersCard>

      {/* KPIs globales */}
      {cobradoresData && (
        <KpiGrid>
          <KpiCard $color="#3b82f6">
            <KpiIcon><Icon icon="lucide:banknote" width={20} /></KpiIcon>
            <KpiNum>{fmtGs(totales.total_cobrado)}</KpiNum>
            <KpiLabel>Total cobrado</KpiLabel>
          </KpiCard>
          <KpiCard $color="#22c55e">
            <KpiIcon><Icon icon="lucide:receipt" width={20} /></KpiIcon>
            <KpiNum>{totales.cantidad_cobros}</KpiNum>
            <KpiLabel>Cobros realizados</KpiLabel>
          </KpiCard>
          {totales.total_mora_cobrada > 0 && (
            <KpiCard $color="#f88533">
              <KpiIcon><Icon icon="lucide:percent" width={20} /></KpiIcon>
              <KpiNum>{fmtGs(totales.total_mora_cobrada)}</KpiNum>
              <KpiLabel>Intereses cobrados</KpiLabel>
            </KpiCard>
          )}
          <KpiCard $color="#f59e0b">
            <KpiIcon><Icon icon="lucide:clock" width={20} /></KpiIcon>
            <KpiNum>{fmtGs(totales.monto_pendiente)}</KpiNum>
            <KpiLabel>Monto pendiente</KpiLabel>
          </KpiCard>
          <KpiCard $color="#ef4444">
            <KpiIcon><Icon icon="lucide:alert-triangle" width={20} /></KpiIcon>
            <KpiNum>
              {totales.total_pendientes > 0
                ? fmtPct(Math.round((totales.total_vencidas / totales.total_pendientes) * 100))
                : "0%"}
            </KpiNum>
            <KpiLabel>Tasa morosidad global</KpiLabel>
          </KpiCard>
        </KpiGrid>
      )}

      <ContentGrid>
        {/* Tabla de cobradores */}
        <Section>
          <SectionTitle>
            <Icon icon="lucide:users" width={16} />
            Rendimiento por Cobrador
          </SectionTitle>

          {loading ? (
            <LoadingMsg><Icon icon="lucide:loader-circle" className="spin" /> Cargando...</LoadingMsg>
          ) : cobradores.length === 0 ? (
            <EmptyMsg>No hay datos en el período seleccionado</EmptyMsg>
          ) : (
            <CobradorList>
              {cobradores.map((r) => {
                const isSelected = cobradorSeleccionado === r.cobrador.id;
                return (
                  <CobradorCard key={r.cobrador.id} $selected={isSelected}>
                    <CobradorHeader onClick={() => setCobradorSeleccionado(isSelected ? null : r.cobrador.id)}>
                      <CobradorNombre>
                        <Icon icon="lucide:user-circle" width={16} />
                        {r.cobrador.nombre} {r.cobrador.apellido}
                      </CobradorNombre>
                      <MorosidadBadge $pct={r.pendientes.tasa_morosidad}>
                        {fmtPct(r.pendientes.tasa_morosidad)} mora
                      </MorosidadBadge>
                    </CobradorHeader>

                    <CobradorStats onClick={() => setCobradorSeleccionado(isSelected ? null : r.cobrador.id)}>
                      <StatItem>
                        <StatVal $color="#3b82f6">{fmtGs(r.cobros.total_cobrado)}</StatVal>
                        <StatLbl>Cobrado</StatLbl>
                      </StatItem>
                      <StatItem>
                        <StatVal>{r.cobros.cantidad_cobros}</StatVal>
                        <StatLbl>Cobros</StatLbl>
                      </StatItem>
                      {r.cobros.total_mora_cobrada > 0 ? (
                        <StatItem>
                          <StatVal $color="#f88533">{fmtGs(r.cobros.total_mora_cobrada)}</StatVal>
                          <StatLbl>Intereses</StatLbl>
                        </StatItem>
                      ) : (
                        <StatItem>
                          <StatVal>{fmtGs(r.cobros.promedio_por_cobro)}</StatVal>
                          <StatLbl>Promedio</StatLbl>
                        </StatItem>
                      )}
                      <StatItem>
                        <StatVal $color="#ef4444">{r.pendientes.total_vencidas}</StatVal>
                        <StatLbl>Vencidas</StatLbl>
                      </StatItem>
                    </CobradorStats>

                    {r.cobros.total_cobrado > 0 && (
                      <MiniBar onClick={() => setCobradorSeleccionado(isSelected ? null : r.cobrador.id)}>
                        <MiniBarFill
                          $pct={cobradoresData?.totales?.total_cobrado > 0
                            ? Math.round((r.cobros.total_cobrado / cobradoresData.totales.total_cobrado) * 100)
                            : 0}
                        />
                      </MiniBar>
                    )}

                    {/* Acciones */}
                    <CobradorActions>
                      <ActionLink onClick={() => setCobradorSeleccionado(isSelected ? null : r.cobrador.id)}>
                        <Icon icon={isSelected ? "lucide:check-circle" : "lucide:bar-chart-2"} width={12} />
                        {isSelected ? "Mostrando productividad" : "Ver productividad"}
                      </ActionLink>
                      <DetalleBtn onClick={() => abrirDetalle(r.cobrador)}>
                        <Icon icon="lucide:list" width={12} />
                        Ver detalle
                      </DetalleBtn>
                    </CobradorActions>
                  </CobradorCard>
                );
              })}
            </CobradorList>
          )}
        </Section>

        {/* Productividad diaria */}
        <Section>
          <SectionTitle>
            <Icon icon="lucide:bar-chart-2" width={16} />
            Productividad Diaria
            {cobradorSeleccionado && cobradoresData && (
              <CobradorTag>
                {(() => { const c = cobradores.find((r) => r.cobrador.id === cobradorSeleccionado); return c ? `${c.cobrador.nombre} ${c.cobrador.apellido}` : ""; })()}
                <button onClick={() => setCobradorSeleccionado(null)}><Icon icon="lucide:x" width={12} /></button>
              </CobradorTag>
            )}
          </SectionTitle>

          {loadingProd ? (
            <LoadingMsg><Icon icon="lucide:loader-circle" className="spin" /> Cargando...</LoadingMsg>
          ) : !productividad || productividad.dias.length === 0 ? (
            <EmptyMsg>Sin cobros en el período</EmptyMsg>
          ) : (
            <>
              <ProdSummary>{fmtGs(productividad.totales.monto)} en {productividad.totales.cantidad} cobros</ProdSummary>
              <BarChart>
                {productividad.dias.map((d) => {
                  const pct = Math.round((d.monto / maxMonto) * 100);
                  return (
                    <BarItem key={d.fecha} title={`${d.fecha}: ${fmtGs(d.monto)} (${d.cantidad} cobros)`}>
                      <BarTooltip>
                        <strong>{fmtGs(d.monto)}</strong>
                        <span>{d.cantidad} cobro{d.cantidad !== 1 ? "s" : ""}</span>
                      </BarTooltip>
                      <Bar $pct={pct} />
                      <BarDate>{d.fecha.slice(5)}</BarDate>
                    </BarItem>
                  );
                })}
              </BarChart>
            </>
          )}
        </Section>
      </ContentGrid>

      {/* ── Panel lateral de detalle ── */}
      {detalleOpen && (
        <DrawerOverlay onClick={() => setDetalleOpen(false)}>
          <DrawerPanel onClick={(e) => e.stopPropagation()}>
            <DrawerHead>
              <DrawerTitle>
                <Icon icon="lucide:list" width={18} />
                <div>
                  <div>Detalle de cobros</div>
                  {detalleCobrador && (
                    <DrawerSubtitle>{detalleCobrador.nombre} {detalleCobrador.apellido}</DrawerSubtitle>
                  )}
                </div>
              </DrawerTitle>
              <DrawerActions>
                <DrawerExportBtn onClick={cargarDetalleExport} title="Exportar Excel">
                  <Icon icon="lucide:file-spreadsheet" width={15} />
                </DrawerExportBtn>
                <DrawerCloseBtn onClick={() => setDetalleOpen(false)}>
                  <Icon icon="lucide:x" width={18} />
                </DrawerCloseBtn>
              </DrawerActions>
            </DrawerHead>

            <DrawerPeriodo>{fechaDesde} al {fechaHasta}</DrawerPeriodo>

            <DrawerBody>
              {loadingDetalle ? (
                <LoadingMsg><Icon icon="lucide:loader-circle" className="spin" /> Cargando...</LoadingMsg>
              ) : detalleData.length === 0 ? (
                <EmptyMsg>Sin cobros en este período</EmptyMsg>
              ) : (
                detalleData.map((recibo) => (
                  <ReciboCard key={recibo.id}>
                    <ReciboHead>
                      <div>
                        <ReciboBadge>N° {recibo.numero_recibo}</ReciboBadge>
                        <ReciboFecha>{recibo.fecha}</ReciboFecha>
                      </div>
                      <ReciboTotal>
                        {fmtGs(recibo.monto_total)}
                        {recibo.mora_total > 0 && (
                          <MoraTag>+{fmtGs(recibo.mora_total)} mora</MoraTag>
                        )}
                      </ReciboTotal>
                    </ReciboHead>

                    <ReciboCliente>
                      <Icon icon="lucide:user" width={12} />
                      {recibo.cliente.nombre}
                      {recibo.cliente.telefono && (
                        <ReciboTel href={`tel:${recibo.cliente.telefono}`}>
                          <Icon icon="lucide:phone" width={11} />
                          {recibo.cliente.telefono}
                        </ReciboTel>
                      )}
                    </ReciboCliente>

                    {recibo.descuento_monto > 0 && (
                      <ReciboDescuento>
                        <Icon icon="lucide:tag" width={11} />
                        Descuento: {fmtGs(recibo.descuento_monto)}
                      </ReciboDescuento>
                    )}

                    <DetalleCuotasList>
                      {recibo.detalles.map((d, i) => (
                        <DetalleCuotaRow key={i}>
                          <DetalleCuotaInfo>
                            <span>{d.factura}</span>
                            <span>Cuota {d.nro_cuota}{d.vencimiento ? ` · vence ${d.vencimiento}` : ""}</span>
                            {d.parcial && <ParcialTag>Parcial</ParcialTag>}
                          </DetalleCuotaInfo>
                          <DetalleCuotaMontos>
                            <strong>{fmtGs(d.monto_pagado)}</strong>
                            {d.descuento > 0 && <span style={{ color: "#22c55e", fontSize: 11 }}>-{fmtGs(d.descuento)}</span>}
                            {d.mora > 0 && <span style={{ color: "#f88533", fontSize: 11 }}>+{fmtGs(d.mora)} mora</span>}
                          </DetalleCuotaMontos>
                        </DetalleCuotaRow>
                      ))}
                    </DetalleCuotasList>
                  </ReciboCard>
                ))
              )}
            </DrawerBody>

            {detalleTotalPages > 1 && (
              <DrawerPagination>
                <PageBtn disabled={detallePage === 1} onClick={() => { const p = detallePage - 1; setDetallePage(p); abrirDetalle(detalleCobrador, p); }}>
                  <Icon icon="lucide:chevron-left" width={14} />
                </PageBtn>
                <span>Pág. {detallePage} de {detalleTotalPages}</span>
                <PageBtn disabled={detallePage === detalleTotalPages} onClick={() => { const p = detallePage + 1; setDetallePage(p); abrirDetalle(detalleCobrador, p); }}>
                  <Icon icon="lucide:chevron-right" width={14} />
                </PageBtn>
              </DrawerPagination>
            )}
          </DrawerPanel>
        </DrawerOverlay>
      )}
    </PageWrap>
  );
}

// ─── Styled Components ────────────────────────────────────────────────────────
const PageWrap = styled.div`
  padding: 24px;
  max-width: 1200px;
  margin: 0 auto;
  @media ${Device.tablet} { padding: 12px; }
`;
const PageHeader = styled.div`
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  margin-bottom: 20px;
  gap: 12px;
  flex-wrap: wrap;
`;
const HeaderTitle = styled.div`
  display: flex;
  align-items: center;
  gap: 12px;
  color: ${({ theme }) => theme.text};
  h1 { font-size: 20px; font-weight: 700; margin: 0; }
  p { font-size: 13px; color: #6b7280; margin: 2px 0 0; }
`;
const ExportBtn = styled.button`
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border-radius: 8px;
  border: 1px solid #d1d5db;
  background: transparent;
  color: ${({ theme }) => theme.text};
  font-size: 13px;
  cursor: pointer;
  &:disabled { opacity: 0.5; cursor: not-allowed; }
  &:hover:not(:disabled) { background: ${({ theme }) => theme.bg3 || "#f3f4f6"}; }
`;
const FiltersCard = styled.div`
  background: ${({ theme }) => theme.body};
  border: 1px solid ${({ theme }) => theme.bg4 || "#e5e7eb"};
  border-radius: 12px;
  padding: 16px;
  margin-bottom: 20px;
`;
const FilterRow = styled.div`
  display: flex;
  align-items: flex-end;
  gap: 12px;
  flex-wrap: wrap;
`;
const FilterGroup = styled.div`
  display: flex;
  flex-direction: column;
  gap: 4px;
`;
const FilterLabel = styled.label`
  font-size: 11px;
  color: #6b7280;
  font-weight: 500;
`;
const FilterInput = styled.input`
  padding: 8px 10px;
  border-radius: 8px;
  border: 1px solid ${({ theme }) => theme.bg4 || "#e5e7eb"};
  background: ${({ theme }) => theme.body};
  color: ${({ theme }) => theme.text};
  font-size: 13px;
`;
const ApplyBtn = styled.button`
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  border-radius: 8px;
  border: none;
  background: #3b82f6;
  color: white;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  &:disabled { opacity: 0.5; cursor: not-allowed; }
`;
const KpiGrid = styled.div`
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 12px;
  margin-bottom: 24px;
`;
const KpiCard = styled.div`
  background: ${({ $color }) => $color + "12"};
  border: 1px solid ${({ $color }) => $color + "30"};
  border-radius: 12px;
  padding: 16px;
`;
const KpiIcon = styled.div`
  color: #6b7280;
  margin-bottom: 8px;
`;
const KpiNum = styled.div`
  font-size: 18px;
  font-weight: 700;
  color: ${({ theme }) => theme.text};
  margin-bottom: 4px;
`;
const KpiLabel = styled.div`
  font-size: 11px;
  color: #6b7280;
`;
const ContentGrid = styled.div`
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  @media (max-width: 900px) { grid-template-columns: 1fr; }
`;
const Section = styled.div`
  background: ${({ theme }) => theme.body};
  border: 1px solid ${({ theme }) => theme.bg4 || "#e5e7eb"};
  border-radius: 12px;
  padding: 16px;
`;
const SectionTitle = styled.div`
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 600;
  color: ${({ theme }) => theme.text};
  margin-bottom: 16px;
  flex-wrap: wrap;
`;
const CobradorTag = styled.span`
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  background: #3b82f615;
  border: 1px solid #3b82f640;
  border-radius: 20px;
  font-size: 11px;
  color: #3b82f6;
  font-weight: 500;
  button { background: none; border: none; cursor: pointer; color: #3b82f6; display: flex; align-items: center; padding: 0; }
`;
const CobradorList = styled.div`
  display: flex;
  flex-direction: column;
  gap: 10px;
`;
const CobradorCard = styled.div`
  border: 1px solid ${({ $selected, theme }) => ($selected ? "#3b82f6" : theme.bg4 || "#e5e7eb")};
  background: ${({ $selected }) => ($selected ? "#3b82f608" : "transparent")};
  border-radius: 10px;
  padding: 12px;
  transition: border-color 0.15s;
  &:hover { border-color: #3b82f680; }
`;
const CobradorHeader = styled.div`
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
  gap: 8px;
  cursor: pointer;
`;
const CobradorNombre = styled.div`
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  font-weight: 600;
  color: ${({ theme }) => theme.text};
`;
const MorosidadBadge = styled.span`
  padding: 2px 8px;
  border-radius: 20px;
  font-size: 11px;
  font-weight: 600;
  background: ${({ $pct }) => $pct >= 50 ? "#fef2f2" : $pct >= 20 ? "#fffbeb" : "#f0fdf4"};
  color: ${({ $pct }) => $pct >= 50 ? "#ef4444" : $pct >= 20 ? "#d97706" : "#16a34a"};
`;
const CobradorStats = styled.div`
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  margin-bottom: 10px;
  cursor: pointer;
`;
const StatItem = styled.div`
  text-align: center;
`;
const StatVal = styled.div`
  font-size: 13px;
  font-weight: 700;
  color: ${({ $color, theme }) => $color || theme.text};
`;
const StatLbl = styled.div`
  font-size: 10px;
  color: #9ca3af;
  margin-top: 1px;
`;
const MiniBar = styled.div`
  height: 4px;
  border-radius: 4px;
  background: #e5e7eb;
  margin-bottom: 8px;
  overflow: hidden;
  cursor: pointer;
`;
const MiniBarFill = styled.div`
  height: 100%;
  width: ${({ $pct }) => $pct}%;
  background: #3b82f6;
  border-radius: 4px;
`;
const CobradorActions = styled.div`
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
`;
const ActionLink = styled.div`
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 10px;
  color: #9ca3af;
  cursor: pointer;
  &:hover { color: #3b82f6; }
`;
const DetalleBtn = styled.button`
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 10px;
  border-radius: 6px;
  border: 1px solid #3b82f640;
  background: #3b82f610;
  color: #3b82f6;
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  &:hover { background: #3b82f620; }
`;
const LoadingMsg = styled.div`
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 32px;
  color: #6b7280;
  font-size: 13px;
  .spin { animation: spin 1s linear infinite; }
  @keyframes spin { to { transform: rotate(360deg); } }
`;
const EmptyMsg = styled.div`
  text-align: center;
  padding: 32px;
  color: #9ca3af;
  font-size: 13px;
`;
const ProdSummary = styled.div`
  font-size: 12px;
  color: #6b7280;
  margin-bottom: 12px;
  text-align: right;
`;
const BarChart = styled.div`
  display: flex;
  align-items: flex-end;
  gap: 4px;
  height: 180px;
  overflow-x: auto;
  padding-bottom: 24px;
  position: relative;
`;
const BarItem = styled.div`
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  min-width: 28px;
  flex: 1;
  height: 100%;
  position: relative;
  &:hover > div:first-child { display: flex; }
`;
const BarTooltip = styled.div`
  display: none;
  flex-direction: column;
  align-items: center;
  position: absolute;
  bottom: calc(100% - 20px);
  left: 50%;
  transform: translateX(-50%);
  background: #1f2937;
  color: white;
  padding: 4px 8px;
  border-radius: 6px;
  font-size: 10px;
  white-space: nowrap;
  z-index: 10;
  pointer-events: none;
  strong { font-size: 11px; }
  gap: 1px;
`;
const Bar = styled.div`
  width: 100%;
  height: ${({ $pct }) => Math.max($pct, 2)}%;
  background: #3b82f6;
  border-radius: 3px 3px 0 0;
  &:hover { background: #2563eb; }
`;
const BarDate = styled.div`
  font-size: 9px;
  color: #9ca3af;
  position: absolute;
  bottom: 0;
  white-space: nowrap;
  transform: rotate(-45deg);
  transform-origin: top left;
  left: 50%;
`;

// ─── Drawer Detalle ───────────────────────────────────────────────────────────
const DrawerOverlay = styled.div`
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  z-index: 1000;
  display: flex;
  justify-content: flex-end;
`;
const DrawerPanel = styled.div`
  width: 100%;
  max-width: 520px;
  background: ${({ theme }) => theme.body};
  border-left: 1px solid ${({ theme }) => theme.bg4 || "#e5e7eb"};
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
  animation: slideIn 0.2s ease;
  @keyframes slideIn {
    from { transform: translateX(100%); }
    to { transform: translateX(0); }
  }
`;
const DrawerHead = styled.div`
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid ${({ theme }) => theme.bg4 || "#e5e7eb"};
  flex-shrink: 0;
`;
const DrawerTitle = styled.div`
  display: flex;
  align-items: center;
  gap: 10px;
  color: ${({ theme }) => theme.text};
  font-size: 15px;
  font-weight: 700;
`;
const DrawerSubtitle = styled.div`
  font-size: 12px;
  color: #6b7280;
  font-weight: 400;
  margin-top: 1px;
`;
const DrawerActions = styled.div`
  display: flex;
  align-items: center;
  gap: 8px;
`;
const DrawerExportBtn = styled.button`
  width: 32px; height: 32px;
  border-radius: 8px;
  border: 1px solid #d1d5db;
  background: transparent;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  color: #22c55e;
  &:hover { background: #f0fdf4; }
`;
const DrawerCloseBtn = styled.button`
  width: 32px; height: 32px;
  border-radius: 8px;
  border: 1px solid #d1d5db;
  background: transparent;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  color: ${({ theme }) => theme.text};
  &:hover { background: ${({ theme }) => theme.bg3 || "#f3f4f6"}; }
`;
const DrawerPeriodo = styled.div`
  padding: 8px 20px;
  font-size: 11px;
  color: #9ca3af;
  border-bottom: 1px solid ${({ theme }) => theme.bg4 || "#e5e7eb"};
  flex-shrink: 0;
`;
const DrawerBody = styled.div`
  flex: 1;
  overflow-y: auto;
  padding: 16px 20px;
  display: flex;
  flex-direction: column;
  gap: 12px;
`;
const DrawerPagination = styled.div`
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 12px;
  border-top: 1px solid ${({ theme }) => theme.bg4 || "#e5e7eb"};
  font-size: 12px;
  color: #6b7280;
  flex-shrink: 0;
`;
const PageBtn = styled.button`
  width: 30px; height: 30px;
  border-radius: 6px;
  border: 1px solid #e5e7eb;
  background: transparent;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  &:disabled { opacity: 0.4; cursor: not-allowed; }
`;

// ─── Recibo cards dentro del drawer ──────────────────────────────────────────
const ReciboCard = styled.div`
  border: 1px solid ${({ theme }) => theme.bg4 || "#e5e7eb"};
  border-radius: 10px;
  padding: 12px;
  background: ${({ theme }) => theme.body};
`;
const ReciboHead = styled.div`
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  margin-bottom: 8px;
  gap: 8px;
`;
const ReciboBadge = styled.span`
  display: inline-block;
  background: #3b82f615;
  color: #3b82f6;
  border: 1px solid #3b82f640;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 600;
  padding: 1px 6px;
  margin-right: 6px;
`;
const ReciboFecha = styled.span`
  font-size: 11px;
  color: #9ca3af;
`;
const ReciboTotal = styled.div`
  text-align: right;
  font-size: 14px;
  font-weight: 700;
  color: ${({ theme }) => theme.text};
`;
const MoraTag = styled.div`
  font-size: 11px;
  color: #f88533;
  font-weight: 600;
`;
const ReciboCliente = styled.div`
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 600;
  color: ${({ theme }) => theme.text};
  margin-bottom: 4px;
  flex-wrap: wrap;
`;
const ReciboTel = styled.a`
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 11px;
  color: #3b82f6;
  font-weight: 400;
  text-decoration: none;
`;
const ReciboDescuento = styled.div`
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  color: #22c55e;
  margin-bottom: 6px;
`;
const DetalleCuotasList = styled.div`
  border-top: 1px solid ${({ theme }) => theme.bg4 || "#e5e7eb"};
  margin-top: 8px;
  padding-top: 6px;
  display: flex;
  flex-direction: column;
  gap: 6px;
`;
const DetalleCuotaRow = styled.div`
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
`;
const DetalleCuotaInfo = styled.div`
  display: flex;
  flex-direction: column;
  gap: 1px;
  font-size: 12px;
  color: ${({ theme }) => theme.text};
  span:first-child { font-weight: 600; }
  span:nth-child(2) { color: #9ca3af; font-size: 11px; }
`;
const ParcialTag = styled.span`
  font-size: 10px;
  background: #fef3c7;
  color: #d97706;
  border-radius: 4px;
  padding: 1px 5px;
  font-weight: 600;
`;
const DetalleCuotaMontos = styled.div`
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 1px;
  font-size: 12px;
  font-weight: 600;
  color: ${({ theme }) => theme.text};
  white-space: nowrap;
`;
