/* global React, Icon, Badge, Card, Button, brl, Stat, tempoAtras, ChartCanvas */

// ─── Smart Alerts (3 priorities) ──────────────────────────────────────────────
function SmartAlerts({ onNav }) {
  const [alertas, setAlertas] = React.useState(null);
  const [collapsed, setCollapsed] = React.useState(false);

  React.useEffect(() => {
    if (!window.tmSupabase) return;
    const hoje = new Date();
    const em7dias = new Date(hoje.getTime() + 7 * 86400000);
    const hojeISO = hoje.toISOString().slice(0, 10);
    const em7diasISO = em7dias.toISOString().slice(0, 10);
    const ha3dias = new Date(hoje.getTime() - 3 * 86400000).toISOString();
    const ha5dias = new Date(hoje.getTime() - 5 * 86400000).toISOString();

    Promise.all([
      window.tmSupabase.from('contas_receber').select('*')
        .eq('status', 'Em aberto').lt('vencimento', hojeISO),
      window.tmSupabase.from('contas_receber').select('*')
        .eq('status', 'Em aberto').gte('vencimento', hojeISO).lte('vencimento', em7diasISO),
      window.tmSupabase.from('produtos').select('nome, sku, estoque, estoque_minimo, preco_custo')
        .or('estoque.eq.0,estoque.is.null'),
      window.tmSupabase.from('produtos').select('nome, sku, estoque, estoque_minimo, preco_custo')
        .gt('estoque', 0).lte('estoque', 5),
      window.tmSupabase.from('pedidos').select('numero, cliente_nome, created_at, status')
        .eq('status', 'Em andamento').lt('created_at', ha3dias),
      window.tmSupabase.from('produtos').select('nome, sku, preco_custo')
        .or('preco_custo.eq.0,preco_custo.is.null'),
    ]).then(([vencRes, proxRes, semRes, baixoRes, pedRes, semCustoRes]) => {
      const criticos = [];
      const atencao = [];
      const oportunidades = [];

      // CRITICOS
      (semRes.data || []).forEach(p => {
        criticos.push({
          icon: 'alert-circle', color: 'var(--tm-danger)',
          text: `Sem estoque: ${p.nome} (${p.sku})`,
          detail: 'Estoque zerado',
          nav: 'produtos/lista',
        });
      });
      (vencRes.data || []).forEach(c => {
        const saldo = (parseFloat(c.valor) || 0) - (parseFloat(c.valor_recebido) || 0);
        if (saldo > 1000) {
          criticos.push({
            icon: 'alert-triangle', color: 'var(--tm-danger)',
            text: `Conta vencida: ${c.referencia || c.cliente_nome} — R$ ${brl(saldo)}`,
            detail: `Venc. ${new Date(c.vencimento).toLocaleDateString('pt-BR')}`,
            nav: 'financeiro/contas-receber',
          });
        } else {
          atencao.push({
            icon: 'alert-triangle', color: 'var(--tm-warning)',
            text: `Conta vencida: ${c.referencia || c.cliente_nome} — R$ ${brl(saldo)}`,
            detail: `Venc. ${new Date(c.vencimento).toLocaleDateString('pt-BR')}`,
            nav: 'financeiro/contas-receber',
          });
        }
      });
      (pedRes.data || []).filter(p => new Date(p.created_at) < new Date(ha5dias)).forEach(p => {
        criticos.push({
          icon: 'truck', color: 'var(--tm-danger)',
          text: `Pedido ${p.numero} travado há +5 dias`,
          detail: p.cliente_nome,
          nav: 'pedidos/abertos',
        });
      });

      // ATENCAO
      (baixoRes.data || []).forEach(p => {
        atencao.push({
          icon: 'package', color: 'var(--tm-warning)',
          text: `Estoque baixo: ${p.nome} (${p.sku})`,
          detail: `${p.estoque} un. restantes`,
          nav: 'produtos/lista',
        });
      });
      (proxRes.data || []).forEach(c => {
        atencao.push({
          icon: 'clock', color: 'var(--tm-warning)',
          text: `Vence em breve: ${c.referencia || c.cliente_nome} — R$ ${brl((parseFloat(c.valor) || 0) - (parseFloat(c.valor_recebido) || 0))}`,
          detail: `Venc. ${new Date(c.vencimento).toLocaleDateString('pt-BR')}`,
          nav: 'financeiro/contas-receber',
        });
      });
      (pedRes.data || []).filter(p => new Date(p.created_at) >= new Date(ha5dias)).forEach(p => {
        atencao.push({
          icon: 'truck', color: 'var(--tm-warning)',
          text: `Pedido ${p.numero} parado há +3 dias`,
          detail: p.cliente_nome,
          nav: 'pedidos/abertos',
        });
      });
      (semCustoRes.data || []).forEach(p => {
        atencao.push({
          icon: 'circle-alert', color: 'var(--tm-warning)',
          text: `Sem custo cadastrado: ${p.nome}`,
          detail: p.sku,
          nav: 'produtos/lista',
        });
      });

      setAlertas({ criticos, atencao, oportunidades });
    });
  }, []);

  if (alertas === null) {
    return (
      <Card title="Alertas inteligentes"
            action={<span className="muted" style={{ fontSize: 11.5 }}>Carregando...</span>}>
        <div style={{ padding: "24px 16px", textAlign: "center", color: "var(--tm-fg-3)" }}>
          <Icon name="loader" size={20} style={{ opacity: 0.4 }} />
        </div>
      </Card>
    );
  }

  const total = alertas.criticos.length + alertas.atencao.length + alertas.oportunidades.length;

  if (total === 0) {
    return (
      <Card title="Alertas inteligentes"
            action={<span className="muted" style={{ fontSize: 11.5 }}>Atualizado agora</span>}>
        <div style={{ padding: "24px 16px", textAlign: "center", color: "var(--tm-fg-3)" }}>
          <Icon name="check-circle" size={28} style={{ opacity: 0.3, marginBottom: 10 }} />
          <div style={{ fontSize: 13.5 }}>Tudo em ordem!</div>
          <div style={{ fontSize: 12, marginTop: 4 }}>Nenhuma atenção pendente no momento</div>
        </div>
      </Card>
    );
  }

  const toggleBtn = (
    <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
      {alertas.criticos.length > 0 && <Badge tone="danger">{alertas.criticos.length} crítico{alertas.criticos.length !== 1 ? 's' : ''}</Badge>}
      {alertas.atencao.length > 0 && <Badge tone="warning">{alertas.atencao.length} atenção</Badge>}
      {alertas.oportunidades.length > 0 && <Badge tone="info">{alertas.oportunidades.length} oportunidade{alertas.oportunidades.length !== 1 ? 's' : ''}</Badge>}
      <button
        onClick={() => setCollapsed(c => !c)}
        title={collapsed ? 'Expandir' : 'Recolher'}
        style={{
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          width: 26, height: 26, borderRadius: 6, border: 'none', cursor: 'pointer',
          background: 'var(--tm-bg-3)', color: 'var(--tm-fg-3)', transition: 'all 0.15s',
        }}
      >
        <Icon name={collapsed ? 'chevron-down' : 'chevron-up'} size={14} />
      </button>
    </div>
  );

  if (collapsed) {
    return (
      <Card title="Alertas inteligentes" action={toggleBtn}>
        <div style={{
          display: 'flex', alignItems: 'center', gap: 12, padding: '10px 16px',
          fontSize: 12.5, color: 'var(--tm-fg-3)',
        }}>
          {alertas.criticos.length > 0 && (
            <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4, color: 'var(--tm-danger)' }}>
              <Icon name="alert-circle" size={13} /> {alertas.criticos.length} crítico{alertas.criticos.length !== 1 ? 's' : ''}
            </span>
          )}
          {alertas.atencao.length > 0 && (
            <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4, color: 'var(--tm-warning)' }}>
              <Icon name="clock" size={13} /> {alertas.atencao.length} aviso{alertas.atencao.length !== 1 ? 's' : ''}
            </span>
          )}
          {alertas.oportunidades.length > 0 && (
            <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4, color: 'var(--tm-info, #5B9BD5)' }}>
              <Icon name="trending-up" size={13} /> {alertas.oportunidades.length} oportunidade{alertas.oportunidades.length !== 1 ? 's' : ''}
            </span>
          )}
        </div>
      </Card>
    );
  }

  const renderGroup = (items, groupLabel, groupIcon, groupColor, maxShow) => {
    if (items.length === 0) return null;
    const shown = items.slice(0, maxShow || 6);
    return (
      <div>
        <div style={{
          display: 'flex', alignItems: 'center', gap: 6, padding: '8px 16px',
          fontSize: 10.5, fontWeight: 600, letterSpacing: '0.08em', textTransform: 'uppercase',
          color: groupColor, background: 'var(--tm-bg-2)', borderBottom: '1px solid var(--tm-line-1)',
        }}>
          <Icon name={groupIcon} size={12} /> {groupLabel}
        </div>
        {shown.map((a, i) => (
          <div
            key={i}
            onClick={() => a.nav && onNav(a.nav)}
            style={{
              display: 'flex', alignItems: 'center', gap: 10, padding: '9px 16px',
              borderBottom: '1px solid var(--tm-line-1)',
              cursor: a.nav ? 'pointer' : 'default', transition: 'background .12s',
            }}
            onMouseEnter={e => { if (a.nav) e.currentTarget.style.background = 'var(--tm-bg-2)'; }}
            onMouseLeave={e => { e.currentTarget.style.background = 'transparent'; }}
          >
            <Icon name={a.icon} size={15} style={{ color: a.color, flexShrink: 0 }} />
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: 12.5, color: 'var(--tm-fg-1)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                {a.text}
              </div>
              {a.detail && <div style={{ fontSize: 11, color: 'var(--tm-fg-4)', marginTop: 1 }}>{a.detail}</div>}
            </div>
            {a.nav && <Icon name="chevron-right" size={13} style={{ color: 'var(--tm-fg-4)', flexShrink: 0 }} />}
          </div>
        ))}
        {items.length > (maxShow || 6) && (
          <div style={{ padding: '6px 16px', fontSize: 11, color: 'var(--tm-fg-4)', textAlign: 'center', borderBottom: '1px solid var(--tm-line-1)' }}>
            +{items.length - (maxShow || 6)} outros
          </div>
        )}
      </div>
    );
  };

  return (
    <Card title="Alertas inteligentes" action={toggleBtn}>
      <div style={{ display: 'flex', flexDirection: 'column' }}>
        {renderGroup(alertas.criticos, 'Crítico', 'alert-circle', 'var(--tm-danger)', 5)}
        {renderGroup(alertas.atencao, 'Atenção', 'clock', 'var(--tm-warning)', 5)}
        {renderGroup(alertas.oportunidades, 'Oportunidade', 'trending-up', 'var(--tm-info, #5B9BD5)', 4)}
      </div>
    </Card>
  );
}

// ─── Vendas por linha de produto ──────────────────────────────────────────────
function VendasPorLinha({ chartMode, setChartMode, start, end }) {
  const [linhaData, setLinhaData] = React.useState(null);

  React.useEffect(() => {
    if (!window.tmSupabase) return;
    const s0 = start.toISOString();
    const s1 = new Date(end.getTime() + 86400000).toISOString();

    Promise.all([
      window.tmSupabase.from('pedidos').select('id').eq('status', 'Atendido')
        .gte('created_at', s0).lte('created_at', s1),
    ]).then(async ([pedRes]) => {
      const pedIds = (pedRes.data || []).map(p => p.id);
      if (pedIds.length === 0) { setLinhaData([]); return; }

      const { data: itens } = await window.tmSupabase.from('pedido_itens')
        .select('produto_id, quantidade, preco_lista, desconto_pct')
        .in('pedido_id', pedIds);

      if (!itens || itens.length === 0) { setLinhaData([]); return; }

      const prodIds = [...new Set((itens || []).map(i => i.produto_id).filter(Boolean))];
      const { data: prods } = await window.tmSupabase.from('produtos')
        .select('id, linha, custo, preco_venda')
        .in('id', prodIds);

      const prodMap = {};
      (prods || []).forEach(p => { prodMap[p.id] = p; });

      const byLinha = {};
      (itens || []).forEach(it => {
        const prod = prodMap[it.produto_id] || {};
        const linha = prod.linha || 'Sem linha';
        if (!byLinha[linha]) byLinha[linha] = { linha, qty: 0, receita: 0, custo: 0 };
        const qty = parseFloat(it.quantidade) || 0;
        const preco = parseFloat(it.preco_lista) || 0;
        const desc = parseFloat(it.desconto_pct) || 0;
        const custoUn = parseFloat(prod.custo) || 0;
        byLinha[linha].qty += qty;
        byLinha[linha].receita += qty * preco * (1 - desc / 100);
        byLinha[linha].custo += qty * custoUn;
      });

      const arr = Object.values(byLinha).sort((a, b) => b.receita - a.receita);
      setLinhaData(arr);
    });
  }, [start.getTime(), end.getTime()]);

  const CHART_COLORS = ['#C9A36B', '#5BB17A', '#5B9BD5', '#D9655E', '#A78BDA', '#D4A04A', '#6BC5D2', '#E07BAA'];

  const renderChart = () => {
    if (!linhaData || linhaData.length === 0) {
      return (
        <div style={{ padding: "40px 0", textAlign: "center", color: "var(--tm-fg-3)" }}>
          <Icon name="bar-chart-2" size={32} style={{ opacity: 0.3, marginBottom: 10 }} />
          <div style={{ fontSize: 13 }}>Sem dados de {chartMode} no período</div>
          <div style={{ fontSize: 12, marginTop: 4 }}>Crie pedidos para ver o gráfico de vendas</div>
        </div>
      );
    }

    const getValue = (item) => {
      if (chartMode === 'volume') return item.qty;
      if (chartMode === 'faturamento') return item.receita;
      return item.custo > 0 ? ((item.receita - item.custo) / item.receita) * 100 : 0;
    };
    const formatValue = (item) => {
      if (chartMode === 'volume') return `${item.qty} un.`;
      if (chartMode === 'faturamento') return `R$ ${brl(item.receita)}`;
      if (item.custo > 0) return `${((item.receita - item.custo) / item.receita * 100).toFixed(1)}%`;
      return 'N/D';
    };

    const maxVal = Math.max(...linhaData.map(getValue), 1);

    return (
      <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
        {linhaData.map((item, i) => {
          const val = getValue(item);
          const pct = Math.max((val / maxVal) * 100, 2);
          const color = CHART_COLORS[i % CHART_COLORS.length];
          return (
            <div key={item.linha} style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <div style={{ width: 100, fontSize: 11.5, color: 'var(--tm-fg-2)', textAlign: 'right', flexShrink: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                {item.linha}
              </div>
              <div style={{ flex: 1, background: 'var(--tm-bg-2)', borderRadius: 4, height: 22, overflow: 'hidden' }}>
                <div style={{
                  width: `${pct}%`, height: '100%', background: color, borderRadius: 4,
                  transition: 'width 0.4s ease',
                }} />
              </div>
              <div style={{ width: 80, fontSize: 11.5, color: 'var(--tm-fg-2)', fontVariantNumeric: 'tabular-nums', flexShrink: 0 }}>
                {formatValue(item)}
              </div>
            </div>
          );
        })}
      </div>
    );
  };

  const renderStats = () => {
    if (!linhaData || linhaData.length === 0) {
      if (chartMode === 'volume') return <>
        <Stat label="Total unidades" v="—" /><Stat label="Linhas ativas" v="—" />
        <Stat label="Maior volume" v="—" /><Stat label="Menor volume" v="—" />
        <Stat label="Média/linha" v="—" /><Stat label="Devoluções" v="—" />
      </>;
      if (chartMode === 'faturamento') return <>
        <Stat label="Faturamento" v="—" /><Stat label="Custo" v="—" />
        <Stat label="Markup" v="—" /><Stat label="Impostos" v="—" />
        <Stat label="Taxa venda" v="—" /><Stat label="Lucro" v="—" />
      </>;
      return <>
        <Stat label="Margem bruta" v="—" /><Stat label="Margem líq." v="—" />
        <Stat label="Maior margem" v="—" /><Stat label="Menor margem" v="—" />
        <Stat label="CMV" v="—" /><Stat label="EBITDA est." v="—" />
      </>;
    }

    const totalQty = linhaData.reduce((s, i) => s + i.qty, 0);
    const totalRec = linhaData.reduce((s, i) => s + i.receita, 0);
    const totalCusto = linhaData.reduce((s, i) => s + i.custo, 0);
    const sorted = [...linhaData].sort((a, b) => b.qty - a.qty);

    if (chartMode === 'volume') return <>
      <Stat label="Total unidades" v={String(totalQty)} tone="up" />
      <Stat label="Linhas ativas" v={String(linhaData.length)} />
      <Stat label="Maior volume" v={sorted[0]?.linha || '—'} sub={`${sorted[0]?.qty || 0} un.`} />
      <Stat label="Menor volume" v={sorted[sorted.length - 1]?.linha || '—'} sub={`${sorted[sorted.length - 1]?.qty || 0} un.`} />
      <Stat label="Média/linha" v={`${Math.round(totalQty / linhaData.length)} un.`} />
      <Stat label="Devoluções" v="0" />
    </>;
    if (chartMode === 'faturamento') {
      const lucro = totalRec - totalCusto;
      const markup = totalCusto > 0 ? ((totalRec / totalCusto - 1) * 100).toFixed(1) + '%' : '—';
      return <>
        <Stat label="Faturamento" v={`R$ ${brl(totalRec)}`} tone="up" />
        <Stat label="Custo" v={totalCusto > 0 ? `R$ ${brl(totalCusto)}` : '—'} />
        <Stat label="Markup" v={markup} />
        <Stat label="Impostos" v="—" />
        <Stat label="Taxa venda" v="—" />
        <Stat label="Lucro" v={totalCusto > 0 ? `R$ ${brl(lucro)}` : '—'} tone={lucro > 0 ? 'up' : undefined} />
      </>;
    }
    const margemBruta = totalRec > 0 && totalCusto > 0 ? ((totalRec - totalCusto) / totalRec * 100) : null;
    const linhasComMargem = linhaData.filter(i => i.custo > 0).map(i => ({
      ...i, margem: (i.receita - i.custo) / i.receita * 100,
    })).sort((a, b) => b.margem - a.margem);
    return <>
      <Stat label="Margem bruta" v={margemBruta !== null ? `${margemBruta.toFixed(1)}%` : 'N/C'} tone={margemBruta > 0 ? 'up' : undefined} />
      <Stat label="Margem líq." v="—" sub="sem impostos" />
      <Stat label="Maior margem" v={linhasComMargem[0]?.linha || 'N/C'} sub={linhasComMargem[0] ? `${linhasComMargem[0].margem.toFixed(1)}%` : ''} />
      <Stat label="Menor margem" v={linhasComMargem.length > 0 ? linhasComMargem[linhasComMargem.length - 1].linha : 'N/C'} sub={linhasComMargem.length > 0 ? `${linhasComMargem[linhasComMargem.length - 1].margem.toFixed(1)}%` : ''} />
      <Stat label="CMV" v={totalCusto > 0 ? `R$ ${brl(totalCusto)}` : 'N/C'} />
      <Stat label="EBITDA est." v="—" />
    </>;
  };

  return (
    <Card title="Vendas por linha de produto"
          action={
            <div style={{ display: "flex", gap: 6 }}>
              {[
                { id: 'volume', label: 'Volume' },
                { id: 'faturamento', label: 'Faturamento' },
                { id: 'margem', label: 'Margem' },
              ].map(({ id, label }) => (
                <span key={id} className={`chip${chartMode === id ? ' active' : ''}`}
                      style={{ cursor: 'pointer' }} onClick={() => setChartMode(id)}>
                  {label}
                </span>
              ))}
            </div>
          }>
      <div style={{ padding: 20 }}>
        {renderChart()}
        <div style={{ display: "grid", gridTemplateColumns: "repeat(6, 1fr)", gap: 12, marginTop: 18 }}>
          {renderStats()}
        </div>
      </div>
    </Card>
  );
}

// ─── Top Distribuidores ───────────────────────────────────────────────────────
function TopDistribuidores() {
  const [data, setData] = React.useState(null);

  React.useEffect(() => {
    if (!window.tmSupabase) return;
    Promise.all([
      window.tmSupabase.from('pedidos').select('cliente_nome, total, status').eq('status', 'Atendido'),
      window.tmSupabase.from('distribuidores').select('nome, cidade, status, total_faturado')
        .order('total_faturado', { ascending: false }),
    ]).then(([pedRes, distRes]) => {
      const pedByCliente = {};
      (pedRes.data || []).forEach(p => {
        const nome = p.cliente_nome || 'Sem nome';
        if (!pedByCliente[nome]) pedByCliente[nome] = { nome, total: 0, count: 0 };
        pedByCliente[nome].total += parseFloat(p.total) || 0;
        pedByCliente[nome].count += 1;
      });

      const distribuidores = (distRes.data || []).map(d => {
        const pedData = pedByCliente[d.nome];
        return {
          nome: d.nome, cidade: d.cidade, status: d.status || 'Bronze',
          totalFaturado: pedData ? pedData.total : (parseFloat(d.total_faturado) || 0),
          pedidos: pedData ? pedData.count : 0,
        };
      });

      const distNomes = new Set(distribuidores.map(d => d.nome));
      Object.values(pedByCliente).forEach(pc => {
        if (!distNomes.has(pc.nome)) {
          distribuidores.push({ nome: pc.nome, cidade: '', status: null, totalFaturado: pc.total, pedidos: pc.count });
        }
      });

      distribuidores.sort((a, b) => b.totalFaturado - a.totalFaturado);
      setData(distribuidores);
    });
  }, []);

  if (data === null) return <div style={{ padding: "24px 16px", textAlign: "center", color: "var(--tm-fg-3)" }}><Icon name="loader" size={20} style={{ opacity: 0.4 }} /></div>;
  if (data.length === 0) return <div style={{ padding: "24px 16px", textAlign: "center", color: "var(--tm-fg-3)" }}><Icon name="users" size={28} style={{ opacity: 0.3, marginBottom: 10 }} /><div style={{ fontSize: 13 }}>Sem distribuidores</div></div>;

  const statusTone = { 'Ouro': 'warning', 'Prata': 'neutral', 'Bronze': 'info' };

  return (
    <div style={{ display: 'flex', flexDirection: 'column' }}>
      {data.slice(0, 5).map((d, i) => (
        <div key={d.nome} style={{
          display: 'flex', alignItems: 'center', gap: 10, padding: '10px 16px',
          borderBottom: i < Math.min(data.length, 5) - 1 ? '1px solid var(--tm-line-1)' : 'none',
        }}>
          <div style={{
            width: 22, height: 22, borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center',
            fontSize: 11, fontWeight: 700, background: 'var(--tm-bg-2)', color: i === 0 ? 'var(--tm-brand-champagne)' : 'var(--tm-fg-3)',
          }}>{i + 1}</div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 13, fontWeight: 500, color: 'var(--tm-fg-1)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{d.nome}</div>
            <div style={{ fontSize: 11, color: 'var(--tm-fg-4)', display: 'flex', gap: 8, marginTop: 2 }}>
              {d.cidade && <span>{d.cidade}</span>}
              {d.pedidos > 0 && <span>{d.pedidos} {d.pedidos === 1 ? 'pedido' : 'pedidos'}</span>}
            </div>
          </div>
          <div style={{ textAlign: 'right', flexShrink: 0 }}>
            <div style={{ fontSize: 12.5, fontWeight: 600, color: 'var(--tm-fg-1)', fontVariantNumeric: 'tabular-nums' }}>
              {d.totalFaturado > 0 ? `R$ ${brl(d.totalFaturado)}` : '—'}
            </div>
            {d.status && <Badge tone={statusTone[d.status] || 'neutral'}>{d.status}</Badge>}
          </div>
        </div>
      ))}
    </div>
  );
}

// ─── Top SKUs ─────────────────────────────────────────────────────────────────
function TopSkus() {
  const [data, setData] = React.useState(null);
  const mesAtual = new Date().toLocaleDateString('pt-BR', { month: 'long' });

  React.useEffect(() => {
    if (!window.tmSupabase) return;
    window.tmSupabase.from('pedido_itens')
      .select('sku, descricao, quantidade, preco_lista')
      .then(({ data: itens }) => {
        if (!itens || itens.length === 0) { setData([]); return; }
        const bySku = {};
        itens.forEach(it => {
          const key = it.sku || it.descricao || 'Sem SKU';
          if (!bySku[key]) bySku[key] = { sku: it.sku, desc: it.descricao || it.sku, qty: 0, valor: 0 };
          const qty = parseFloat(it.quantidade) || 0;
          const preco = parseFloat(it.preco_lista) || 0;
          bySku[key].qty += qty;
          bySku[key].valor += qty * preco;
        });
        setData(Object.values(bySku).sort((a, b) => b.qty - a.qty).slice(0, 5));
      });
  }, []);

  if (data === null) return <div style={{ padding: "24px 16px", textAlign: "center", color: "var(--tm-fg-3)" }}><Icon name="loader" size={20} style={{ opacity: 0.4 }} /></div>;
  if (data.length === 0) return <div style={{ padding: "24px 16px", textAlign: "center", color: "var(--tm-fg-3)" }}><Icon name="package" size={28} style={{ opacity: 0.3, marginBottom: 10 }} /><div style={{ fontSize: 13 }}>Sem dados de venda</div></div>;

  const maxQty = Math.max(...data.map(d => d.qty), 1);

  return (
    <div style={{ display: 'flex', flexDirection: 'column' }}>
      {data.map((item, i) => (
        <div key={item.sku || i} style={{
          display: 'flex', alignItems: 'center', gap: 10, padding: '10px 16px',
          borderBottom: i < data.length - 1 ? '1px solid var(--tm-line-1)' : 'none',
        }}>
          <div style={{
            width: 22, height: 22, borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center',
            fontSize: 11, fontWeight: 700, background: 'var(--tm-bg-2)', color: i < 3 ? 'var(--tm-brand-champagne)' : 'var(--tm-fg-3)',
          }}>{i + 1}</div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 13, fontWeight: 500, color: 'var(--tm-fg-1)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{item.desc}</div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 4 }}>
              <div style={{ flex: 1, background: 'var(--tm-bg-2)', borderRadius: 3, height: 4, overflow: 'hidden' }}>
                <div style={{ width: `${(item.qty / maxQty) * 100}%`, height: '100%', background: 'var(--tm-brand-champagne)', borderRadius: 3 }} />
              </div>
              <span style={{ fontSize: 11, color: 'var(--tm-fg-4)', flexShrink: 0 }}>{item.qty} un.</span>
            </div>
          </div>
          <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--tm-fg-2)', fontVariantNumeric: 'tabular-nums', flexShrink: 0, textAlign: 'right' }}>
            R$ {brl(item.valor)}
          </div>
        </div>
      ))}
    </div>
  );
}

// ─── Activity Feed (Expanded) ─────────────────────────────────────────────────
function ActivityFeed() {
  const [events, setEvents] = React.useState(null);

  React.useEffect(() => {
    if (!window.tmSupabase) return;
    Promise.all([
      window.tmSupabase.from('pedidos').select('numero, status, cliente_nome, created_at, updated_at')
        .order('updated_at', { ascending: false }).limit(5),
      window.tmSupabase.from('produtos').select('nome, sku, created_at')
        .order('created_at', { ascending: false }).limit(4),
      window.tmSupabase.from('distribuidores').select('nome, created_at')
        .order('created_at', { ascending: false }).limit(3),
      window.tmSupabase.from('clientes').select('nome, created_at')
        .order('created_at', { ascending: false }).limit(3),
      window.tmSupabase.from('contas_receber').select('referencia, cliente_nome, valor, updated_at, status')
        .eq('status', 'Recebido').order('updated_at', { ascending: false }).limit(3),
      window.tmSupabase.from('movimentacoes_estoque').select('tipo, quantidade, produto_nome, created_at')
        .order('created_at', { ascending: false }).limit(3),
    ]).then(([pedRes, prodRes, distRes, cliRes, crRes, movRes]) => {
      const items = [];
      (pedRes.data || []).forEach(p => {
        const statusMap = {
          'Atendido': { icon: 'check-circle', text: `Pedido ${p.numero} faturado`, color: 'var(--tm-success)' },
          'Em andamento': { icon: 'clock', text: `Pedido ${p.numero} em andamento`, color: 'var(--tm-warning)' },
          'Cancelado': { icon: 'x-circle', text: `Pedido ${p.numero} cancelado`, color: 'var(--tm-danger)' },
        };
        const info = statusMap[p.status] || { icon: 'file-text', text: `Pedido ${p.numero} · ${p.status}`, color: 'var(--tm-fg-3)' };
        items.push({ ...info, sub: p.cliente_nome, time: p.updated_at || p.created_at });
      });
      (prodRes.data || []).forEach(p => {
        items.push({ icon: 'package-plus', text: `Produto cadastrado: ${p.nome}`, sub: p.sku, time: p.created_at, color: 'var(--tm-brand-champagne)' });
      });
      (distRes.data || []).forEach(d => {
        items.push({ icon: 'user-plus', text: `Distribuidor: ${d.nome}`, sub: null, time: d.created_at, color: 'var(--tm-info, #5B9BD5)' });
      });
      (cliRes.data || []).forEach(c => {
        items.push({ icon: 'user-plus', text: `Cliente: ${c.nome}`, sub: null, time: c.created_at, color: 'var(--tm-info, #5B9BD5)' });
      });
      (crRes.data || []).forEach(c => {
        items.push({ icon: 'circle-check', text: `Conta recebida: ${c.referencia || c.cliente_nome}`, sub: c.valor ? `R$ ${brl(parseFloat(c.valor))}` : null, time: c.updated_at, color: 'var(--tm-success)' });
      });
      (movRes.data || []).forEach(m => {
        const label = m.tipo === 'Entrada' ? 'Entrada estoque' : m.tipo === 'Saída' ? 'Saída estoque' : 'Ajuste estoque';
        items.push({ icon: 'archive', text: `${label}: ${m.produto_nome || ''}`, sub: `${m.quantidade} un.`, time: m.created_at, color: 'var(--tm-fg-3)' });
      });

      items.sort((a, b) => new Date(b.time) - new Date(a.time));
      setEvents(items.slice(0, 12));
    });
  }, []);

  if (events === null) return <div style={{ padding: "24px 16px", textAlign: "center", color: "var(--tm-fg-3)" }}><Icon name="loader" size={20} style={{ opacity: 0.4 }} /></div>;
  if (events.length === 0) return <div style={{ padding: "24px 16px", textAlign: "center", color: "var(--tm-fg-3)" }}><Icon name="activity" size={28} style={{ opacity: 0.3, marginBottom: 10 }} /><div style={{ fontSize: 13 }}>Sem atividade recente</div></div>;

  return (
    <div style={{ display: 'flex', flexDirection: 'column' }}>
      {events.map((ev, i) => (
        <div key={i} style={{
          display: 'flex', alignItems: 'flex-start', gap: 10, padding: '9px 16px',
          borderBottom: i < events.length - 1 ? '1px solid var(--tm-line-1)' : 'none',
        }}>
          <div style={{ marginTop: 2, flexShrink: 0 }}>
            <Icon name={ev.icon} size={14} style={{ color: ev.color }} />
          </div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 12.5, color: 'var(--tm-fg-1)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{ev.text}</div>
            {ev.sub && <div style={{ fontSize: 11, color: 'var(--tm-fg-4)', marginTop: 1 }}>{ev.sub}</div>}
          </div>
          <div style={{ fontSize: 11, color: 'var(--tm-fg-4)', flexShrink: 0, whiteSpace: 'nowrap', marginTop: 1 }}>
            {tempoAtras(ev.time)}
          </div>
        </div>
      ))}
    </div>
  );
}

// ─── Fluxo Financeiro (Chart.js line chart) ──────────────────────────────────
function FluxoFinanceiro({ start, end }) {
  const [tab, setTab] = React.useState('diario');
  const [chartData, setChartData] = React.useState(null);

  React.useEffect(() => {
    if (!window.tmSupabase) return;
    Promise.all([
      window.tmSupabase.from('contas_receber').select('vencimento, valor, valor_recebido, status'),
      window.tmSupabase.from('contas_pagar').select('vencimento, valor, status'),
    ]).then(([crRes, cpRes]) => {
      const cr = crRes.data || [];
      const cp = cpRes.data || [];
      setChartData({ cr, cp });
    });
  }, []);

  if (!chartData) return <div style={{ padding: 40, textAlign: 'center', color: 'var(--tm-fg-3)' }}><Icon name="loader" size={20} style={{ opacity: 0.4 }} /></div>;

  const buildChart = () => {
    const s = new Date(start);
    const e = new Date(end);
    const days = Math.ceil((e - s) / 86400000);
    let buckets = [];
    let labelFn;

    if (tab === 'diario') {
      const maxDays = Math.min(days, 60);
      for (let i = 0; i < maxDays; i++) {
        const d = new Date(s.getTime() + i * 86400000);
        buckets.push({ key: d.toISOString().slice(0, 10), label: d.toLocaleDateString('pt-BR', { day: '2-digit', month: '2-digit' }) });
      }
    } else if (tab === 'semanal') {
      const weeks = Math.min(Math.ceil(days / 7), 16);
      for (let i = 0; i < weeks; i++) {
        const wStart = new Date(s.getTime() + i * 7 * 86400000);
        const wEnd = new Date(wStart.getTime() + 6 * 86400000);
        buckets.push({
          key: `w${i}`,
          start: wStart.toISOString().slice(0, 10),
          end: wEnd.toISOString().slice(0, 10),
          label: `${wStart.toLocaleDateString('pt-BR', { day: '2-digit', month: '2-digit' })}`,
        });
      }
    } else {
      const months = Math.min(Math.ceil(days / 30), 12);
      for (let i = 0; i < months; i++) {
        const mDate = new Date(s.getFullYear(), s.getMonth() + i, 1);
        const mEnd = new Date(s.getFullYear(), s.getMonth() + i + 1, 0);
        buckets.push({
          key: `m${i}`,
          start: mDate.toISOString().slice(0, 10),
          end: mEnd.toISOString().slice(0, 10),
          label: mDate.toLocaleDateString('pt-BR', { month: 'short' }),
        });
      }
    }

    const entradas = buckets.map(() => 0);
    const saidas = buckets.map(() => 0);

    chartData.cr.forEach(c => {
      if (!c.vencimento) return;
      const v = c.vencimento.slice(0, 10);
      const valor = (parseFloat(c.valor) || 0) - (parseFloat(c.valor_recebido) || 0);
      if (c.status === 'Recebido') return;
      buckets.forEach((b, i) => {
        if (tab === 'diario') { if (v === b.key) entradas[i] += parseFloat(c.valor) || 0; }
        else { if (v >= b.start && v <= b.end) entradas[i] += parseFloat(c.valor) || 0; }
      });
    });

    chartData.cp.forEach(c => {
      if (!c.vencimento) return;
      const v = c.vencimento.slice(0, 10);
      buckets.forEach((b, i) => {
        if (tab === 'diario') { if (v === b.key) saidas[i] += parseFloat(c.valor) || 0; }
        else { if (v >= b.start && v <= b.end) saidas[i] += parseFloat(c.valor) || 0; }
      });
    });

    return {
      labels: buckets.map(b => b.label),
      datasets: [
        {
          label: 'Entradas',
          data: entradas,
          borderColor: '#5BB17A',
          backgroundColor: 'rgba(91,177,122,0.1)',
          fill: true,
          tension: 0.3,
          pointRadius: 2,
          borderWidth: 2,
        },
        {
          label: 'Saídas',
          data: saidas,
          borderColor: '#D9655E',
          backgroundColor: 'rgba(217,101,94,0.08)',
          fill: true,
          tension: 0.3,
          pointRadius: 2,
          borderWidth: 2,
        },
      ],
    };
  };

  const data = buildChart();
  const totalEntradas = data.datasets[0].data.reduce((a, b) => a + b, 0);
  const totalSaidas = data.datasets[1].data.reduce((a, b) => a + b, 0);
  const saldo = totalEntradas - totalSaidas;

  return (
    <div>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 }}>
        <div style={{ display: 'flex', gap: 12, fontSize: 11.5 }}>
          <span style={{ color: '#5BB17A' }}>● Entradas: R$ {brl(totalEntradas)}</span>
          <span style={{ color: '#D9655E' }}>● Saídas: R$ {brl(totalSaidas)}</span>
          <span style={{ color: saldo >= 0 ? 'var(--tm-success)' : 'var(--tm-danger)' }}>Saldo: R$ {brl(saldo)}</span>
        </div>
        <div style={{ display: 'flex', gap: 4 }}>
          {['diario', 'semanal', 'mensal'].map(t => (
            <span key={t} className={`chip${tab === t ? ' active' : ''}`} style={{ cursor: 'pointer', fontSize: 11 }} onClick={() => setTab(t)}>
              {t === 'diario' ? 'Diário' : t === 'semanal' ? 'Semanal' : 'Mensal'}
            </span>
          ))}
        </div>
      </div>
      <ChartCanvas
        type="line"
        data={data}
        height={200}
        options={{
          scales: {
            x: { grid: { color: 'rgba(255,255,255,0.06)' }, ticks: { color: 'rgba(255,255,255,0.55)', font: { size: 10 } } },
            y: { grid: { color: 'rgba(255,255,255,0.06)' }, ticks: { color: 'rgba(255,255,255,0.55)', font: { size: 10 }, callback: (v) => v >= 1000 ? `${(v/1000).toFixed(0)}k` : v } },
          },
          plugins: {
            legend: { display: true, position: 'bottom', labels: { color: 'rgba(255,255,255,0.7)', font: { size: 11 }, boxWidth: 12, padding: 16 } },
            tooltip: { callbacks: { label: (ctx) => `${ctx.dataset.label}: R$ ${brl(ctx.raw)}` } },
          },
        }}
      />
    </div>
  );
}

// ─── Ranking Comercial (tabbed) ──────────────────────────────────────────────
function RankingComercial({ start, end }) {
  const [tab, setTab] = React.useState('distribuidores');
  const [data, setData] = React.useState(null);

  React.useEffect(() => {
    if (!window.tmSupabase) return;
    const s0 = start.toISOString();
    const s1 = new Date(end.getTime() + 86400000).toISOString();

    Promise.all([
      window.tmSupabase.from('pedidos').select('cliente_nome, vendedor, total, status, created_at')
        .eq('status', 'Atendido').gte('created_at', s0).lte('created_at', s1),
      window.tmSupabase.from('pedido_itens').select('pedido_id, descricao, quantidade, preco_lista, desconto_pct'),
      window.tmSupabase.from('distribuidores').select('nome, uf, cidade'),
    ]).then(([pedRes, itensRes, distRes]) => {
      const peds = pedRes.data || [];
      const itens = itensRes.data || [];
      const dists = distRes.data || [];

      const distMap = {};
      dists.forEach(d => { distMap[d.nome] = d; });

      // By distribuidor
      const byDist = {};
      peds.forEach(p => {
        const nome = p.cliente_nome || 'Sem nome';
        if (!byDist[nome]) byDist[nome] = { nome, fat: 0, pedidos: 0, uf: distMap[nome]?.uf || '' };
        byDist[nome].fat += parseFloat(p.total) || 0;
        byDist[nome].pedidos++;
      });

      // By vendedor
      const byVend = {};
      peds.forEach(p => {
        const vend = p.vendedor || 'Sem vendedor';
        if (!byVend[vend]) byVend[vend] = { nome: vend, fat: 0, pedidos: 0 };
        byVend[vend].fat += parseFloat(p.total) || 0;
        byVend[vend].pedidos++;
      });

      // By UF
      const byUf = {};
      peds.forEach(p => {
        const dist = distMap[p.cliente_nome];
        const uf = dist?.uf || '—';
        if (!byUf[uf]) byUf[uf] = { nome: uf, fat: 0, pedidos: 0 };
        byUf[uf].fat += parseFloat(p.total) || 0;
        byUf[uf].pedidos++;
      });

      setData({
        distribuidores: Object.values(byDist).sort((a, b) => b.fat - a.fat).slice(0, 10),
        vendedores: Object.values(byVend).sort((a, b) => b.fat - a.fat).slice(0, 10),
        estados: Object.values(byUf).sort((a, b) => b.fat - a.fat).slice(0, 10),
      });
    });
  }, [start.getTime(), end.getTime()]);

  if (!data) return <div style={{ padding: 40, textAlign: 'center', color: 'var(--tm-fg-3)' }}><Icon name="loader" size={20} style={{ opacity: 0.4 }} /></div>;

  const currentData = data[tab] || [];
  const maxFat = currentData.length > 0 ? currentData[0].fat : 1;

  return (
    <div>
      <div style={{ display: 'flex', gap: 4, marginBottom: 12 }}>
        {[
          { id: 'distribuidores', label: 'Distribuidores' },
          { id: 'vendedores', label: 'Vendedores' },
          { id: 'estados', label: 'Estados' },
        ].map(t => (
          <span key={t.id} className={`chip${tab === t.id ? ' active' : ''}`} style={{ cursor: 'pointer', fontSize: 11 }} onClick={() => setTab(t.id)}>
            {t.label}
          </span>
        ))}
      </div>
      {currentData.length === 0 ? (
        <div style={{ padding: 24, textAlign: 'center', color: 'var(--tm-fg-3)', fontSize: 13 }}>Sem dados no período</div>
      ) : (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
          {currentData.map((item, i) => (
            <div key={item.nome} style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <div style={{ width: 20, fontSize: 11, fontWeight: 700, color: i < 3 ? 'var(--tm-brand-champagne)' : 'var(--tm-fg-4)', textAlign: 'right' }}>{i + 1}</div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 3 }}>
                  <span style={{ fontSize: 12, color: 'var(--tm-fg-1)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{item.nome}</span>
                  <span style={{ fontSize: 11, color: 'var(--tm-fg-2)', fontVariantNumeric: 'tabular-nums', flexShrink: 0, marginLeft: 8 }}>R$ {brl(item.fat)}</span>
                </div>
                <div style={{ background: 'var(--tm-bg-2)', borderRadius: 3, height: 4, overflow: 'hidden' }}>
                  <div style={{ width: `${Math.max((item.fat / maxFat) * 100, 2)}%`, height: '100%', background: 'var(--tm-brand-champagne)', borderRadius: 3, transition: 'width 0.3s' }} />
                </div>
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

// ─── Mapa de Vendas (Leaflet heatmap by state) ──────────────────────────────
const IBGE_TO_UF_DASH = {
  11:'RO',12:'AC',13:'AM',14:'RR',15:'PA',16:'AP',17:'TO',
  21:'MA',22:'PI',23:'CE',24:'RN',25:'PB',26:'PE',27:'AL',28:'SE',29:'BA',
  31:'MG',32:'ES',33:'RJ',35:'SP',
  41:'PR',42:'SC',43:'RS',
  50:'MS',51:'MT',52:'GO',53:'DF',
};

function MapaVendas({ start, end }) {
  const mapRef = React.useRef(null);
  const leafletRef = React.useRef(null);
  const geoLayerRef = React.useRef(null);
  const geoCache = React.useRef(null);
  const [status, setStatus] = React.useState('loading');

  const startKey = Math.floor(start.getTime() / 60000);
  const endKey   = Math.floor(end.getTime() / 60000);

  React.useEffect(() => {
    if (!mapRef.current || !window.L || leafletRef.current) return;
    leafletRef.current = window.L.map(mapRef.current, {
      center: [-14.5, -51.5], zoom: 4,
      zoomControl: true, attributionControl: false,
      scrollWheelZoom: true, dragging: true,
      minZoom: 3, maxZoom: 7,
    });
    return () => { if (leafletRef.current) { leafletRef.current.remove(); leafletRef.current = null; } };
  }, []);

  React.useEffect(() => {
    const map = leafletRef.current;
    if (!map || !window.tmSupabase) return;
    const L = window.L;

    const s0 = start.toISOString();
    const s1 = new Date(end.getTime() + 86400000).toISOString();

    if (geoLayerRef.current) { map.removeLayer(geoLayerRef.current); geoLayerRef.current = null; }
    setStatus('loading');

    Promise.all([
      window.tmSupabase.from('pedidos').select('cliente_nome, total, status')
        .eq('status', 'Atendido').gte('created_at', s0).lte('created_at', s1),
      window.tmSupabase.from('distribuidores').select('nome, uf'),
    ]).then(([pedRes, distRes]) => {
      const peds = pedRes.data || [];
      const dists = distRes.data || [];
      const distUf = {};
      dists.forEach(d => { distUf[d.nome] = d.uf; });

      const ufFat = {};
      peds.forEach(p => {
        const uf = distUf[p.cliente_nome] || '—';
        if (uf === '—') return;
        if (!ufFat[uf]) ufFat[uf] = { fat: 0, pedidos: 0 };
        ufFat[uf].fat += parseFloat(p.total) || 0;
        ufFat[uf].pedidos++;
      });

      const maxFat = Math.max(...Object.values(ufFat).map(u => u.fat), 1);

      const getColor = (fat) => {
        if (!fat || fat === 0) return 'rgba(148,163,184,0.2)';
        const intensity = Math.min(fat / maxFat, 1);
        const r = Math.round(148 + (201 - 148) * intensity);
        const g = Math.round(163 + (163 - 163) * intensity);
        const b = Math.round(184 + (107 - 184) * intensity);
        return `rgba(${r},${g},${b},${0.3 + intensity * 0.6})`;
      };

      const buildLayer = (geo) => {
        const layer = L.geoJSON(geo, {
          style: (f) => {
            const uf = IBGE_TO_UF_DASH[parseInt(f.properties?.codarea ?? f.id ?? 0)];
            const fat = ufFat[uf]?.fat || 0;
            return { fillColor: getColor(fat), fillOpacity: 1, weight: 1, color: 'rgba(255,255,255,0.3)' };
          },
          onEachFeature: (f, layer) => {
            const uf = IBGE_TO_UF_DASH[parseInt(f.properties?.codarea ?? f.id ?? 0)] || '?';
            const info = ufFat[uf];
            const html = info
              ? `<b>${uf}</b><br>R$ ${brl(info.fat)}<br>${info.pedidos} pedido${info.pedidos !== 1 ? 's' : ''}`
              : `<b>${uf}</b><br><span style="color:#94a3b8">Sem vendas</span>`;
            layer.bindTooltip(html, { sticky: true });
            layer.on({
              mouseover: (e) => { e.target.setStyle({ fillOpacity: 1, weight: 2.5, color: '#C9A36B' }); e.target.bringToFront(); },
              mouseout: (e) => { e.target.setStyle({ weight: 1, color: 'rgba(255,255,255,0.3)', fillOpacity: 1 }); },
            });
          },
        });
        layer.addTo(map);
        geoLayerRef.current = layer;
        setStatus('ready');
      };

      if (geoCache.current) {
        buildLayer(geoCache.current);
      } else {
        fetch('https://servicodados.ibge.gov.br/api/v3/malhas/paises/BR?intrarregiao=UF&formato=application/vnd.geo+json')
          .then(r => r.json())
          .then(geo => { geoCache.current = geo; buildLayer(geo); })
          .catch(() => setStatus('error'));
      }
    });
  }, [startKey, endKey]);

  return (
    <div style={{ position: 'relative', height: 280, borderRadius: 8, overflow: 'hidden', background: 'var(--tm-bg-2)' }}>
      <div ref={mapRef} style={{ width: '100%', height: '100%' }} />
      {status === 'loading' && (
        <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'var(--tm-bg-2)' }}>
          <Icon name="loader" size={20} style={{ opacity: 0.4 }} />
        </div>
      )}
      {status === 'error' && (
        <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--tm-fg-3)' }}>
          <span style={{ fontSize: 12 }}>Mapa indisponível</span>
        </div>
      )}
    </div>
  );
}

// ─── Estoque Inteligente ─────────────────────────────────────────────────────
function EstoqueInteligente({ onNav }) {
  const [data, setData] = React.useState(null);

  React.useEffect(() => {
    if (!window.tmSupabase) return;
    const ha60dias = new Date(Date.now() - 60 * 86400000).toISOString();
    const ha30dias = new Date(Date.now() - 30 * 86400000).toISOString();

    Promise.all([
      window.tmSupabase.from('produtos').select('id, nome, sku, estoque, estoque_minimo, preco_venda'),
      window.tmSupabase.from('pedido_itens').select('produto_id, quantidade, created_at')
        .gte('created_at', ha30dias),
      window.tmSupabase.from('movimentacoes_estoque').select('produto_id, created_at')
        .gte('created_at', ha60dias),
    ]).then(([prodRes, itensRes, movRes]) => {
      const prods = prodRes.data || [];
      const itens = itensRes.data || [];
      const movs = movRes.data || [];

      // Venda média diária por produto (últimos 30 dias)
      const vendaPorProd = {};
      itens.forEach(it => {
        if (!it.produto_id) return;
        vendaPorProd[it.produto_id] = (vendaPorProd[it.produto_id] || 0) + (parseFloat(it.quantidade) || 0);
      });

      // Produtos com movimentação nos últimos 60 dias
      const comMov = new Set(movs.map(m => m.produto_id).filter(Boolean));

      const ruptura = [];
      const critico = [];
      const parados = [];
      const excesso = [];

      prods.forEach(p => {
        const est = parseFloat(p.estoque) || 0;
        const vendaDiaria = (vendaPorProd[p.id] || 0) / 30;
        const diasAteRuptura = vendaDiaria > 0 ? Math.floor(est / vendaDiaria) : null;
        const vendaMensal = vendaDiaria * 30;

        if (est <= 0) {
          ruptura.push({ ...p, diasAteRuptura: 0, vendaDiaria });
        } else if (diasAteRuptura !== null && diasAteRuptura < 14) {
          critico.push({ ...p, diasAteRuptura, vendaDiaria });
        }

        if (est > 0 && !comMov.has(p.id) && vendaDiaria === 0) {
          parados.push({ ...p, diasAteRuptura, vendaDiaria });
        }

        if (est > 0 && vendaMensal > 0 && est > vendaMensal * 10) {
          excesso.push({ ...p, mesesEstoque: Math.floor(est / vendaMensal), vendaDiaria });
        }
      });

      setData({ ruptura, critico, parados, excesso });
    });
  }, []);

  if (!data) return <div style={{ padding: 40, textAlign: 'center', color: 'var(--tm-fg-3)' }}><Icon name="loader" size={20} style={{ opacity: 0.4 }} /></div>;

  const renderList = (items, color, labelFn, maxShow) => {
    if (items.length === 0) return <div style={{ fontSize: 12, color: 'var(--tm-fg-4)', padding: '4px 0' }}>Nenhum</div>;
    return items.slice(0, maxShow || 4).map((p, i) => (
      <div key={p.id || i} style={{
        display: 'flex', alignItems: 'center', gap: 8, padding: '5px 0',
        borderBottom: i < Math.min(items.length, maxShow || 4) - 1 ? '1px solid var(--tm-line-1)' : 'none',
        cursor: 'pointer',
      }} onClick={() => onNav('produtos/lista')}>
        <div style={{ width: 6, height: 6, borderRadius: '50%', background: color, flexShrink: 0 }} />
        <div style={{ flex: 1, fontSize: 12, color: 'var(--tm-fg-2)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{p.nome}</div>
        <div style={{ fontSize: 11, color: 'var(--tm-fg-4)', flexShrink: 0 }}>{labelFn(p)}</div>
      </div>
    ));
  };

  return (
    <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16, minWidth: 0 }}>
      <div style={{ minWidth: 0 }}>
        <div style={{ fontSize: 11, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'var(--tm-danger)', marginBottom: 8, display: 'flex', alignItems: 'center', gap: 6 }}>
          <Icon name="alert-circle" size={12} /> Ruptura ({data.ruptura.length})
        </div>
        {renderList(data.ruptura, 'var(--tm-danger)', () => 'zerado')}
      </div>
      <div style={{ minWidth: 0 }}>
        <div style={{ fontSize: 11, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'var(--tm-warning)', marginBottom: 8, display: 'flex', alignItems: 'center', gap: 6 }}>
          <Icon name="clock" size={12} /> Risco ({data.critico.length})
        </div>
        {renderList(data.critico, 'var(--tm-warning)', (p) => `${p.diasAteRuptura}d restantes`)}
      </div>
      <div style={{ minWidth: 0 }}>
        <div style={{ fontSize: 11, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'var(--tm-fg-3)', marginBottom: 8, display: 'flex', alignItems: 'center', gap: 6 }}>
          <Icon name="archive" size={12} /> Parados 60d+ ({data.parados.length})
        </div>
        {renderList(data.parados, 'var(--tm-fg-4)', () => 'sem giro')}
      </div>
      <div style={{ minWidth: 0 }}>
        <div style={{ fontSize: 11, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'var(--tm-info, #5B9BD5)', marginBottom: 8, display: 'flex', alignItems: 'center', gap: 6 }}>
          <Icon name="package" size={12} /> Excesso ({data.excesso.length})
        </div>
        {renderList(data.excesso, 'var(--tm-info, #5B9BD5)', (p) => `${p.mesesEstoque} meses`)}
      </div>
    </div>
  );
}

// ─── Dashboard de Recompra ───────────────────────────────────────────────────
function RecompraDash({ onNav }) {
  const [data, setData] = React.useState(null);

  React.useEffect(() => {
    if (!window.tmSupabase) return;
    window.tmSupabase.from('pedidos')
      .select('cliente_nome, created_at, status')
      .eq('status', 'Atendido')
      .order('created_at', { ascending: true })
      .then(({ data: peds }) => {
        if (!peds || peds.length === 0) { setData({ emRisco: [], stats: {} }); return; }

        // Group pedidos by client
        const byClient = {};
        peds.forEach(p => {
          const nome = p.cliente_nome || 'Sem nome';
          if (!byClient[nome]) byClient[nome] = [];
          byClient[nome].push(new Date(p.created_at));
        });

        const now = Date.now();
        const emRisco = [];
        let totalCiclos = 0;
        let clientesComCiclo = 0;

        Object.entries(byClient).forEach(([nome, datas]) => {
          if (datas.length < 2) {
            // Cliente com apenas 1 compra: considerar em risco se há mais de 60 dias
            const diasDesdeUltimo = Math.floor((now - datas[0].getTime()) / 86400000);
            if (diasDesdeUltimo > 60) {
              emRisco.push({ nome, ultimaCompra: datas[0], diasInativo: diasDesdeUltimo, cicloMedio: null, compras: 1 });
            }
            return;
          }

          datas.sort((a, b) => a - b);
          const intervalos = [];
          for (let i = 1; i < datas.length; i++) {
            intervalos.push((datas[i] - datas[i - 1]) / 86400000);
          }
          const cicloMedio = intervalos.reduce((a, b) => a + b, 0) / intervalos.length;
          totalCiclos += cicloMedio;
          clientesComCiclo++;

          const ultimaCompra = datas[datas.length - 1];
          const diasInativo = Math.floor((now - ultimaCompra.getTime()) / 86400000);

          if (diasInativo > cicloMedio * 1.5) {
            emRisco.push({ nome, ultimaCompra, diasInativo, cicloMedio: Math.round(cicloMedio), compras: datas.length });
          }
        });

        emRisco.sort((a, b) => b.diasInativo - a.diasInativo);
        const cicloGeral = clientesComCiclo > 0 ? Math.round(totalCiclos / clientesComCiclo) : 0;

        setData({
          emRisco: emRisco.slice(0, 8),
          stats: {
            totalRisco: emRisco.length,
            cicloGeral,
            clientesAtivos: Object.keys(byClient).length,
          },
        });
      });
  }, []);

  if (!data) return <div style={{ padding: 40, textAlign: 'center', color: 'var(--tm-fg-3)' }}><Icon name="loader" size={20} style={{ opacity: 0.4 }} /></div>;

  return (
    <div>
      <div style={{ display: 'flex', gap: 16, marginBottom: 14 }}>
        <div style={{ flex: 1, background: 'var(--tm-bg-2)', borderRadius: 6, padding: '10px 12px', textAlign: 'center' }}>
          <div style={{ fontSize: 18, fontWeight: 600, color: data.stats.totalRisco > 0 ? 'var(--tm-warning)' : 'var(--tm-fg-1)' }}>{data.stats.totalRisco}</div>
          <div style={{ fontSize: 10, color: 'var(--tm-fg-4)', textTransform: 'uppercase', letterSpacing: '0.08em' }}>Em risco</div>
        </div>
        <div style={{ flex: 1, background: 'var(--tm-bg-2)', borderRadius: 6, padding: '10px 12px', textAlign: 'center' }}>
          <div style={{ fontSize: 18, fontWeight: 600, color: 'var(--tm-fg-1)' }}>{data.stats.cicloGeral}d</div>
          <div style={{ fontSize: 10, color: 'var(--tm-fg-4)', textTransform: 'uppercase', letterSpacing: '0.08em' }}>Ciclo médio</div>
        </div>
        <div style={{ flex: 1, background: 'var(--tm-bg-2)', borderRadius: 6, padding: '10px 12px', textAlign: 'center' }}>
          <div style={{ fontSize: 18, fontWeight: 600, color: 'var(--tm-fg-1)' }}>{data.stats.clientesAtivos}</div>
          <div style={{ fontSize: 10, color: 'var(--tm-fg-4)', textTransform: 'uppercase', letterSpacing: '0.08em' }}>Clientes ativos</div>
        </div>
      </div>
      {data.emRisco.length === 0 ? (
        <div style={{ padding: 16, textAlign: 'center', color: 'var(--tm-fg-3)', fontSize: 12.5 }}>
          <Icon name="check-circle" size={22} style={{ opacity: 0.3, marginBottom: 6 }} />
          <div>Todos os clientes comprando no ritmo</div>
        </div>
      ) : (
        <div style={{ display: 'flex', flexDirection: 'column' }}>
          {data.emRisco.map((c, i) => (
            <div key={c.nome} style={{
              display: 'flex', alignItems: 'center', gap: 10, padding: '7px 0',
              borderBottom: i < data.emRisco.length - 1 ? '1px solid var(--tm-line-1)' : 'none',
              cursor: 'pointer',
            }} onClick={() => onNav('crm/distribuidores')}>
              <div style={{ width: 6, height: 6, borderRadius: '50%', background: c.diasInativo > 90 ? 'var(--tm-danger)' : 'var(--tm-warning)', flexShrink: 0 }} />
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 12, color: 'var(--tm-fg-1)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{c.nome}</div>
                <div style={{ fontSize: 11, color: 'var(--tm-fg-4)' }}>
                  {c.compras} compra{c.compras !== 1 ? 's' : ''}{c.cicloMedio ? ` · ciclo ${c.cicloMedio}d` : ''}
                </div>
              </div>
              <div style={{ fontSize: 11, color: c.diasInativo > 90 ? 'var(--tm-danger)' : 'var(--tm-warning)', fontWeight: 600, flexShrink: 0 }}>
                {c.diasInativo}d inativo
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

// ─── Metas & Progresso ───────────────────────────────────────────────────────
function MetasWidget({ start, end, empresaAtual }) {
  const [metas, setMetas] = React.useState(null);
  const [kpiData, setKpiData] = React.useState(null);
  const [showForm, setShowForm] = React.useState(false);
  const [draft, setDraft] = React.useState({ tipo: 'faturamento', periodo: 'mensal', valor_alvo: '' });
  const [editId, setEditId] = React.useState(null);
  const [editDraft, setEditDraft] = React.useState({ tipo: '', valor_alvo: '' });

  const now = new Date();
  const mesAtual = now.getMonth() + 1;
  const anoAtual = now.getFullYear();

  React.useEffect(() => {
    if (!window.tmSupabase) return;
    window.tmSupabase.from('metas').select('*')
      .eq('ano', anoAtual)
      .then(({ data }) => setMetas(data || []));
  }, []);

  React.useEffect(() => {
    if (!window.tmSupabase) return;
    const s0 = start.toISOString();
    const s1 = new Date(end.getTime() + 86400000).toISOString();

    Promise.all([
      window.tmSupabase.from('pedidos').select('total, cliente_nome')
        .eq('status', 'Atendido').gte('created_at', s0).lte('created_at', s1),
      window.tmSupabase.from('clientes').select('id')
        .gte('created_at', s0).lte('created_at', s1),
    ]).then(([pedRes, cliRes]) => {
      const peds = pedRes.data || [];
      const fat = peds.reduce((a, p) => a + (parseFloat(p.total) || 0), 0);
      setKpiData({
        faturamento: fat,
        pedidos: peds.length,
        novos_clientes: (cliRes.data || []).length,
        margem: 0,
      });
    });
  }, [start.getTime(), end.getTime()]);

  const salvarMeta = async () => {
    if (!window.tmSupabase || !draft.valor_alvo) return;
    const rec = {
      tipo: draft.tipo,
      periodo: draft.periodo,
      ano: anoAtual,
      mes: draft.periodo === 'mensal' ? mesAtual : null,
      valor_alvo: parseFloat(draft.valor_alvo) || 0,
      empresa_id: empresaAtual?.id || null,
    };
    const { data } = await window.tmSupabase.from('metas').insert(rec).select().single();
    if (data) setMetas(prev => [...(prev || []), data]);
    setShowForm(false);
    setDraft({ tipo: 'faturamento', periodo: 'mensal', valor_alvo: '' });
  };

  const iniciarEdicao = (m) => {
    setEditId(m.id);
    setEditDraft({ tipo: m.tipo, valor_alvo: String(m.valor_alvo || '') });
    setShowForm(false);
  };

  const salvarEdicao = async () => {
    if (!window.tmSupabase || !editId || !editDraft.valor_alvo) return;
    const updates = { tipo: editDraft.tipo, valor_alvo: parseFloat(editDraft.valor_alvo) || 0 };
    await window.tmSupabase.from('metas').update(updates).eq('id', editId);
    setMetas(prev => (prev || []).map(m => m.id === editId ? { ...m, ...updates } : m));
    setEditId(null);
  };

  const apagarMeta = async (m) => {
    const label = tipoLabel[m.tipo] || m.tipo;
    if (!confirm(`Apagar meta "${label}"?\n\nEssa ação não pode ser desfeita.`)) return;
    if (window.tmSupabase) {
      await window.tmSupabase.from('metas').delete().eq('id', m.id);
    }
    setMetas(prev => (prev || []).filter(x => x.id !== m.id));
  };

  if (metas === null || kpiData === null) {
    return <div style={{ padding: 40, textAlign: 'center', color: 'var(--tm-fg-3)' }}><Icon name="loader" size={20} style={{ opacity: 0.4 }} /></div>;
  }

  const metasMes = metas.filter(m =>
    (m.periodo === 'mensal' && m.mes === mesAtual && m.ano === anoAtual) ||
    (m.periodo === 'anual' && m.ano === anoAtual)
  );

  const getAtual = (tipo) => {
    if (tipo === 'faturamento') return kpiData.faturamento;
    if (tipo === 'pedidos') return kpiData.pedidos;
    if (tipo === 'novos_clientes') return kpiData.novos_clientes;
    return 0;
  };

  const tipoLabel = { faturamento: 'Faturamento', pedidos: 'Pedidos', novos_clientes: 'Novos clientes', margem: 'Margem' };

  const diasNoMes = new Date(anoAtual, mesAtual, 0).getDate();
  const diasPassados = now.getDate();
  const diasRestantes = diasNoMes - diasPassados;

  return (
    <div>
      {metasMes.length === 0 && !showForm ? (
        <div style={{ padding: 20, textAlign: 'center' }}>
          <div style={{ color: 'var(--tm-fg-3)', fontSize: 13, marginBottom: 12 }}>Nenhuma meta definida para este mês</div>
          <Button variant="secondary" size="sm" icon="target" onClick={() => setShowForm(true)}>Criar meta</Button>
        </div>
      ) : (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          {metasMes.map(m => {
            const atual = getAtual(m.tipo);
            const alvo = parseFloat(m.valor_alvo) || 1;
            const pct = Math.min((atual / alvo) * 100, 100);
            const previsao = diasPassados > 0 ? (atual / diasPassados) * diasNoMes : 0;
            const ritmoDiario = diasRestantes > 0 ? Math.max(0, (alvo - atual) / diasRestantes) : 0;
            const isMoney = m.tipo === 'faturamento' || m.tipo === 'margem';
            const isEditing = editId === m.id;

            if (isEditing) {
              return (
                <div key={m.id} style={{ padding: 12, background: 'var(--tm-bg-2)', borderRadius: 8, border: '1px solid var(--tm-line-1)' }}>
                  <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--tm-fg-1)', marginBottom: 10 }}>Editar meta</div>
                  <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
                    <div className="field" style={{ margin: 0 }}>
                      <label>Tipo</label>
                      <select className="input" value={editDraft.tipo} onChange={e => setEditDraft({ ...editDraft, tipo: e.target.value })}>
                        <option value="faturamento">Faturamento</option>
                        <option value="pedidos">Pedidos</option>
                        <option value="novos_clientes">Novos clientes</option>
                      </select>
                    </div>
                    <div className="field" style={{ margin: 0 }}>
                      <label>Valor alvo</label>
                      <input className="input" type="number" value={editDraft.valor_alvo}
                        onChange={e => setEditDraft({ ...editDraft, valor_alvo: e.target.value })} />
                    </div>
                    <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
                      <Button variant="secondary" size="sm" onClick={() => setEditId(null)}>Cancelar</Button>
                      <Button variant="primary" size="sm" onClick={salvarEdicao}>Salvar</Button>
                    </div>
                  </div>
                </div>
              );
            }

            return (
              <div key={m.id} className="meta-row" style={{ position: 'relative' }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 6 }}>
                  <span style={{ fontSize: 12, fontWeight: 600, color: 'var(--tm-fg-1)' }}>{tipoLabel[m.tipo] || m.tipo}</span>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                    <span style={{ fontSize: 11, color: pct >= 100 ? 'var(--tm-success)' : 'var(--tm-fg-3)', fontVariantNumeric: 'tabular-nums' }}>
                      {isMoney ? `R$ ${brl(atual)}` : atual} / {isMoney ? `R$ ${brl(alvo)}` : alvo}
                    </span>
                    <button onClick={() => iniciarEdicao(m)} title="Editar meta" style={{
                      background: 'none', border: 'none', cursor: 'pointer', padding: 2,
                      color: 'var(--tm-fg-4)', display: 'inline-flex', borderRadius: 4,
                    }}><Icon name="edit-2" size={12} /></button>
                    <button onClick={() => apagarMeta(m)} title="Apagar meta" style={{
                      background: 'none', border: 'none', cursor: 'pointer', padding: 2,
                      color: 'var(--tm-fg-4)', display: 'inline-flex', borderRadius: 4,
                    }}><Icon name="trash-2" size={12} /></button>
                  </div>
                </div>
                <div style={{ background: 'var(--tm-bg-2)', borderRadius: 4, height: 8, overflow: 'hidden' }}>
                  <div style={{
                    width: `${pct}%`, height: '100%', borderRadius: 4, transition: 'width 0.4s',
                    background: pct >= 100 ? 'var(--tm-success)' : pct >= 70 ? 'var(--tm-brand-champagne)' : pct >= 40 ? 'var(--tm-warning)' : 'var(--tm-danger)',
                  }} />
                </div>
                <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 4, fontSize: 10.5, color: 'var(--tm-fg-4)' }}>
                  <span>{pct.toFixed(0)}% atingido</span>
                  <span>Previsão: {isMoney ? `R$ ${brl(previsao)}` : Math.round(previsao)}</span>
                  {diasRestantes > 0 && atual < alvo && (
                    <span style={{ color: 'var(--tm-warning)' }}>
                      {isMoney ? `R$ ${brl(ritmoDiario)}` : Math.ceil(ritmoDiario)}/dia necessário
                    </span>
                  )}
                </div>
              </div>
            );
          })}
          {!showForm && (
            <button onClick={() => setShowForm(true)} style={{
              display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6,
              padding: '8px 0', borderRadius: 6, border: '1px dashed var(--tm-line-2)',
              background: 'transparent', color: 'var(--tm-fg-3)', fontSize: 12, cursor: 'pointer',
              fontFamily: 'inherit',
            }}>
              <Icon name="plus" size={13} /> Adicionar meta
            </button>
          )}
        </div>
      )}
      {showForm && (
        <div style={{ marginTop: 12, padding: 14, background: 'var(--tm-bg-2)', borderRadius: 8, border: '1px solid var(--tm-line-1)' }}>
          <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--tm-fg-1)', marginBottom: 10 }}>Nova meta</div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
            <div className="field" style={{ margin: 0 }}>
              <label>Tipo</label>
              <select className="input" value={draft.tipo} onChange={e => setDraft({ ...draft, tipo: e.target.value })}>
                <option value="faturamento">Faturamento</option>
                <option value="pedidos">Pedidos</option>
                <option value="novos_clientes">Novos clientes</option>
              </select>
            </div>
            <div className="field" style={{ margin: 0 }}>
              <label>Valor alvo</label>
              <input className="input" type="number" placeholder={draft.tipo === 'faturamento' ? 'Ex: 50000' : 'Ex: 30'}
                value={draft.valor_alvo} onChange={e => setDraft({ ...draft, valor_alvo: e.target.value })} />
            </div>
            <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
              <Button variant="secondary" size="sm" onClick={() => setShowForm(false)}>Cancelar</Button>
              <Button variant="primary" size="sm" onClick={salvarMeta}>Salvar</Button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

// ─── Mini Calendário Operacional ─────────────────────────────────────────────
function MiniCalendario() {
  const [events, setEvents] = React.useState(null);
  const [selectedDay, setSelectedDay] = React.useState(null);

  const now = new Date();
  const ano = now.getFullYear();
  const mes = now.getMonth();
  const hojeNum = now.getDate();
  const hojeISO = now.toISOString().slice(0, 10);

  const primeiroDia = new Date(ano, mes, 1).getDay();
  const diasNoMes = new Date(ano, mes + 1, 0).getDate();

  React.useEffect(() => {
    if (!window.tmSupabase) return;
    const mesStart = new Date(ano, mes, 1).toISOString().slice(0, 10);
    const mesEnd = new Date(ano, mes + 1, 0).toISOString().slice(0, 10);

    Promise.all([
      window.tmSupabase.from('contas_receber').select('referencia, cliente_nome, valor, vencimento, status')
        .gte('vencimento', mesStart).lte('vencimento', mesEnd),
      window.tmSupabase.from('contas_pagar').select('referencia, fornecedor, valor, vencimento, status')
        .gte('vencimento', mesStart).lte('vencimento', mesEnd),
      window.tmSupabase.from('pedidos').select('numero, cliente_nome, status, created_at')
        .in('status', ['Em andamento', 'Pendente'])
        .gte('created_at', mesStart + 'T00:00:00').lte('created_at', mesEnd + 'T23:59:59'),
    ]).then(([crRes, cpRes, pedRes]) => {
      const byDay = {};

      const addEvent = (day, evt) => {
        if (!byDay[day]) byDay[day] = [];
        byDay[day].push(evt);
      };

      (crRes.data || []).forEach(c => {
        if (!c.vencimento) return;
        const day = parseInt(c.vencimento.slice(8, 10));
        const vencido = c.vencimento < hojeISO && c.status !== 'Recebido';
        addEvent(day, {
          type: 'receber',
          color: vencido ? 'var(--tm-danger)' : c.status === 'Recebido' ? 'var(--tm-success)' : 'var(--tm-info, #5B9BD5)',
          text: `Receber: ${c.referencia || c.cliente_nome}`,
          valor: `R$ ${brl(parseFloat(c.valor) || 0)}`,
          vencido,
        });
      });

      (cpRes.data || []).forEach(c => {
        if (!c.vencimento) return;
        const day = parseInt(c.vencimento.slice(8, 10));
        const vencido = c.vencimento < hojeISO && c.status !== 'Pago';
        addEvent(day, {
          type: 'pagar',
          color: vencido ? 'var(--tm-danger)' : c.status === 'Pago' ? 'var(--tm-success)' : 'var(--tm-warning)',
          text: `Pagar: ${c.referencia || c.fornecedor}`,
          valor: `R$ ${brl(parseFloat(c.valor) || 0)}`,
          vencido,
        });
      });

      (pedRes.data || []).forEach(p => {
        if (!p.created_at) return;
        const day = new Date(p.created_at).getDate();
        addEvent(day, {
          type: 'pedido',
          color: 'var(--tm-brand-champagne)',
          text: `Pedido ${p.numero}: ${p.cliente_nome}`,
          valor: p.status,
        });
      });

      setEvents(byDay);
    });
  }, []);

  if (!events) return <div style={{ padding: 40, textAlign: 'center', color: 'var(--tm-fg-3)' }}><Icon name="loader" size={20} style={{ opacity: 0.4 }} /></div>;

  const mesLabel = new Date(ano, mes).toLocaleDateString('pt-BR', { month: 'long', year: 'numeric' });
  const diasSemana = ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb'];
  const cells = [];
  for (let i = 0; i < primeiroDia; i++) cells.push(null);
  for (let d = 1; d <= diasNoMes; d++) cells.push(d);

  const dayEvents = selectedDay ? (events[selectedDay] || []) : null;

  return (
    <div>
      <div style={{ textAlign: 'center', fontSize: 12, fontWeight: 600, color: 'var(--tm-fg-1)', marginBottom: 10, textTransform: 'capitalize' }}>
        {mesLabel}
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 2, textAlign: 'center' }}>
        {diasSemana.map(d => (
          <div key={d} style={{ fontSize: 9.5, color: 'var(--tm-fg-4)', fontWeight: 600, padding: '4px 0', textTransform: 'uppercase' }}>{d}</div>
        ))}
        {cells.map((day, i) => {
          if (day === null) return <div key={`e${i}`} />;
          const dayEvts = events[day] || [];
          const isToday = day === hojeNum;
          const isSelected = day === selectedDay;
          const hasVencido = dayEvts.some(e => e.vencido);

          return (
            <div
              key={day}
              onClick={() => setSelectedDay(day === selectedDay ? null : day)}
              style={{
                position: 'relative', padding: '5px 2px', borderRadius: 4, cursor: 'pointer',
                fontSize: 11.5, fontWeight: isToday ? 700 : 400,
                color: isToday ? 'var(--tm-brand-champagne)' : isSelected ? 'var(--tm-fg-1)' : 'var(--tm-fg-2)',
                background: isSelected ? 'rgba(201,163,107,0.15)' : isToday ? 'rgba(201,163,107,0.08)' : 'transparent',
                transition: 'background 0.12s',
              }}
            >
              {day}
              {dayEvts.length > 0 && (
                <div style={{ display: 'flex', justifyContent: 'center', gap: 2, marginTop: 2 }}>
                  {dayEvts.slice(0, 3).map((e, j) => (
                    <div key={j} style={{ width: 4, height: 4, borderRadius: '50%', background: e.color }} />
                  ))}
                </div>
              )}
            </div>
          );
        })}
      </div>
      {dayEvents && dayEvents.length > 0 && (
        <div style={{ marginTop: 10, padding: '8px 0', borderTop: '1px solid var(--tm-line-1)' }}>
          <div style={{ fontSize: 10.5, color: 'var(--tm-fg-4)', marginBottom: 6, fontWeight: 600 }}>
            {selectedDay} de {new Date(ano, mes).toLocaleDateString('pt-BR', { month: 'long' })}
          </div>
          {dayEvents.map((e, i) => (
            <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '4px 0', fontSize: 11.5 }}>
              <div style={{ width: 5, height: 5, borderRadius: '50%', background: e.color, flexShrink: 0 }} />
              <span style={{ color: 'var(--tm-fg-2)', flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{e.text}</span>
              <span style={{ color: 'var(--tm-fg-4)', flexShrink: 0 }}>{e.valor}</span>
            </div>
          ))}
        </div>
      )}
      <div style={{ display: 'flex', gap: 12, justifyContent: 'center', marginTop: 10, fontSize: 10, color: 'var(--tm-fg-4)' }}>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}>
          <span style={{ width: 6, height: 6, borderRadius: '50%', background: 'var(--tm-info, #5B9BD5)' }} /> Receber
        </span>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}>
          <span style={{ width: 6, height: 6, borderRadius: '50%', background: 'var(--tm-warning)' }} /> Pagar
        </span>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}>
          <span style={{ width: 6, height: 6, borderRadius: '50%', background: 'var(--tm-danger)' }} /> Vencido
        </span>
      </div>
    </div>
  );
}

// ─── AI Insights (heuristic, no LLM) ────────────────────────────────────────
function AIInsights({ start, end }) {
  const [insights, setInsights] = React.useState(null);
  const [currentIdx, setCurrentIdx] = React.useState(0);

  React.useEffect(() => {
    if (!window.tmSupabase) return;
    const s0 = start.toISOString();
    const s1 = new Date(end.getTime() + 86400000).toISOString();
    const ha30dias = new Date(Date.now() - 30 * 86400000).toISOString();

    Promise.all([
      window.tmSupabase.from('pedidos').select('total, cliente_nome, created_at, status')
        .eq('status', 'Atendido'),
      window.tmSupabase.from('pedido_itens').select('produto_id, quantidade, preco_lista, descricao, created_at'),
      window.tmSupabase.from('produtos').select('id, nome, estoque, linha'),
      window.tmSupabase.from('distribuidores').select('nome, uf, total_faturado'),
    ]).then(([pedRes, itensRes, prodRes, distRes]) => {
      const peds = pedRes.data || [];
      const itens = itensRes.data || [];
      const prods = prodRes.data || [];
      const dists = distRes.data || [];
      const result = [];

      // Insight: linha com crescimento
      const startDate = new Date(start);
      const endDate = new Date(end);
      const diff = endDate - startDate;
      const prevStart = new Date(startDate.getTime() - diff);
      const prevEnd = new Date(startDate.getTime() - 1);

      const prodMap = {};
      prods.forEach(p => { prodMap[p.id] = p; });

      const linhaAtual = {};
      const linhaPrev = {};
      itens.forEach(it => {
        const prod = prodMap[it.produto_id];
        if (!prod) return;
        const linha = prod.linha || 'Sem linha';
        const dt = new Date(it.created_at);
        const val = (parseFloat(it.quantidade) || 0) * (parseFloat(it.preco_lista) || 0);
        if (dt >= startDate && dt <= endDate) {
          linhaAtual[linha] = (linhaAtual[linha] || 0) + val;
        } else if (dt >= prevStart && dt <= prevEnd) {
          linhaPrev[linha] = (linhaPrev[linha] || 0) + val;
        }
      });

      Object.entries(linhaAtual).forEach(([linha, val]) => {
        const prev = linhaPrev[linha] || 0;
        if (prev > 0) {
          const growth = ((val - prev) / prev * 100);
          if (growth > 15) {
            result.push({ icon: 'trending-up', color: 'var(--tm-success)', text: `A linha ${linha} cresceu ${growth.toFixed(0)}% neste período` });
          } else if (growth < -15) {
            result.push({ icon: 'trending-down', color: 'var(--tm-danger)', text: `A linha ${linha} caiu ${Math.abs(growth).toFixed(0)}% vs período anterior` });
          }
        }
      });

      // Insight: estoque acabando
      const vendaDiaria = {};
      itens.forEach(it => {
        if (!it.produto_id) return;
        const dt = new Date(it.created_at);
        if (dt >= new Date(ha30dias)) {
          vendaDiaria[it.produto_id] = (vendaDiaria[it.produto_id] || 0) + (parseFloat(it.quantidade) || 0);
        }
      });

      prods.forEach(p => {
        const est = parseFloat(p.estoque) || 0;
        const vd = (vendaDiaria[p.id] || 0) / 30;
        if (est > 0 && vd > 0) {
          const dias = Math.floor(est / vd);
          if (dias <= 14 && dias > 0) {
            result.push({ icon: 'alert-triangle', color: 'var(--tm-warning)', text: `Estoque de "${p.nome}" acaba em ${dias} dias no ritmo atual` });
          }
        }
      });

      // Insight: distribuidores inativos
      const lastPedByClient = {};
      peds.forEach(p => {
        const d = new Date(p.created_at);
        if (!lastPedByClient[p.cliente_nome] || d > lastPedByClient[p.cliente_nome]) {
          lastPedByClient[p.cliente_nome] = d;
        }
      });

      let inativos = 0;
      dists.forEach(d => {
        const last = lastPedByClient[d.nome];
        if (last) {
          const dias = Math.floor((Date.now() - last.getTime()) / 86400000);
          if (dias > 45) inativos++;
        }
      });
      if (inativos > 0) {
        result.push({ icon: 'users', color: 'var(--tm-info, #5B9BD5)', text: `${inativos} distribuidor${inativos !== 1 ? 'es' : ''} está${inativos !== 1 ? 'ão' : ''} há mais de 45 dias sem comprar` });
      }

      // Insight: faturamento do período
      const fatAtual = peds.filter(p => new Date(p.created_at) >= startDate && new Date(p.created_at) <= endDate)
        .reduce((a, p) => a + (parseFloat(p.total) || 0), 0);
      const fatPrev = peds.filter(p => new Date(p.created_at) >= prevStart && new Date(p.created_at) <= prevEnd)
        .reduce((a, p) => a + (parseFloat(p.total) || 0), 0);
      if (fatPrev > 0) {
        const growth = ((fatAtual - fatPrev) / fatPrev * 100);
        if (Math.abs(growth) > 5) {
          result.push({
            icon: growth > 0 ? 'arrow-up-right' : 'arrow-down-right',
            color: growth > 0 ? 'var(--tm-success)' : 'var(--tm-danger)',
            text: `Faturamento ${growth > 0 ? 'cresceu' : 'caiu'} ${Math.abs(growth).toFixed(0)}% vs período anterior`,
          });
        }
      }

      // Fallback insight
      if (result.length === 0) {
        result.push({ icon: 'sparkles', color: 'var(--tm-brand-champagne)', text: 'Tudo operando normalmente — sem anomalias detectadas neste período' });
      }

      setInsights(result);
    });
  }, [start.getTime(), end.getTime()]);

  // Auto-rotate
  React.useEffect(() => {
    if (!insights || insights.length <= 1) return;
    const timer = setInterval(() => {
      setCurrentIdx(i => (i + 1) % insights.length);
    }, 6000);
    return () => clearInterval(timer);
  }, [insights]);

  if (!insights) return null;

  const current = insights[currentIdx] || insights[0];
  if (!current) return null;

  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 12, padding: '12px 20px',
      background: 'var(--tm-bg-2)', borderRadius: 8,
      border: '1px solid var(--tm-line-1)',
    }}>
      <div style={{
        width: 28, height: 28, borderRadius: '50%',
        background: 'rgba(201,163,107,0.12)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
      }}>
        <Icon name="sparkles" size={14} style={{ color: 'var(--tm-brand-champagne)' }} />
      </div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 10, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.1em', color: 'var(--tm-brand-champagne)', marginBottom: 2 }}>
          Insight da IA
        </div>
        <div style={{
          display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, color: 'var(--tm-fg-1)',
          overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
        }}>
          <Icon name={current.icon} size={14} style={{ color: current.color, flexShrink: 0 }} />
          {current.text}
        </div>
      </div>
      {insights.length > 1 && (
        <div style={{ display: 'flex', alignItems: 'center', gap: 4, flexShrink: 0 }}>
          <button onClick={() => setCurrentIdx(i => (i - 1 + insights.length) % insights.length)}
            style={{ background: 'none', border: 'none', color: 'var(--tm-fg-3)', cursor: 'pointer', padding: 2 }}>
            <Icon name="chevron-left" size={14} />
          </button>
          <span style={{ fontSize: 10, color: 'var(--tm-fg-4)', fontVariantNumeric: 'tabular-nums' }}>
            {currentIdx + 1}/{insights.length}
          </span>
          <button onClick={() => setCurrentIdx(i => (i + 1) % insights.length)}
            style={{ background: 'none', border: 'none', color: 'var(--tm-fg-3)', cursor: 'pointer', padding: 2 }}>
            <Icon name="chevron-right" size={14} />
          </button>
        </div>
      )}
    </div>
  );
}

Object.assign(window, { SmartAlerts, VendasPorLinha, TopDistribuidores, TopSkus, ActivityFeed, FluxoFinanceiro, RankingComercial, MapaVendas, EstoqueInteligente, RecompraDash, MetasWidget, MiniCalendario, AIInsights });
