// module-dashboard.jsx — Painel (loads AFTER modules-core.jsx so it overrides)
// Draggable widget grid + 3 layout variants + quick actions + critical alerts + temporal comparison.
window.NA = window.NA || {};
window.NA.M = window.NA.M || {};
const _dna = window.NA;
const { useState: useStateD, useEffect: useEffectD, useRef: useRefD, useMemo: useMemoD } = React;

// ============================================================
// DASHBOARD V2
// ============================================================
function ModuleDashboard({ t, lang, setT, user }) {
  const [period, setPeriod] = useStateD(() => loadDP("nau_dash_period", "30d"));
  const [variant, setVariant] = useStateD(() => loadDP("nau_dash_variant", "executive"));
  const [customize, setCustomize] = useStateD(false);
  const [hidden, setHidden] = useStateD(() => loadDP("nau_dash_hidden", {}));
  const [showSale, setShowSale] = useStateD(false);
  const [saleForm, setSaleForm] = useStateD({ vehicleId: "", value: "" });
  const [order, setOrder] = useStateD(() => {
    const DEFAULT_ORDER = ["revenue_expense", "bank_ranking", "sales_heatmap", "funnel", "cliente", "settlements_due", "actions"];
    const saved = loadDP("nau_dash_order", null);
    const base = (saved || DEFAULT_ORDER).filter(id => id !== "mentees_ranking");
    const merged = [...base];
    DEFAULT_ORDER.forEach(id => { if (!merged.includes(id)) merged.push(id); });
    return merged;
  });

  useEffectD(() => saveDP("nau_dash_period", period), [period]);
  useEffectD(() => saveDP("nau_dash_variant", variant), [variant]);
  useEffectD(() => saveDP("nau_dash_hidden", hidden), [hidden]);
  useEffectD(() => saveDP("nau_dash_order", order), [order]);

  // Period config — drives every KPI's "vs previous"
  const periodCfg = {
    today: { label: lang === "pt" ? "Hoje" : "Today", prev: lang === "pt" ? "ontem" : "yesterday", days: 1, factor: 0.03 },
    "7d":  { label: lang === "pt" ? "Últimos 7 dias" : "Last 7 days", prev: lang === "pt" ? "7 dias anteriores" : "previous 7 days", days: 7, factor: 0.23 },
    "30d": { label: lang === "pt" ? "Últimos 30 dias" : "Last 30 days", prev: lang === "pt" ? "30 dias anteriores" : "previous 30 days", days: 30, factor: 1 },
    "90d": { label: lang === "pt" ? "Últimos 90 dias" : "Last 90 days", prev: lang === "pt" ? "trimestre anterior" : "previous quarter", days: 90, factor: 2.9 },
    mtd:   { label: lang === "pt" ? "Mês atual" : "Month to date", prev: lang === "pt" ? "mês anterior" : "previous month", days: 23, factor: 0.78 },
  };
  const pc = periodCfg[period] || periodCfg["30d"];

  const [analysesCount, setAnalysesCount] = useStateD(0);
  const [acceptedClients, setAcceptedClients] = useStateD([]);

  useEffectD(() => {
    (async () => {
      if (!_dna.db?.isConfigured()) { setAnalysesCount(0); setAcceptedClients([]); return; }
      await _dna.db.ensureSession();
      try {
        const rows = await _dna.db.listAnalyses();
        setAnalysesCount(rows.length);
        const accepted = await _dna.db.listAcceptedAnalyses();
        setAcceptedClients(accepted.map(r => _dna.db.rowToLegacyListItem(r)));
      } catch (e) { setAnalysesCount(0); setAcceptedClients([]); }
    })();
    const onRefresh = async () => {
      if (!_dna.db?.isConfigured()) return;
      try {
        const rows = await _dna.db.listAnalyses();
        setAnalysesCount(rows.length);
        const accepted = await _dna.db.listAcceptedAnalyses();
        setAcceptedClients(accepted.map(r => _dna.db.rowToLegacyListItem(r)));
      } catch (e) {}
    };
    window.addEventListener("na:analyses-changed", onRefresh);
    return () => window.removeEventListener("na:analyses-changed", onRefresh);
  }, []);

  // Compute KPIs from vehicles + base numbers, scaled by period factor
  const veh = _dna.vehicles;
  const stocked = veh.filter(v => ["in_stock", "overdue", "in_settlement", "settled"].includes(v.status));
  const stockedTotal = stocked.reduce((s, v) => s + v.purchasePrice, 0);
  const sold = veh.filter(v => v.status === "sold");
  const soldRevenue = sold.reduce((s, v) => s + (v.clientValue || v.purchasePrice * 1.15), 0);
  const expenseEst = veh.reduce((s, v) => s + (v.purchasePrice * 0.015 + (v.maintenance ? v.maintenance.length * 400 : 0)), 0);

  const baseRevenue = soldRevenue * pc.factor;
  const baseExpenses = expenseEst * pc.factor;
  const profit = baseRevenue - baseExpenses;
  const profitPrev = profit * 0.88;
  const revenuePrev = baseRevenue * 0.82;
  const stockPrev = stockedTotal * 1.05;
  const avgMargin = sold.length ? (profit / sold.length) : (stocked.length ? stockedTotal / stocked.length * 0.08 : 0);
  const avgMarginPrev = avgMargin * 0.92;
  const analyses = analysesCount;
  const oppCount = analyses + veh.filter(v => v.status !== "sold").length;
  const sales = sold.length || Math.max(1, Math.floor(veh.filter(v => v.status === "sold").length * pc.factor));
  const conversion = oppCount ? (sales / (sales + oppCount)) * 100 : 0;
  const conversionPrev = conversion * 0.84;
  const menteeRanking = _dna.getMenteeSalesRanking(veh, pc.factor);
  const canCloseSale = ["admin", "manager"].includes(user?.key || "admin");

  // Critical alerts
  const overdue = veh.filter(v => v.status === "overdue" || (v.parcels?.overdue || 0) > 0);
  const dueSoon = (_dna.AcquisitionFinance?.getSettlementsDueWithinDays(veh, 7) || []);
  const maintItemsByAcq = _dna.maintenanceItemsByAcq || {};
  const maintPending = _dna.AcquisitionMaintenance?.countMaintenanceAlerts?.(veh, maintItemsByAcq)
    ?? veh.filter(v => v.maintenance && v.maintenance.length > 0).length;
  const criticalCount = overdue.length + dueSoon.length + Math.min(3, maintPending);

  // Variant config — which widgets default-hidden + layout
  const variantConfig = {
    executive: { kpiSize: "lg", widgets: ["revenue_expense", "funnel", "cliente", "bank_ranking", "actions", "sales_heatmap"] },
    operational: { kpiSize: "md", widgets: ["actions", "settlements_due", "cliente", "sales_heatmap", "bank_ranking", "revenue_expense", "funnel"] },
    compact: { kpiSize: "sm", widgets: ["revenue_expense", "cliente", "bank_ranking", "sales_heatmap", "funnel", "actions"] },
  };
  const vc = variantConfig[variant];

  // Effective widget order: respect saved order but use variant order if not customized
  const widgetIds = (order || vc.widgets).filter(id => !hidden[id]);
  const allWidgets = ["revenue_expense", "bank_ranking", "sales_heatmap", "funnel", "cliente", "settlements_due", "actions"];
  const hiddenWidgets = allWidgets.filter(id => hidden[id]);

  // Drag state
  const [dragId, setDragId] = useStateD(null);
  const [overId, setOverId] = useStateD(null);

  const onDragStart = (id) => setDragId(id);
  const onDragOver = (e, id) => { e.preventDefault(); if (id !== dragId) setOverId(id); };
  const onDrop = (e, targetId) => {
    e.preventDefault();
    if (!dragId || dragId === targetId) { setDragId(null); setOverId(null); return; }
    const newOrder = [...widgetIds];
    const from = newOrder.indexOf(dragId);
    const to = newOrder.indexOf(targetId);
    if (from < 0 || to < 0) return;
    newOrder.splice(from, 1);
    newOrder.splice(to, 0, dragId);
    setOrder([...newOrder, ...hiddenWidgets]);
    setDragId(null); setOverId(null);
  };
  const onDragEnd = () => { setDragId(null); setOverId(null); };

  return (
    <div data-screen-label="Dashboard">
      {/* HEADER */}
      <div className="page-head">
        <div className="h">
          <h1><_dna.Icon name="layout-dashboard" size={20} /> {t("nav_dashboard")}</h1>
          <div className="sub">{lang === "pt" ? `Olá, ${user.name.split(" ")[0]} — visão ${pc.label.toLowerCase()}` : `Hi ${user.name.split(" ")[0]} — ${pc.label.toLowerCase()} view`}</div>
        </div>
        <div className="right">
          <_dna.Segmented value={variant} onChange={setVariant} options={[
            { value: "executive", label: lang === "pt" ? "Executivo" : "Executive" },
            { value: "operational", label: lang === "pt" ? "Operacional" : "Operational" },
            { value: "compact", label: lang === "pt" ? "Compacto" : "Compact" }
          ]} />
          <_dna.Segmented value={period} onChange={setPeriod} options={[
            { value: "today", label: lang === "pt" ? "Hoje" : "Today" },
            { value: "7d", label: "7d" },
            { value: "30d", label: "30d" },
            { value: "90d", label: "90d" },
            { value: "mtd", label: lang === "pt" ? "Mês" : "MTD" }
          ]} />
          <_dna.Button kind={customize ? "primary" : "default"} icon={customize ? "check" : "layout-grid"} onClick={() => setCustomize(c => !c)}>
            {customize ? (lang === "pt" ? "Concluir" : "Done") : (lang === "pt" ? "Personalizar" : "Customize")}
          </_dna.Button>
        </div>
      </div>

      {/* QUICK ACTIONS */}
      <div className="row gap-8 mb-16" style={{ flexWrap: "wrap" }}>
        <QuickAction icon="plus-circle" label={lang === "pt" ? "Nova análise" : "New analysis"} onClick={() => setT && setT({ module: "analysis" })} kind="primary" />
        <QuickAction icon="archive" label={lang === "pt" ? "Nova aquisição" : "New acquisition"} onClick={() => setT && setT({ module: "acquisitions" })} />
        <QuickAction icon="receipt" label={lang === "pt" ? "Registrar venda" : "Register sale"} onClick={() => canCloseSale ? setShowSale(true) : alert(lang === "pt" ? "Somente gerente fecha venda." : "Only managers can close sales.")} />
        <QuickAction icon="credit-card" label={lang === "pt" ? "Simular financiamento" : "Simulate financing"} onClick={() => setT && setT({ module: "financing" })} />
        <QuickAction icon="landmark" label={lang === "pt" ? "Lançar no caixa" : "Cashbook entry"} onClick={() => setT && setT({ module: "cashbook" })} />
        <QuickAction icon="wrench" label={lang === "pt" ? "Checklist manutenção" : "Maintenance check"} onClick={() => setT && setT({ module: "maintenance" })} />
      </div>

      {/* CRITICAL ALERTS */}
      {criticalCount > 0 && (
        <div className="card mb-16" style={{
          border: "1px solid var(--color-error-border)",
          background: "linear-gradient(90deg, var(--color-error-bg) 0%, transparent 100%)"
        }}>
          <div style={{ padding: "12px 16px", display: "grid", gridTemplateColumns: "auto 1fr auto", gap: 16, alignItems: "center" }}>
            <div style={{
              width: 40, height: 40, borderRadius: 8, background: "var(--color-error)", color: "#fff",
              display: "flex", alignItems: "center", justifyContent: "center"
            }}><_dna.Icon name="alert-triangle" size={20} /></div>
            <div>
              <div className="fw-600 fs-14">
                {lang === "pt"
                  ? `${criticalCount} pendência${criticalCount > 1 ? "s" : ""} crítica${criticalCount > 1 ? "s" : ""} precisa${criticalCount > 1 ? "m" : ""} de ação`
                  : `${criticalCount} critical issue${criticalCount > 1 ? "s" : ""} need${criticalCount > 1 ? "" : "s"} attention`}
              </div>
              <div className="text-muted fs-12 mt-8" style={{ display: "flex", gap: 16, flexWrap: "wrap" }}>
                {overdue.length > 0 && <span>● {overdue.length} {lang === "pt" ? "quitações em atraso" : "settlements overdue"}</span>}
                {dueSoon.length > 0 && <span>● {dueSoon.length} {lang === "pt" ? "vencem em 7 dias" : "due in 7 days"}</span>}
                <span>● {Math.min(3, maintPending)} {lang === "pt" ? "manutenções pendentes" : "maintenance pending"}</span>
                <span>● 2 {lang === "pt" ? "contratos sem assinatura" : "unsigned contracts"}</span>
              </div>
            </div>
            <_dna.Button kind="danger" icon="arrow-right" onClick={() => setT && setT({
              module: overdue.length ? "acquisitions" : maintPending ? "maintenance" : "management",
              acqFilter: overdue.length ? "overdue" : undefined,
              maintFilter: !overdue.length && maintPending ? "pending" : undefined,
            })}>
              {lang === "pt" ? "Ver tudo" : "View all"}
            </_dna.Button>
          </div>
        </div>
      )}

      {/* KPI CARDS */}
      <KPIGrid lang={lang} size={vc.kpiSize} pc={pc} kpis={[
        { id: "profit", label: lang === "pt" ? "Lucro real do período" : "Net profit", icon: "trending-up",
          value: profit, prev: profitPrev, money: true, dir: "up", accent: "success" },
        { id: "stock", label: lang === "pt" ? "Investimento em estoque" : "Stock investment", icon: "archive",
          value: stockedTotal, prev: stockPrev, money: true, dir: "down", accent: "primary", invert: true,
          hint: lang === "pt" ? `${stocked.length} veículos` : `${stocked.length} vehicles` },
        { id: "revenue", label: lang === "pt" ? "Faturamento bruto" : "Gross revenue", icon: "arrow-up-circle",
          value: baseRevenue, prev: revenuePrev, money: true, dir: "up" },
        { id: "margin", label: lang === "pt" ? "Margem média / veículo" : "Avg margin / vehicle", icon: "percent",
          value: avgMargin, prev: avgMarginPrev, money: true, dir: "up" },
        { id: "conv", label: lang === "pt" ? "Conversão de oportunidades" : "Opportunity conversion", icon: "git-merge",
          value: conversion, prev: conversionPrev, dir: "up", isPercent: true,
          hint: `${sales} ${lang === "pt" ? "vendas" : "sales"} / ${sales + oppCount} ${lang === "pt" ? "oport." : "opps"}` },
      ]} />

      <MenteesRankingBlock lang={lang} ranking={menteeRanking} t={t} />

      {/* CUSTOMIZE PANEL */}
      {customize && (
        <_dna.Card style={{ marginTop: 16, background: "var(--color-primary-bg)", borderColor: "var(--color-primary-border)" }}>
          <_dna.CardBody>
            <div className="row gap-8 mb-8">
              <_dna.Icon name="layout-grid" size={16} style={{ color: "var(--color-primary)" }} />
              <strong>{lang === "pt" ? "Modo personalizar" : "Customize mode"}</strong>
              <span className="text-muted fs-12">{lang === "pt" ? "— arraste widgets para reordenar, clique no olho para ocultar." : "— drag to reorder, click eye to hide."}</span>
            </div>
            <div className="row gap-8" style={{ flexWrap: "wrap" }}>
              {allWidgets.map(id => (
                <button key={id} onClick={() => setHidden(h => ({ ...h, [id]: !h[id] }))}
                  className={"btn sm " + (hidden[id] ? "default" : "primary")}>
                  <_dna.Icon name={hidden[id] ? "eye-off" : "eye"} size={11} />
                  {widgetLabel(id, lang)}
                </button>
              ))}
              <span className="spacer"></span>
              <_dna.Button size="sm" kind="ghost" icon="rotate-ccw" onClick={() => {
                setOrder(vc.widgets); setHidden({});
              }}>{lang === "pt" ? "Restaurar padrão" : "Reset"}</_dna.Button>
            </div>
          </_dna.CardBody>
        </_dna.Card>
      )}

      {/* WIDGET GRID */}
      <div style={{
        display: "grid",
        gridTemplateColumns: variant === "compact" ? "repeat(3, 1fr)" : "repeat(2, 1fr)",
        gap: 12, marginTop: 16
      }}>
        {widgetIds.map(id => (
          <WidgetSlot key={id} id={id} lang={lang} customize={customize}
            isOver={overId === id} isDragging={dragId === id}
            onDragStart={() => onDragStart(id)} onDragOver={(e) => onDragOver(e, id)} onDrop={(e) => onDrop(e, id)} onDragEnd={onDragEnd}
            onHide={() => setHidden(h => ({ ...h, [id]: true }))}
            span={getSpan(id, variant)}>
            <WidgetContent id={id} lang={lang} pc={pc} veh={veh} setT={setT} t={t} analysesCount={analysesCount} acceptedClients={acceptedClients} />
          </WidgetSlot>
        ))}
      </div>

      {widgetIds.length === 0 && (
        <_dna.Card padded style={{ marginTop: 16, textAlign: "center" }}>
          <_dna.Empty icon="layout-grid" title={lang === "pt" ? "Painel vazio" : "Empty dashboard"}
            message={lang === "pt" ? "Todos os widgets estão ocultos. Clique em Personalizar para reativá-los." : "All widgets are hidden. Click Customize to bring them back."} />
        </_dna.Card>
      )}
      <_dna.Modal open={showSale} onClose={() => setShowSale(false)} title={lang === "pt" ? "Registrar venda" : "Register sale"}
        footer={<>
          <_dna.Button kind="ghost" onClick={() => setShowSale(false)}>{t("common_cancel")}</_dna.Button>
          <_dna.Button kind="primary" disabled={!canCloseSale} onClick={async () => {
            if (!saleForm.vehicleId || !saleForm.value) return;
            try {
              if (_dna.db?.isConfigured() && _dna.AcquisitionFinance?.registerSale) {
                await _dna.AcquisitionFinance.registerSale(saleForm.vehicleId, Number(saleForm.value), user?.key, lang);
              } else {
                const v = veh.find(x => x.id === saleForm.vehicleId);
                await _dna.Cashbook.addEntry({
                  type: "in", category: lang === "pt" ? "Venda de veículo" : "Vehicle sale",
                  description: `${lang === "pt" ? "Venda" : "Sale"} — ${v?.plate || ""}`,
                  amount: Number(saleForm.value), acquisitionId: saleForm.vehicleId, origin: "auto", sourceRef: `sale:${saleForm.vehicleId}`,
                });
                const idx = (_dna.vehicles || []).findIndex(x => x.id === saleForm.vehicleId);
                if (idx >= 0) {
                  const arr = [..._dna.vehicles];
                  arr[idx] = { ...arr[idx], status: "sold", salePrice: Number(saleForm.value), soldAt: new Date().toLocaleDateString("pt-BR"), soldBy: user?.key };
                  window.NA.vehicles = arr;
                }
                window.dispatchEvent(new Event("na:acquisitions-changed"));
              }
              setShowSale(false);
              setSaleForm({ vehicleId: "", value: "" });
            } catch (err) { alert(err.message); }
          }}>{t("common_save")}</_dna.Button>
        </>}>
        <div className="col gap-12">
          <_dna.Field label={lang === "pt" ? "Veículo" : "Vehicle"} required>
            <_dna.Select value={saleForm.vehicleId} onChange={v => setSaleForm(f => ({ ...f, vehicleId: v }))} placeholder={lang === "pt" ? "Selecione" : "Select"}
              options={veh.filter(v => v.status !== "sold").map(v => ({ value: v.id, label: v.plate + " — " + v.brand }))} />
          </_dna.Field>
          <_dna.Field label={lang === "pt" ? "Valor da venda" : "Sale value"} required>
            <_dna.Input mono type="number" value={saleForm.value} onChange={v => setSaleForm(f => ({ ...f, value: v }))} />
          </_dna.Field>
        </div>
      </_dna.Modal>
    </div>
  );
}

// ============================================================
// HELPERS
// ============================================================
function loadDP(key, def) {
  try { const v = localStorage.getItem(key); return v ? JSON.parse(v) : def; } catch (e) { return def; }
}
function saveDP(key, v) { try { localStorage.setItem(key, JSON.stringify(v)); } catch (e) {} }

function widgetLabel(id, lang) {
  return ({
    revenue_expense: lang === "pt" ? "Receitas vs Despesas" : "Revenue vs Expenses",
    bank_ranking: lang === "pt" ? "Ranking de bancos" : "Bank ranking",
    sales_heatmap: lang === "pt" ? "Mapa de vendas" : "Sales heatmap",
    funnel: lang === "pt" ? "Funil de vendas" : "Sales funnel",
    cliente: "Cliente",
    actions: lang === "pt" ? "Ações imediatas" : "Immediate actions",
    settlements_due: lang === "pt" ? "Quitações vencendo (7d)" : "Settlements due (7d)",
  })[id] || id;
}
function getSpan(id, variant) {
  // span 2 = full width on the 2-col grid
  if (variant === "compact") {
    if (id === "actions" || id === "cliente" || id === "settlements_due") return 2;
    return 1;
  }
  if (id === "actions" || id === "cliente" || id === "settlements_due") return 2;
  return 1;
}

function QuickAction({ icon, label, onClick, kind = "default" }) {
  return (
    <button className={"btn " + kind} onClick={onClick} style={{ height: 36 }}>
      <_dna.Icon name={icon} size={14} />{label}
    </button>
  );
}

// ============================================================
// KPI GRID with temporal comparison
// ============================================================
function KPIGrid({ lang, size, pc, kpis }) {
  const cols = kpis.length;
  return (
    <div style={{ display: "grid", gridTemplateColumns: `repeat(${cols}, 1fr)`, gap: 12 }}>
      {kpis.map(k => {
        const delta = k.prev ? ((k.value - k.prev) / k.prev) * 100 : 0;
        const positive = k.invert ? delta < 0 : delta > 0;
        return (
          <div key={k.id} className="stat" style={{
            padding: size === "lg" ? "16px 18px" : size === "sm" ? "10px 12px" : "14px 16px",
            borderColor: k.accent === "success" ? "var(--color-success-border)" :
                         k.accent === "primary" ? "var(--color-primary-border)" : "var(--color-border-secondary)",
            background: k.accent === "success" ? "linear-gradient(180deg, var(--color-success-bg) 0%, transparent 70%)" :
                        k.accent === "primary" ? "linear-gradient(180deg, var(--color-primary-bg) 0%, transparent 70%)" :
                        "var(--color-bg-container)"
          }}>
            <div className="label"><_dna.Icon name={k.icon} size={size === "sm" ? 12 : 14} />{k.label}</div>
            <div className="num" style={{ fontSize: size === "lg" ? 30 : size === "sm" ? 20 : 24 }}>
              {k.isPercent
                ? <><span className="money">{k.value.toFixed(1)}</span><span style={{ fontSize: "0.55em", color: "var(--fg3)" }}>%</span></>
                : k.money ? <_dna.Money value={k.value} lang={lang} /> : _dna.fmtInt(k.value)}
            </div>
            {k.hint && <div className="hint">{k.hint}</div>}
            <div className="row gap-4" style={{ marginTop: 4, fontSize: 11 }}>
              <_dna.Icon name={positive ? "trending-up" : delta === 0 ? "minus" : "trending-down"} size={11}
                style={{ color: positive ? "var(--color-success)" : delta === 0 ? "var(--fg3)" : "var(--color-error)" }} />
              <span className="mono" style={{ color: positive ? "var(--color-success)" : delta === 0 ? "var(--fg3)" : "var(--color-error)", fontWeight: 500 }}>
                {delta > 0 ? "+" : ""}{delta.toFixed(1)}%
              </span>
              <span className="text-faint">vs {pc.prev}</span>
            </div>
          </div>
        );
      })}
    </div>
  );
}

// ============================================================
// WIDGET SLOT — draggable wrapper
// ============================================================
function WidgetSlot({ id, lang, customize, isOver, isDragging, onDragStart, onDragOver, onDrop, onDragEnd, onHide, children, span }) {
  return (
    <div
      draggable={customize}
      onDragStart={onDragStart}
      onDragOver={onDragOver}
      onDrop={onDrop}
      onDragEnd={onDragEnd}
      style={{
        gridColumn: `span ${span}`,
        opacity: isDragging ? 0.4 : 1,
        border: isOver ? "2px dashed var(--color-primary)" : "1px solid var(--color-border-secondary)",
        borderRadius: 8,
        background: "var(--color-bg-container)",
        position: "relative",
        transition: "opacity 0.15s, border-color 0.15s",
        cursor: customize ? "grab" : "default"
      }}
    >
      {customize && (
        <div style={{
          position: "absolute", top: 8, right: 8, zIndex: 5, display: "flex", gap: 4, alignItems: "center",
          background: "var(--color-bg-elevated)", border: "1px solid var(--color-border)", borderRadius: 6, padding: 2
        }}>
          <_dna.Icon name="grip-vertical" size={14} style={{ color: "var(--fg3)" }} />
          <button className="icon-btn-sq" style={{ width: 22, height: 22, border: "none" }} onClick={onHide}>
            <_dna.Icon name="eye-off" size={11} />
          </button>
        </div>
      )}
      {children}
    </div>
  );
}

// ============================================================
// WIDGET CONTENT DISPATCH
// ============================================================
function WidgetContent({ id, lang, pc, veh, setT, t, analysesCount, acceptedClients }) {
  switch (id) {
    case "revenue_expense": return <WRevenueExpense lang={lang} pc={pc} veh={veh} />;
    case "bank_ranking": return <WBankRanking lang={lang} pc={pc} veh={veh} />;
    case "sales_heatmap": return <WSalesHeatmap lang={lang} pc={pc} />;
    case "funnel": return <WFunnel lang={lang} pc={pc} veh={veh} setT={setT} analysesCount={analysesCount} />;
    case "cliente": return <WCliente lang={lang} clients={acceptedClients} setT={setT} t={t} />;
    case "actions": return <WActions lang={lang} veh={veh} setT={setT} />;
    case "settlements_due": return <WSettlementsDue lang={lang} veh={veh} setT={setT} />;
    default: return null;
  }
}

// ============================================================
// W: REVENUE VS EXPENSES — grouped bars
// ============================================================
function WRevenueExpense({ lang, pc, veh }) {
  const buckets = useMemoD(() => {
    const labels = pc.days <= 7
      ? (lang === "pt" ? ["Seg","Ter","Qua","Qui","Sex","Sáb","Dom"] : ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"])
      : pc.days <= 30
      ? (lang === "pt" ? ["Sem 1","Sem 2","Sem 3","Sem 4"] : ["Wk 1","Wk 2","Wk 3","Wk 4"])
      : (lang === "pt" ? ["Jan","Fev","Mar","Abr","Mai","Jun"] : ["Jan","Feb","Mar","Apr","May","Jun"]);
    const soldRev = veh.filter(v => v.status === "sold").reduce((s, v) => s + (v.clientValue || v.purchasePrice * 1.15), 0);
    const expEst = veh.reduce((s, v) => s + v.purchasePrice * 0.015, 0);
    const seeds = [0.6, 1.4, 0.8, 1.0, 1.2, 0.4, 0.3].slice(0, labels.length);
    const seedSum = seeds.reduce((a, b) => a + b, 0) || 1;
    return labels.map((l, i) => ({
      label: l,
      revenue: (soldRev * pc.factor / seedSum) * (seeds[i] || 1),
      expense: (expEst * pc.factor / seedSum) * (seeds[i] || 1) * 0.35,
    }));
  }, [pc.days, pc.factor, lang, veh]);
  const max = Math.max(...buckets.map(b => Math.max(b.revenue, b.expense)));

  return (
    <div>
      <div className="card-head">
        <h3><_dna.Icon name="bar-chart-3" size={14} />{lang === "pt" ? "Receitas vs Despesas" : "Revenue vs Expenses"}</h3>
        <div className="right">
          <div className="row gap-12 fs-11">
            <span className="row gap-4"><span style={{ width: 8, height: 8, background: "var(--color-success)", borderRadius: 2 }}></span>{lang === "pt" ? "Receita" : "Revenue"}</span>
            <span className="row gap-4"><span style={{ width: 8, height: 8, background: "var(--color-error)", borderRadius: 2 }}></span>{lang === "pt" ? "Despesa" : "Expense"}</span>
          </div>
        </div>
      </div>
      <div className="card-body">
        <div style={{ display: "flex", alignItems: "flex-end", gap: 12, height: 180 }}>
          {buckets.map((b, i) => (
            <div key={i} style={{ flex: 1, display: "flex", flexDirection: "column", alignItems: "center", gap: 4, height: "100%" }}>
              <div style={{ flex: 1, width: "100%", display: "flex", alignItems: "flex-end", gap: 3, justifyContent: "center" }}>
                <div title={_dna.fmtMoney(b.revenue, lang)} style={{ width: "40%", height: (b.revenue / max) * 100 + "%", background: "var(--color-success)", borderRadius: "3px 3px 0 0", minHeight: 2 }}></div>
                <div title={_dna.fmtMoney(b.expense, lang)} style={{ width: "40%", height: (b.expense / max) * 100 + "%", background: "var(--color-error)", borderRadius: "3px 3px 0 0", minHeight: 2 }}></div>
              </div>
              <div className="text-faint mono fs-11">{b.label}</div>
            </div>
          ))}
        </div>
        <div className="row jcsb mt-16" style={{ paddingTop: 12, borderTop: "1px dashed var(--color-border-secondary)" }}>
          <div><div className="text-faint fs-11">{lang === "pt" ? "Receita total" : "Total revenue"}</div>
            <_dna.Money value={buckets.reduce((s, b) => s + b.revenue, 0)} lang={lang} className="fw-600 fs-15" /></div>
          <div><div className="text-faint fs-11">{lang === "pt" ? "Despesa total" : "Total expense"}</div>
            <_dna.Money value={buckets.reduce((s, b) => s + b.expense, 0)} lang={lang} className="fw-600 fs-15" style={{ color: "var(--color-error)" }} /></div>
          <div><div className="text-faint fs-11">{lang === "pt" ? "Saldo" : "Net"}</div>
            <_dna.Money value={buckets.reduce((s, b) => s + b.revenue - b.expense, 0)} lang={lang}
              className="fw-600 fs-15" style={{ color: "var(--color-success)" }} /></div>
        </div>
      </div>
    </div>
  );
}

// ============================================================
// RANKING DE MENTORADOS — bloco único em lista
// ============================================================
function MenteesRankingBlock({ lang, ranking, t }) {
  if (!ranking || !ranking.length) return null;
  const totalVehicles = ranking.reduce((s, m) => s + m.count, 0);
  const totalValue = ranking.reduce((s, m) => s + m.value, 0);

  return (
    <_dna.Card style={{ marginTop: 16 }}>
      <_dna.CardHead
        icon="trophy"
        title={t("dash_mentees_ranking")}
        right={
          <span className="text-faint fs-11">
            {totalVehicles} {t("dash_vehicles_sold")} · <_dna.Money value={totalValue} lang={lang} className="mono" />
          </span>
        }
      />
      <_dna.CardBody style={{ padding: 0 }}>
        <table className="tbl">
          <thead>
            <tr>
              <th style={{ width: 48, paddingLeft: 16 }}>#</th>
              <th>{lang === "pt" ? "Mentorado" : "Mentee"}</th>
              <th style={{ width: 110, textAlign: "right" }}>{lang === "pt" ? "Veículos" : "Vehicles"}</th>
              <th style={{ width: 150, textAlign: "right", paddingRight: 16 }}>{t("dash_sale_value")}</th>
            </tr>
          </thead>
          <tbody>
            {ranking.map((m, i) => (
              <tr key={m.key} style={i === 0 ? { background: "var(--color-success-bg)" } : undefined}>
                <td className="mono fw-600 text-faint" style={{ paddingLeft: 16 }}>#{i + 1}</td>
                <td>
                  <div className="row gap-8">
                    <_dna.Avatar name={m.name} color={m.color} size="sm" />
                    <span className="fw-500">{m.name}</span>
                  </div>
                </td>
                <td className="mono fw-600" style={{ textAlign: "right" }}>{m.count}</td>
                <td className="mono fw-500" style={{ textAlign: "right", paddingRight: 16 }}>
                  <_dna.Money value={m.value} lang={lang} />
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </_dna.CardBody>
    </_dna.Card>
  );
}

// ============================================================
// W: BANK RANKING by margin
// ============================================================
function WBankRanking({ lang, pc, veh }) {
  const bankMap = {};
  veh.forEach(v => {
    if (!bankMap[v.bank]) bankMap[v.bank] = { deals: 0, margin: 0 };
    bankMap[v.bank].deals += 1;
    bankMap[v.bank].margin += Math.max(0, (v.clientValue || 0) - v.purchasePrice);
  });
  const banks = Object.keys(bankMap).map(name => {
    const b = bankMap[name];
    const avg = b.deals ? b.margin / b.deals : 0;
    return { name, deals: b.deals, avg, margin: 0 };
  }).sort((a, b) => b.avg - a.avg).slice(0, 6).map((b, i) => ({
    ...b,
    margin: Math.min(25, 8 + (6 - i) * 2.5),
    color: "var(--preset-orange)",
  }));
  if (!banks.length) banks.push({ name: "—", deals: 0, avg: 0, margin: 0, color: "var(--preset-orange)" });
  const max = Math.max(...banks.map(b => b.avg), 1);

  return (
    <div>
      <div className="card-head">
        <h3><_dna.Icon name="trophy" size={14} />{lang === "pt" ? "Ranking de bancos por margem" : "Bank ranking by margin"}</h3>
        <div className="right"><span className="text-faint fs-11">{lang === "pt" ? "margem média por venda" : "avg margin per sale"}</span></div>
      </div>
      <div className="card-body">
        <div className="col gap-8">
          {banks.map((b, i) => (
            <div key={b.name} style={{ display: "grid", gridTemplateColumns: "24px 80px 1fr 100px 60px", gap: 10, alignItems: "center" }}>
              <span className="mono fs-12 fw-600 text-faint">#{i + 1}</span>
              <span className="fw-500 fs-13">{b.name}</span>
              <div className="progress" style={{ height: 16, position: "relative" }}>
                <div style={{ height: "100%", width: (b.avg / max) * 100 + "%",
                  background: i === 0 ? "var(--color-success)" : i < 3 ? "var(--preset-orange)" : "var(--color-fill)",
                  borderRadius: 3 }}></div>
              </div>
              <_dna.Money value={b.avg} lang={lang} className="mono fs-12 fw-500" style={{ textAlign: "right" }} />
              <span className="mono fs-11" style={{ color: b.margin > 15 ? "var(--color-success)" : "var(--fg2)", textAlign: "right" }}>
                {b.margin.toFixed(1)}%
              </span>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

// ============================================================
// W: SALES HEATMAP — day of week × week
// ============================================================
function WSalesHeatmap({ lang, pc }) {
  const days = lang === "pt" ? ["Seg","Ter","Qua","Qui","Sex","Sáb","Dom"] : ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"];
  const weeks = useMemoD(() => Array.from({ length: 5 }, (_, w) => {
    const today = new Date();
    return days.map((_, d) => {
      const seed = (w * 7 + d);
      const isWeekend = d >= 5;
      const isFuture = w === 4 && d >= today.getDay();
      if (isFuture) return null;
      const base = isWeekend ? 0.4 : 1.2;
      // pseudo-random but stable per cell
      const r = ((seed * 9301 + 49297) % 233280) / 233280;
      return Math.floor(base * r * 6);
    });
  }), [days.join(",")]);

  const maxV = Math.max(...weeks.flat().filter(v => v !== null));
  const colorFor = (v) => {
    if (v === null) return "transparent";
    if (v === 0) return "var(--color-fill-quaternary)";
    const ratio = v / (maxV || 1);
    return `rgba(82,196,26,${0.2 + ratio * 0.75})`;
  };

  const totals = days.map((_, d) => weeks.reduce((s, w) => s + (w[d] || 0), 0));
  const bestDay = totals.indexOf(Math.max(...totals));
  const totalSales = weeks.flat().filter(v => v).reduce((s, v) => s + v, 0);

  return (
    <div>
      <div className="card-head">
        <h3><_dna.Icon name="calendar-days" size={14} />{lang === "pt" ? "Heatmap de vendas" : "Sales heatmap"}</h3>
        <div className="right">
          <span className="chip mono">{totalSales} {lang === "pt" ? "vendas" : "sales"}</span>
          <span className="text-faint fs-11">— {lang === "pt" ? "melhor dia:" : "best day:"} <b>{days[bestDay]}</b></span>
        </div>
      </div>
      <div className="card-body">
        <div style={{ display: "grid", gridTemplateColumns: "40px repeat(5, 1fr)", gap: 4, alignItems: "center" }}>
          <span></span>
          {[1, 2, 3, 4, 5].map(w => <span key={w} className="text-faint fs-11 mono" style={{ textAlign: "center" }}>S{w}</span>)}
          {days.map((d, di) => (
            <React.Fragment key={d}>
              <span className="text-faint fs-11 mono">{d}</span>
              {weeks.map((w, wi) => (
                <div key={wi} title={w[di] !== null ? `${w[di]} ${lang === "pt" ? "vendas" : "sales"}` : ""}
                  style={{
                    aspectRatio: "1.5", background: colorFor(w[di]), borderRadius: 4,
                    border: "1px solid " + (w[di] === maxV && maxV > 0 ? "var(--color-success)" : "var(--color-border-secondary)"),
                    display: "flex", alignItems: "center", justifyContent: "center",
                    fontFamily: "var(--font-mono)", fontSize: 11, fontWeight: 600,
                    color: w[di] === null ? "transparent" : w[di] === 0 ? "var(--fg3)" : w[di] > maxV / 2 ? "#fff" : "var(--green-9)"
                  }}>{w[di]}</div>
              ))}
            </React.Fragment>
          ))}
        </div>
        <div className="row jcsb mt-16" style={{ paddingTop: 8, borderTop: "1px dashed var(--color-border-secondary)" }}>
          <span className="text-faint fs-11">{lang === "pt" ? "Menos" : "Less"}</span>
          <div className="row gap-1">
            {[0, 1, 2, 3, 4, 5].map(v => <div key={v} style={{ width: 14, height: 14, background: colorFor(v || 0.01), borderRadius: 3, border: "1px solid var(--color-border-secondary)" }}></div>)}
          </div>
          <span className="text-faint fs-11">{lang === "pt" ? "Mais" : "More"}</span>
        </div>
      </div>
    </div>
  );
}

// ============================================================
// W: SALES FUNNEL
// ============================================================
function WFunnel({ lang, pc, veh, setT, analysesCount }) {
  const analyses = analysesCount || 0;
  const acquired = veh.filter(v => v.status !== "sold").length;
  const stock = veh.filter(v => ["in_stock", "overdue", "in_settlement", "settled"].includes(v.status)).length;
  const soldN = veh.filter(v => v.status === "sold").length;
  const stages = [
    { key: "lead", label: lang === "pt" ? "Captação" : "Lead", count: acquired + analyses, color: "var(--blue-3)" },
    { key: "analysis", label: lang === "pt" ? "Análise" : "Analysis", count: analyses + veh.filter(v => v.status === "in_process").length, color: "var(--blue-5)" },
    { key: "acquired", label: lang === "pt" ? "Adquirido" : "Acquired", count: acquired, color: "var(--blue-6)" },
    { key: "stock", label: lang === "pt" ? "Em estoque" : "In stock", count: stock, color: "var(--blue-7)" },
    { key: "sold", label: lang === "pt" ? "Vendido" : "Sold", count: soldN, color: "var(--color-success)" },
  ];
  const max = stages[0].count;

  return (
    <div>
      <div className="card-head">
        <h3><_dna.Icon name="filter" size={14} />{lang === "pt" ? "Funil: captação → venda" : "Funnel: lead → sale"}</h3>
        <div className="right">
          <span className="text-faint fs-11">{lang === "pt" ? "conversão geral" : "overall conv."}</span>
          <span className="chip mono" style={{ background: "var(--color-success-bg)", color: "var(--green-7)" }}>
            {((stages[stages.length - 1].count / stages[0].count) * 100).toFixed(1)}%
          </span>
        </div>
      </div>
      <div className="card-body">
        <div className="col gap-4">
          {stages.map((s, i) => {
            const width = (s.count / max) * 100;
            const dropoff = i > 0 ? stages[i - 1].count - s.count : 0;
            const conv = i > 0 ? (s.count / stages[i - 1].count) * 100 : 100;
            return (
              <div key={s.key}>
                <div className="row jcsb mb-8" style={{ fontSize: 12 }}>
                  <span className="row gap-8">
                    <span style={{ width: 8, height: 8, background: s.color, borderRadius: 2 }}></span>
                    <span className="fw-500">{s.label}</span>
                    {i > 0 && <span className="text-faint fs-11">{conv.toFixed(0)}% {lang === "pt" ? "de cima" : "from above"}</span>}
                  </span>
                  <span className="mono fw-600">{s.count}</span>
                </div>
                <div style={{ position: "relative", height: 28, background: "var(--color-fill-quaternary)", borderRadius: 4, overflow: "hidden" }}>
                  <div style={{
                    position: "absolute", left: "50%", transform: "translateX(-50%)",
                    width: width + "%", height: "100%", background: s.color,
                    transition: "width 0.4s var(--ease-out)"
                  }}></div>
                </div>
                {dropoff > 0 && (
                  <div className="text-faint fs-11 mono" style={{ textAlign: "right", marginTop: 2 }}>
                    − {dropoff} {lang === "pt" ? "perda" : "dropped"}
                  </div>
                )}
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}

// ============================================================
// W: CLIENTE — oportunidades aceitas com dados do vendedor
// ============================================================
function WCliente({ lang, clients, setT, t }) {
  const fmtDate = (iso) => {
    if (!iso) return "—";
    try { return new Date(iso).toLocaleDateString("pt-BR"); } catch (e) { return "—"; }
  };

  return (
    <div>
      <div className="card-head">
        <h3><_dna.Icon name="user" size={14} />Cliente</h3>
        <div className="right">
          <span className="chip mono">{clients.length}</span>
          <_dna.Button kind="ghost" size="sm" icon="external-link" onClick={() => setT && setT({ module: "opportunities" })}>
            {lang === "pt" ? "Ver oportunidades" : "View opportunities"}
          </_dna.Button>
        </div>
      </div>
      <div className="card-body" style={{ padding: clients.length ? 0 : undefined }}>
        {clients.length === 0 ? (
          <_dna.Empty icon="user" title={lang === "pt" ? "Nenhum cliente aceito ainda" : "No accepted clients yet"}
            message={lang === "pt" ? "Aceite uma oportunidade pendente para registrar o vendedor aqui." : "Accept a pending opportunity to register the seller here."} />
        ) : (
          <table className="tbl">
            <thead><tr>
              <th>{lang === "pt" ? "Vendedor" : "Seller"}</th>
              <th>{t("common_plate")}</th>
              <th>{lang === "pt" ? "Veículo" : "Vehicle"}</th>
              <th>{lang === "pt" ? "Contato" : "Contact"}</th>
              <th>{lang === "pt" ? "Lucro est." : "Est. profit"}</th>
              <th>{lang === "pt" ? "Aceito em" : "Accepted on"}</th>
            </tr></thead>
            <tbody>{clients.map(c => (
              <tr key={c.id} style={{ cursor: "pointer" }} onClick={() => setT && setT({ module: "analysis", analysisId: c.id })}>
                <td className="fw-600">{c.sellerName || "—"}</td>
                <td className="mono">{c.plate}</td>
                <td><div className="fw-500">{c.brand}</div><div className="text-faint fs-11">{c.model}</div></td>
                <td className="fs-12">
                  {c.sellerPhone && <div className="mono">{c.sellerPhone}</div>}
                  {c.sellerEmail && <div className="text-faint">{c.sellerEmail}</div>}
                  {!c.sellerPhone && !c.sellerEmail && "—"}
                </td>
                <td className="mono"><_dna.Money value={c.expectedProfit} lang={lang} className="text-success" /></td>
                <td className="mono fs-12">{fmtDate(c.statusChangedAt)}</td>
              </tr>
            ))}</tbody>
          </table>
        )}
      </div>
    </div>
  );
}

// ============================================================
// W: ACTIONS REQUIRED TABLE
// ============================================================
function WActions({ lang, veh, setT }) {
  const actions = useMemoD(() => {
    const list = [];
    const itemsByAcq = window.NA?.maintenanceItemsByAcq || {};
    const AM = window.NA?.AcquisitionMaintenance;
    veh.filter(v => v.status === "overdue").forEach(v => {
      list.push({
        id: v.id + "_pay", urgency: "high", icon: "credit-card",
        title: lang === "pt" ? "Quitar parcelas em atraso" : "Pay overdue installments",
        vehicle: v, detail: `${v.parcels.overdue} ${lang === "pt" ? "parcela(s) atrasada(s)" : "overdue installment(s)"} — ${v.bank}`,
        amount: v.purchasePrice * 0.05, action: "settle"
      });
    });
    veh.filter(v => AM?.hasMaintenancePending?.(v, itemsByAcq[v.id] || [])).slice(0, 2).forEach(v => {
      const items = itemsByAcq[v.id] || [];
      const prog = AM?.computeMaintenanceProgress?.(items, AM?.vehicleMaintenanceFlags?.(v));
      list.push({
        id: v.id + "_maint", urgency: "med", icon: "wrench",
        title: lang === "pt" ? "Concluir manutenção" : "Finish maintenance",
        vehicle: v, detail: (prog?.pendingLabels || []).slice(0, 3).join(", ") || v.plate,
        amount: null, action: "maint"
      });
    });
    list.push({
      id: "doc1", urgency: "med", icon: "file-signature",
      title: lang === "pt" ? "Assinar contrato de venda" : "Sign sale contract",
      vehicle: veh[12] || veh[0], detail: lang === "pt" ? "Cliente: dione Alves" : "Client: dione Alves",
      amount: null, action: "doc"
    });
    list.push({
      id: "doc2", urgency: "low", icon: "file-text",
      title: lang === "pt" ? "Anexar CRLV" : "Attach registration",
      vehicle: veh[1] || veh[0], detail: lang === "pt" ? "CRLV pendente desde 14/05" : "Pending since 05/14",
      amount: null, action: "doc"
    });
    return list.slice(0, 6);
  }, [veh, lang]);

  return (
    <div>
      <div className="card-head">
        <h3><_dna.Icon name="alert-circle" size={14} />{lang === "pt" ? "Ações imediatas" : "Immediate actions"}</h3>
        <div className="right">
          <_dna.Tag kind="error">{actions.filter(a => a.urgency === "high").length} {lang === "pt" ? "urgentes" : "urgent"}</_dna.Tag>
          <_dna.Tag kind="warning">{actions.filter(a => a.urgency === "med").length} {lang === "pt" ? "média" : "med"}</_dna.Tag>
          <_dna.Tag kind="default">{actions.filter(a => a.urgency === "low").length} {lang === "pt" ? "baixa" : "low"}</_dna.Tag>
        </div>
      </div>
      <div className="card-body" style={{ padding: 0 }}>
        <table className="tbl">
          <thead><tr>
            <th></th>
            <th>{lang === "pt" ? "Ação" : "Action"}</th>
            <th>{lang === "pt" ? "Veículo" : "Vehicle"}</th>
            <th>{lang === "pt" ? "Detalhe" : "Detail"}</th>
            <th style={{ textAlign: "right" }}>{lang === "pt" ? "Valor" : "Amount"}</th>
            <th></th>
          </tr></thead>
          <tbody>
            {actions.map(a => (
              <tr key={a.id}>
                <td><span style={{
                  display: "inline-flex", alignItems: "center", justifyContent: "center",
                  width: 26, height: 26, borderRadius: 6,
                  background: a.urgency === "high" ? "var(--color-error-bg)" : a.urgency === "med" ? "var(--color-warning-bg)" : "var(--color-fill-tertiary)",
                  color: a.urgency === "high" ? "var(--color-error)" : a.urgency === "med" ? "var(--color-warning)" : "var(--fg2)"
                }}><_dna.Icon name={a.icon} size={13} /></span></td>
                <td className="fw-500 fs-13">{a.title}</td>
                <td><span className="chip mono">{a.vehicle.plate}</span> <span className="text-faint fs-11">{a.vehicle.brand}</span></td>
                <td className="text-muted fs-12">{a.detail}</td>
                <td className="mono" style={{ textAlign: "right" }}>{a.amount ? <_dna.Money value={a.amount} lang={lang} /> : <span className="text-faint">—</span>}</td>
                <td><_dna.Button kind="ghost" size="sm" icon="arrow-right" onClick={() => setT && setT({
                  module: a.action === "settle" ? "acquisitions" : a.action === "maint" ? "maintenance" : "contracts",
                  acquisitionId: a.action === "settle" || a.action === "maint" ? a.vehicle.id : undefined,
                  acqFilter: a.action === "settle" ? "overdue" : undefined,
                  maintFilter: a.action === "maint" ? "pending" : undefined,
                })}>{lang === "pt" ? "Resolver" : "Resolve"}</_dna.Button></td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}

function WSettlementsDue({ lang, veh, setT }) {
  const AF = _dna.AcquisitionFinance;
  const due = useMemoD(() => AF?.getSettlementsDueWithinDays(veh, 7) || [], [veh, AF]);
  return (
    <div>
      <div className="card-head">
        <h3><_dna.Icon name="calendar-clock" size={14} />{lang === "pt" ? "Quitações vencendo nos próximos 7 dias" : "Settlements due in 7 days"}</h3>
        <div className="right">
          <_dna.Tag kind={due.length ? "warning" : "success"}>{due.length}</_dna.Tag>
          {due.length > 0 && setT && (
            <_dna.Button kind="ghost" size="sm" icon="filter" onClick={() => setT({ module: "acquisitions", acqFilter: "due_7d" })}>
              {lang === "pt" ? "Ver filtrado" : "View filtered"}
            </_dna.Button>
          )}
        </div>
      </div>
      <div className="card-body" style={{ padding: due.length ? 0 : undefined }}>
        {due.length === 0 ? (
          <_dna.Empty icon="check-circle-2" title={lang === "pt" ? "Nenhuma quitação próxima" : "No upcoming settlements"} />
        ) : (
          <table className="tbl">
            <thead><tr>
              <th>{lang === "pt" ? "Placa" : "Plate"}</th>
              <th>{lang === "pt" ? "Veículo" : "Vehicle"}</th>
              <th>{lang === "pt" ? "Vencimento" : "Due"}</th>
              <th>{lang === "pt" ? "Parcela" : "Installment"}</th>
              <th></th>
            </tr></thead>
            <tbody>{due.map(v => (
              <tr key={v.id}>
                <td className="mono fw-600">{v.plate}</td>
                <td className="fs-12">{v.brand} {String(v.model || "").slice(0, 24)}</td>
                <td className="mono fs-12">{AF?.fmtPtDate(AF?.getNextInstallmentDue(v))}</td>
                <td className="mono fs-12">{v.parcels?.paid || 0}/{v.parcels?.total || 0}</td>
                <td>{setT && (
                  <_dna.Button kind="ghost" size="sm" icon="external-link" onClick={() => setT({ module: "acquisitions", acquisitionId: v.id })}>
                    {lang === "pt" ? "Abrir" : "Open"}
                  </_dna.Button>
                )}</td>
              </tr>
            ))}</tbody>
          </table>
        )}
      </div>
    </div>
  );
}

window.NA.M.dashboard = ModuleDashboard;
