// ═══════════════════════════════════════════════════════
// BAUKO CRM — Carteiras (distribuição de clientes por vendedor)
// ═══════════════════════════════════════════════════════
//
// Tela de gestão de carteira comercial:
//   - Cards de vendedor com avatar colorido + contagem de clientes
//   - Drawer com lista de clientes do vendedor selecionado
//   - Modal de transferência (redistribuir cliente entre vendedores)
//   - Card especial "Sem vendedor" para órfãos
//
// Fonte de vendedores: BAUKO_AUTH.getVendedoresAtivos (Lista SP "Usuários").
// Persistência: cliente.vendedor_id (coluna SP "proprietario" — FIELD_MAP em crm-api.js).
//
/* global React, CRM_DATA, CRM_API, BAUKO_AUTH, Badge, Panel, fR */

const { useState: useCartState, useEffect: useCartEffect, useMemo: useCartMemo } = React;

function _escHtml(s) {
  return String(s || '').replace(/[&<>"']/g, function(c) {
    return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c];
  });
}

const SEM_VENDEDOR_ID    = '__sem_vendedor__';
const PAGE_SIZE_CARTEIRA = 50;
const GRUPOS_CARTEIRA    = ['comercial', 'gerencia', 'BDR'];  // mesmos do dropdown do ClienteModal

// ── Conversão UF (sigla ↔ nome completo do estado) ────
// Usado pelo MapaCarteiras pra casar o GeoJSON do Brasil (que vem com nomes completos)
// com o campo c.uf dos clientes (que é sigla 2 letras).
const UF_NOMES = {
  AC: 'Acre', AL: 'Alagoas', AP: 'Amapá', AM: 'Amazonas', BA: 'Bahia',
  CE: 'Ceará', DF: 'Distrito Federal', ES: 'Espírito Santo', GO: 'Goiás',
  MA: 'Maranhão', MT: 'Mato Grosso', MS: 'Mato Grosso do Sul', MG: 'Minas Gerais',
  PA: 'Pará', PB: 'Paraíba', PR: 'Paraná', PE: 'Pernambuco', PI: 'Piauí',
  RJ: 'Rio de Janeiro', RN: 'Rio Grande do Norte', RS: 'Rio Grande do Sul',
  RO: 'Rondônia', RR: 'Roraima', SC: 'Santa Catarina', SP: 'São Paulo',
  SE: 'Sergipe', TO: 'Tocantins',
};
const NOMES_UF = Object.keys(UF_NOMES).reduce(function(acc, k) { acc[UF_NOMES[k]] = k; return acc; }, {});

// URLs externas (cache em localStorage após primeira carga)
const BRASIL_GEOJSON_URL  = 'https://raw.githubusercontent.com/codeforamerica/click_that_hood/master/public/data/brazil-states.geojson';
const MUNICIPIOS_JSON_URL = 'municipios.json';  // hospedado no Netlify junto ao CRM
const CACHE_KEY_GEO       = 'bauko_brasil_geojson_v1';
const CACHE_KEY_MUN       = 'bauko_municipios_v1';

// ── Helpers ───────────────────────────────────────────
function getClienteVendedor(c) {
  // Compatível com pós-deploy (vendedor_id) e pré-deploy (proprietario).
  return (c.vendedor_id || c.proprietario || '').trim();
}

function iniciaisDe(nome) {
  return String(nome || '?').split(' ').map(p => p[0] || '').slice(0, 2).join('').toUpperCase();
}

function getVendedoresParaTransferir() {
  if (window.BAUKO_AUTH && typeof window.BAUKO_AUTH.getVendedoresAtivos === 'function') {
    return window.BAUKO_AUTH.getVendedoresAtivos({ gruposPermitidos: GRUPOS_CARTEIRA }) || [];
  }
  return [];
}

function getVendedoresAtivosByEmail() {
  // Mapa { emailLower: { id, nome, cor, grupo, cargo } } — usado pra hidratar cards.
  var byEmail = {};
  if (window.BAUKO_AUTH && typeof window.BAUKO_AUTH.getVendedoresAtivos === 'function') {
    var lista = window.BAUKO_AUTH.getVendedoresAtivos() || [];
    lista.forEach(function(v) {
      if (v && v.id) byEmail[v.id.toLowerCase()] = v;
    });
  }
  return byEmail;
}

// ════════════════════════════════════════════════════════════
// MODAL — Transferir cliente entre vendedores
// ════════════════════════════════════════════════════════════
function TransferirCarteiraModal({ cliente, vendedorAtual, vendedoresDisp, onClose, onConfirm }) {
  const [novoVendedor, setNovoVendedor] = useCartState('');
  const [salvando, setSalvando] = useCartState(false);
  const [erro, setErro] = useCartState(null);

  useCartEffect(() => {
    setNovoVendedor('');
    setSalvando(false);
    setErro(null);
  }, [cliente && cliente.id]);

  useCartEffect(() => {
    try { window.lucide && window.lucide.createIcons({ attrs: { 'stroke-width': 1.75 } }); } catch (e) {}
  });

  if (!cliente) return null;

  function handleConfirmar() {
    if (!novoVendedor) { setErro('Selecione o novo vendedor'); return; }
    if (novoVendedor === (vendedorAtual && vendedorAtual.email)) {
      setErro('Esse já é o vendedor atual do cliente');
      return;
    }
    setSalvando(true);
    setErro(null);
    Promise.resolve(onConfirm(novoVendedor === SEM_VENDEDOR_ID ? '' : novoVendedor))
      .catch(function(e) { setErro('Erro: ' + (e && e.message || e)); })
      .finally(function() { setSalvando(false); });
  }

  // Dropdown: opção "sem vendedor" + todos os ativos (exceto o atual)
  var opcoes = vendedoresDisp.filter(function(v) {
    return !vendedorAtual || v.id !== vendedorAtual.email;
  });

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal-box" style={{ maxWidth: 480 }} onClick={function(e) { e.stopPropagation(); }}>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 14 }}>
          <div>
            <div className="modal-title">Transferir cliente</div>
            <div className="modal-sub" style={{ marginTop: 6 }}>
              {cliente.razao}
              {cliente.cidade ? ' · ' + cliente.cidade + (cliente.uf ? '/' + cliente.uf : '') : ''}
            </div>
          </div>
          <button className="modal-close-btn" onClick={onClose} title="Fechar">
            <i data-lucide="x"></i>
          </button>
        </div>

        {/* Vendedor atual */}
        <div style={{
          background: 'var(--surface-2)', border: '1px solid var(--border)',
          borderRadius: 'var(--r-md)', padding: '10px 12px', marginBottom: 12,
          display: 'flex', alignItems: 'center', gap: 10,
        }}>
          <div style={{
            width: 32, height: 32, borderRadius: '50%',
            background: vendedorAtual ? vendedorAtual.cor : 'var(--tx-3)',
            color: '#fff', display: 'grid', placeItems: 'center',
            font: '600 11px/1 var(--ff-body)', flexShrink: 0,
          }}>
            {vendedorAtual ? iniciaisDe(vendedorAtual.nome) : '?'}
          </div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ font: '400 10px/1 var(--ff-body)', color: 'var(--tx-3)', textTransform: 'uppercase', letterSpacing: '.07em' }}>
              Vendedor atual
            </div>
            <div style={{ font: '500 13px/1.3 var(--ff-body)', color: 'var(--tx)', marginTop: 4 }}>
              {vendedorAtual ? vendedorAtual.nome : '(sem vendedor atribuído)'}
            </div>
          </div>
        </div>

        {/* Dropdown novo vendedor */}
        <div className="f" style={{ marginBottom: 14 }}>
          <label>Novo vendedor responsável</label>
          <select className="inp select" value={novoVendedor}
            onChange={function(e) { setNovoVendedor(e.target.value); setErro(null); }}>
            <option value="">— Selecione —</option>
            <option value={SEM_VENDEDOR_ID}>Sem vendedor (deixar órfão)</option>
            <option disabled>──────────</option>
            {opcoes.map(function(v) {
              return <option key={v.id} value={v.id}>{v.nome} · {v.grupo}</option>;
            })}
          </select>
        </div>

        {erro && (
          <div style={{
            padding: '10px 12px', background: 'var(--danger-050)', border: '1px solid var(--danger)',
            borderRadius: 'var(--r-sm)', font: '400 12px/1.4 var(--ff-body)', color: 'var(--danger)', marginBottom: 12,
          }}>
            {erro}
          </div>
        )}

        <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
          <button className="btn btn-secondary" onClick={onClose} disabled={salvando}>Cancelar</button>
          <button className="btn btn-primary" onClick={handleConfirmar} disabled={salvando}>
            {salvando
              ? <><i data-lucide="loader" style={{ width: 13, height: 13 }}></i> Transferindo...</>
              : <><i data-lucide="arrow-right-left" style={{ width: 13, height: 13 }}></i> Confirmar transferência</>
            }
          </button>
        </div>
      </div>
    </div>
  );
}

// ════════════════════════════════════════════════════════════
// CARD — Vendedor (com avatar, barra proporcional, contagem)
// ════════════════════════════════════════════════════════════
function VendedorCard({ vendedor, qtd, maxQtd, selecionado, onClick }) {
  var pct = maxQtd > 0 ? (qtd / maxQtd) * 100 : 0;
  return (
    <div onClick={onClick}
      style={{
        background: selecionado ? 'var(--grn-050)' : 'var(--surface)',
        border: '1px solid ' + (selecionado ? 'var(--grn)' : 'var(--border)'),
        borderRadius: 'var(--r-lg)',
        padding: 14,
        cursor: 'pointer',
        boxShadow: selecionado ? '0 4px 12px rgba(0,124,68,.12)' : 'var(--shadow-1)',
        transition: 'all 150ms ease',
        display: 'flex', flexDirection: 'column', gap: 10,
        opacity: vendedor.ativoNaWhitelist ? 1 : 0.75,
      }}
      onMouseEnter={function(e) { if (!selecionado) e.currentTarget.style.borderColor = 'var(--border-2)'; }}
      onMouseLeave={function(e) { if (!selecionado) e.currentTarget.style.borderColor = 'var(--border)'; }}
    >
      <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <div style={{
          width: 38, height: 38, borderRadius: '50%',
          background: vendedor.cor || 'var(--grn)',
          color: '#fff', display: 'grid', placeItems: 'center',
          font: '600 13px/1 var(--ff-body)', flexShrink: 0,
        }}>
          {iniciaisDe(vendedor.nome)}
        </div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{
            font: '500 13px/1.2 var(--ff-body)', color: 'var(--tx)',
            overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
          }} title={vendedor.nome}>
            {vendedor.nome}
          </div>
          <div style={{ font: '400 10px/1.2 var(--ff-mono)', color: 'var(--tx-3)', marginTop: 3 }}>
            {vendedor.grupo}{!vendedor.ativoNaWhitelist ? ' · inativo' : ''}
          </div>
        </div>
      </div>
      <div>
        <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 5 }}>
          <span style={{ font: '400 28px/1 var(--ff-display)', color: 'var(--grn)', letterSpacing: '.02em' }}>
            {qtd.toLocaleString('pt-BR')}
          </span>
          <span style={{ font: '400 11px/1 var(--ff-body)', color: 'var(--tx-3)' }}>
            {qtd === 1 ? 'cliente' : 'clientes'}
          </span>
        </div>
        {/* Barra proporcional */}
        <div style={{ height: 4, background: 'var(--gry-100)', borderRadius: 2, overflow: 'hidden' }}>
          <div style={{
            height: '100%',
            width: pct + '%',
            background: vendedor.cor || 'var(--grn)',
            borderRadius: 2,
            transition: 'width 200ms ease',
          }}></div>
        </div>
      </div>
    </div>
  );
}

// ════════════════════════════════════════════════════════════
// CARD — "Sem vendedor" (órfãos)
// ════════════════════════════════════════════════════════════
function SemVendedorCard({ qtd, selecionado, onClick }) {
  return (
    <div onClick={onClick}
      style={{
        background: selecionado ? 'var(--warn-050)' : 'var(--surface)',
        border: '1px dashed ' + (selecionado ? 'var(--warn)' : 'var(--border-2)'),
        borderRadius: 'var(--r-lg)',
        padding: 14,
        cursor: 'pointer',
        boxShadow: selecionado ? '0 4px 12px rgba(244,163,0,.15)' : 'none',
        transition: 'all 150ms ease',
        display: 'flex', flexDirection: 'column', gap: 10,
      }}
    >
      <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <div style={{
          width: 38, height: 38, borderRadius: '50%',
          background: 'var(--warn)',
          color: '#fff', display: 'grid', placeItems: 'center', flexShrink: 0,
        }}>
          <i data-lucide="user-x" style={{ width: 18, height: 18 }}></i>
        </div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ font: '500 13px/1.2 var(--ff-body)', color: 'var(--tx)' }}>
            Sem vendedor
          </div>
          <div style={{ font: '400 10px/1.2 var(--ff-mono)', color: 'var(--tx-3)', marginTop: 3 }}>
            precisa atribuição
          </div>
        </div>
      </div>
      <div>
        <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between' }}>
          <span style={{ font: '400 28px/1 var(--ff-display)', color: 'var(--warn)', letterSpacing: '.02em' }}>
            {qtd.toLocaleString('pt-BR')}
          </span>
          <span style={{ font: '400 11px/1 var(--ff-body)', color: 'var(--tx-3)' }}>
            órfão{qtd === 1 ? '' : 's'}
          </span>
        </div>
      </div>
    </div>
  );
}

// ════════════════════════════════════════════════════════════
// LISTA — Clientes do vendedor selecionado (com filtros + paginação)
// ════════════════════════════════════════════════════════════
function ListaClientesCarteira({ vendedor, clientes, onTransferir, onBack, onOpenCliente }) {
  const [search, setSearch] = useCartState("");
  const [ufFilter, setUfFilter] = useCartState("");
  const [page, setPage] = useCartState(1);

  useCartEffect(() => { setPage(1); }, [search, ufFilter, vendedor && vendedor.email]);
  useCartEffect(() => {
    try { window.lucide && window.lucide.createIcons({ attrs: { 'stroke-width': 1.75 } }); } catch (e) {}
  });

  // Opções de UF derivadas da carteira do vendedor (não da base toda)
  const ufOptions = useCartMemo(function() {
    var set = {};
    clientes.forEach(function(c) {
      var u = (c.uf || '').toUpperCase().slice(0, 2);
      if (u) set[u] = (set[u] || 0) + 1;
    });
    return Object.keys(set).sort().map(function(k) { return { uf: k, n: set[k] }; });
  }, [clientes]);

  // Filtragem
  const filtered = clientes
    .filter(function(c) { return !ufFilter || (c.uf || '').toUpperCase().slice(0, 2) === ufFilter; })
    .filter(function(c) {
      if (!search.trim()) return true;
      var s = search.toLowerCase();
      return (
        (c.razao || '').toLowerCase().includes(s) ||
        (c.cidade || '').toLowerCase().includes(s) ||
        (c.cnpj || '').includes(s) ||
        (c.cpf || '').includes(s) ||
        (c.segmento || '').toLowerCase().includes(s)
      );
    });

  const visiveis = filtered.slice(0, page * PAGE_SIZE_CARTEIRA);
  const temMais = visiveis.length < filtered.length;

  return (
    <div className="panel">
      {/* Header */}
      <div className="panel__hd" style={{ padding: '14px 18px', gap: 12, flexWrap: 'wrap' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, flex: 1, minWidth: 0 }}>
          <button className="btn btn-ghost" onClick={onBack} style={{ padding: '6px 10px' }} title="Voltar">
            <i data-lucide="arrow-left" style={{ width: 14, height: 14 }}></i>
          </button>
          <div style={{
            width: 36, height: 36, borderRadius: '50%',
            background: vendedor.cor || 'var(--grn)',
            color: '#fff', display: 'grid', placeItems: 'center',
            font: '600 13px/1 var(--ff-body)', flexShrink: 0,
          }}>
            {vendedor.email === SEM_VENDEDOR_ID
              ? <i data-lucide="user-x" style={{ width: 16, height: 16 }}></i>
              : iniciaisDe(vendedor.nome)
            }
          </div>
          <div style={{ minWidth: 0 }}>
            <h3 style={{ margin: 0 }}>{vendedor.nome}</h3>
            <div className="meta" style={{ margin: 0, marginTop: 3 }}>
              {clientes.length.toLocaleString('pt-BR')} {clientes.length === 1 ? 'cliente na carteira' : 'clientes na carteira'}
              {vendedor.grupo ? ' · ' + vendedor.grupo : ''}
            </div>
          </div>
        </div>
        {/* Filtros */}
        <div style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }}>
          <select className="inp select" value={ufFilter} onChange={function(e) { setUfFilter(e.target.value); }}
            style={{ minWidth: 90, padding: '7px 28px 7px 10px', fontSize: 12 }}>
            <option value="">UF</option>
            {ufOptions.map(function(o) { return <option key={o.uf} value={o.uf}>{o.uf} ({o.n})</option>; })}
          </select>
          <div className="tb__search" style={{ minWidth: 200 }}>
            <i data-lucide="search"></i>
            <input placeholder="Razão, CNPJ, cidade..." value={search} onChange={function(e) { setSearch(e.target.value); }} />
          </div>
        </div>
      </div>

      {/* Tabela */}
      {clientes.length === 0 ? (
        <div style={{ padding: '48px 0', textAlign: 'center', color: 'var(--tx-3)' }}>
          <i data-lucide="briefcase" style={{ width: 24, height: 24, display: 'block', margin: '0 auto 10px' }}></i>
          <div style={{ font: '500 13px/1 var(--ff-body)', color: 'var(--tx-2)' }}>
            Carteira vazia
          </div>
        </div>
      ) : filtered.length === 0 ? (
        <div style={{ padding: '48px 0', textAlign: 'center', color: 'var(--tx-3)' }}>
          <i data-lucide="search-x" style={{ width: 24, height: 24, display: 'block', margin: '0 auto 10px' }}></i>
          <div style={{ font: '500 13px/1 var(--ff-body)', color: 'var(--tx-2)', marginBottom: 8 }}>
            Nenhum cliente encontrado
          </div>
          <button className="btn btn-ghost" style={{ fontSize: 12 }}
            onClick={function() { setSearch(''); setUfFilter(''); }}>Limpar filtros</button>
        </div>
      ) : (
        <>
          <div className="dt-wrap">
            <table className="dt">
              <thead>
                <tr>
                  <th>Razão social</th>
                  <th>Cidade/UF</th>
                  <th>Segmento</th>
                  <th style={{ textAlign: 'right' }}>Vol. anual</th>
                  <th>Status</th>
                  <th style={{ textAlign: 'center', width: 110 }}>Ações</th>
                </tr>
              </thead>
              <tbody>
                {visiveis.map(function(c) {
                  return (
                    <tr key={c.id}
                      style={{ cursor: 'pointer', opacity: c.status === 'inativo' ? 0.55 : 1 }}
                      onClick={function() { onOpenCliente && onOpenCliente(c.id); }}
                    >
                      <td>
                        <div style={{ font: '500 13px/1.2 var(--ff-body)', color: 'var(--tx)' }}>{c.razao}</div>
                        <div style={{ font: '400 11px/1 var(--ff-mono)', color: 'var(--tx-3)', marginTop: 2 }}>
                          {c.cnpj || c.cpf || '—'}
                        </div>
                      </td>
                      <td className="tx2" style={{ fontSize: 12 }}>
                        {c.cidade ? c.cidade + (c.uf ? '/' + c.uf : '') : (c.uf || '—')}
                      </td>
                      <td className="tx2" style={{ fontSize: 12 }}>{c.segmento || '—'}</td>
                      <td className="num">{fR(c.volume_anual)}</td>
                      <td><Badge status={c.status} /></td>
                      <td style={{ textAlign: 'center' }} onClick={function(e) { e.stopPropagation(); }}>
                        <button className="btn btn-ghost"
                          style={{ fontSize: 11, padding: '5px 10px', gap: 4 }}
                          onClick={function() { onTransferir(c); }}
                          title="Transferir para outro vendedor">
                          <i data-lucide="arrow-right-left" style={{ width: 12, height: 12 }}></i>
                          Transferir
                        </button>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
          {(temMais || filtered.length > PAGE_SIZE_CARTEIRA) && (
            <div style={{
              padding: '14px 18px', borderTop: '1px solid var(--border)',
              display: 'flex', alignItems: 'center', justifyContent: 'space-between',
              gap: 12, flexWrap: 'wrap',
            }}>
              <div style={{ font: '400 12px/1.4 var(--ff-body)', color: 'var(--tx-3)' }}>
                Mostrando <strong style={{ color: 'var(--tx-2)' }}>{visiveis.length.toLocaleString('pt-BR')}</strong> de <strong style={{ color: 'var(--tx-2)' }}>{filtered.length.toLocaleString('pt-BR')}</strong> {filtered.length === 1 ? 'cliente' : 'clientes'}
              </div>
              {temMais && (
                <button className="btn btn-secondary" onClick={function() { setPage(function(p) { return p + 1; }); }}
                  style={{ fontSize: 12 }}>
                  <i data-lucide="chevrons-down" style={{ width: 13, height: 13 }}></i>
                  Carregar mais {Math.min(PAGE_SIZE_CARTEIRA, filtered.length - visiveis.length).toLocaleString('pt-BR')}
                </button>
              )}
            </div>
          )}
        </>
      )}
    </div>
  );
}

// ════════════════════════════════════════════════════════════
// MAPA — Leaflet com drill-down UF → markers por município
// ════════════════════════════════════════════════════════════
function MapaCarteiras({ clientes, vendedoresInfo }) {
  const containerRef     = React.useRef(null);
  const mapRef           = React.useRef(null);
  const polygonsLayerRef = React.useRef(null);
  const markersLayerRef  = React.useRef(null);

  const [status, setStatus]   = useCartState('loading');     // 'loading' | 'ready' | 'error'
  const [statusMsg, setStatusMsg] = useCartState('');
  const [drillDown, setDrillDown] = useCartState(null);      // sigla UF ou null
  const [geoBrasil, setGeoBrasil] = useCartState(null);
  const [municipios, setMunicipios] = useCartState(null);
  const [filtroVendedor, setFiltroVendedor] = useCartState(''); // '' = todos | email do vendedor

  // ── Lista de vendedores p/ dropdown (todos com clientes na base atual) ────
  const vendedoresOptions = useCartMemo(function() {
    var emails = {};
    clientes.forEach(function(c) {
      var v = ((c.vendedor_id || c.proprietario || '') + '').toLowerCase().trim();
      if (v) emails[v] = (emails[v] || 0) + 1;
    });
    return Object.keys(emails).map(function(e) {
      var info = vendedoresInfo[e];
      return { email: e, nome: info ? info.nome : e.split('@')[0], qtd: emails[e], cor: info ? info.cor : '#9ca3af' };
    }).sort(function(a, b) {
      return (a.nome || '').localeCompare(b.nome || '', 'pt-BR');
    });
  }, [clientes, vendedoresInfo]);

  // ── Clientes efetivamente exibidos (aplica filtro de vendedor) ────────────
  const clientesFiltrados = useCartMemo(function() {
    if (!filtroVendedor) return clientes;
    return clientes.filter(function(c) {
      var v = ((c.vendedor_id || c.proprietario || '') + '').toLowerCase().trim();
      return v === filtroVendedor;
    });
  }, [clientes, filtroVendedor]);

  // ── Contagem por UF + vendedor (memo, já filtrado) ──────
  const uf2Vend = useCartMemo(function() {
    var m = {};
    clientesFiltrados.forEach(function(c) {
      var uf = (c.uf || '').toUpperCase().slice(0, 2);
      var v  = ((c.vendedor_id || c.proprietario || '') + '').toLowerCase().trim();
      if (!uf || !v) return;
      if (!m[uf]) m[uf] = {};
      m[uf][v] = (m[uf][v] || 0) + 1;
    });
    return m;
  }, [clientesFiltrados]);

  // ── Cor do estado (dominante) ──────────────────────────
  function corDoEstado(uf) {
    var m = uf2Vend[uf];
    if (!m) return '#e5e7eb';   // cinza neutro
    var ranked = Object.keys(m).sort(function(a, b) { return m[b] - m[a]; });
    var info = vendedoresInfo[ranked[0]];
    return info ? info.cor : '#9ca3af';
  }

  // ── Tooltip rico ────────────────────────────────────────
  function tooltipDoEstado(uf) {
    var m = uf2Vend[uf] || {};
    var emails = Object.keys(m);
    var total = emails.reduce(function(s, e) { return s + m[e]; }, 0);
    if (total === 0) return '<div style="font-weight:600">' + uf + '</div><div style="color:#666">Sem clientes</div>';
    var ranked = emails.sort(function(a, b) { return m[b] - m[a]; }).slice(0, 5);
    var html = '<div style="font-weight:600;margin-bottom:4px">' + (UF_NOMES[uf] || uf) + ' — ' + total + ' cliente' + (total > 1 ? 's' : '') + '</div>';
    ranked.forEach(function(email) {
      var v = vendedoresInfo[email];
      var nome = v ? v.nome : email;
      var pct = Math.round(m[email] / total * 100);
      var cor = v ? v.cor : '#9ca3af';
      html += '<div style="display:flex;align-items:center;gap:6px;line-height:1.4">'
            + '<span style="width:8px;height:8px;border-radius:50%;background:' + cor + ';display:inline-block;flex-shrink:0"></span>'
            + '<span>' + nome + ': ' + m[email] + ' (' + pct + '%)</span></div>';
    });
    var sobra = emails.length - ranked.length;
    if (sobra > 0) html += '<div style="color:#666;font-size:11px;margin-top:3px">+ ' + sobra + ' vendedor' + (sobra > 1 ? 'es' : '') + '</div>';
    html += '<div style="font-size:10px;color:#999;margin-top:6px">Clique para ver clientes</div>';
    return html;
  }

  // ── Carrega GeoJSON Brasil + municipios.json (com cache) ─
  useCartEffect(function() {
    var cancel = false;
    if (typeof window.L === 'undefined') {
      setStatus('error');
      setStatusMsg('Leaflet não carregou. Recarregue a página.');
      return;
    }
    setStatus('loading');

    function tryCache(key) {
      try { var raw = localStorage.getItem(key); if (raw) return JSON.parse(raw); } catch (e) {}
      return null;
    }
    function setCache(key, data) {
      try { localStorage.setItem(key, JSON.stringify(data)); } catch (e) { /* quota? */ }
    }

    var cachedGeo = tryCache(CACHE_KEY_GEO);
    var cachedMun = tryCache(CACHE_KEY_MUN);

    var pGeo = cachedGeo
      ? Promise.resolve(cachedGeo)
      : fetch(BRASIL_GEOJSON_URL).then(function(r) { return r.json(); }).then(function(d) { setCache(CACHE_KEY_GEO, d); return d; });

    var pMun = cachedMun
      ? Promise.resolve(cachedMun)
      : fetch(MUNICIPIOS_JSON_URL).then(function(r) { return r.json(); }).then(function(d) { setCache(CACHE_KEY_MUN, d); return d; });

    Promise.all([pGeo, pMun]).then(function(arr) {
      if (cancel) return;
      setGeoBrasil(arr[0]);
      setMunicipios(arr[1]);
      setStatus('ready');
    }).catch(function(e) {
      if (cancel) return;
      console.error('[MapaCarteiras] erro ao carregar dados:', e);
      setStatus('error');
      setStatusMsg('Erro ao carregar dados do mapa: ' + (e.message || e));
    });

    return function() { cancel = true; };
  }, []);

  // ── Inicializa o mapa Leaflet quando dados prontos ─────
  useCartEffect(function() {
    if (status !== 'ready' || mapRef.current || !containerRef.current) return;
    var L = window.L;
    var map = L.map(containerRef.current, {
      center: [-15.78, -52.92],
      zoom: 4,
      minZoom: 3,
      zoomControl: true,
    });
    L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png', {
      attribution: '© OpenStreetMap, © CARTO',
      subdomains: 'abcd',
      maxZoom: 19,
    }).addTo(map);
    mapRef.current = map;
    // Força recalculo de tamanho (Leaflet às vezes nasce com 0 de altura)
    setTimeout(function() { try { map.invalidateSize(); } catch (e) {} }, 100);
  }, [status]);

  // ── Renderiza polígonos OU markers conforme drillDown ──
  useCartEffect(function() {
    if (status !== 'ready' || !mapRef.current) return;
    var L = window.L;
    var map = mapRef.current;

    // Limpa camadas existentes
    if (polygonsLayerRef.current) { map.removeLayer(polygonsLayerRef.current); polygonsLayerRef.current = null; }
    if (markersLayerRef.current)  { map.removeLayer(markersLayerRef.current);  markersLayerRef.current  = null; }

    if (!drillDown) {
      // ── Modo Brasil: renderiza polígonos dos estados ────
      if (!geoBrasil) return;
      var layer = L.geoJSON(geoBrasil, {
        style: function(feature) {
          var uf = NOMES_UF[feature.properties.name] || '';
          return {
            fillColor: corDoEstado(uf),
            fillOpacity: 0.72,
            weight: 1.2,
            color: '#fff',
          };
        },
        onEachFeature: function(feature, lyr) {
          var uf = NOMES_UF[feature.properties.name] || feature.properties.name;
          lyr.bindTooltip(tooltipDoEstado(uf), { sticky: true, direction: 'top' });
          lyr.on('mouseover', function(e) { e.target.setStyle({ fillOpacity: 0.92, weight: 2 }); });
          lyr.on('mouseout',  function(e) { e.target.setStyle({ fillOpacity: 0.72, weight: 1.2 }); });
          lyr.on('click',     function() { setDrillDown(uf); });
        },
      }).addTo(map);
      polygonsLayerRef.current = layer;
      try { map.fitBounds(layer.getBounds(), { padding: [10, 10] }); } catch (e) {}
    } else {
      // ── Modo drill-down: markers por município ─────────
      if (!municipios) return;
      var cluster = L.markerClusterGroup({
        maxClusterRadius: 50,
        spiderfyOnMaxZoom: true,
        showCoverageOnHover: false,
      });

      var clientesUF = clientesFiltrados.filter(function(c) { return (c.uf || '').toUpperCase().slice(0, 2) === drillDown; });
      var semCoord = 0;

      clientesUF.forEach(function(c) {
        var cidade = (c.cidade || '').trim();
        if (!cidade) { semCoord++; return; }
        var coords = municipios[cidade + '|' + drillDown];
        if (!coords) {
          // Fallback: tenta normalizando acentos
          var semAcento = cidade.normalize('NFD').replace(/[̀-ͯ]/g, '');
          coords = municipios[semAcento + '|' + drillDown];
        }
        if (!coords) { semCoord++; return; }

        var v = ((c.vendedor_id || c.proprietario || '') + '').toLowerCase().trim();
        var info = v ? vendedoresInfo[v] : null;
        var cor  = info ? info.cor : (v ? '#9ca3af' : '#e5a700');

        var icon = L.divIcon({
          className: 'bauko-mapa-marker',
          html: '<div style="width:14px;height:14px;border-radius:50%;background:' + cor + ';border:2px solid #fff;box-shadow:0 1px 3px rgba(0,0,0,.35)"></div>',
          iconSize: [14, 14],
          iconAnchor: [7, 7],
        });

        var marker = L.marker(coords, { icon: icon });
        marker.bindTooltip(
          '<div style="font-weight:600">' + _escHtml(c.razao || '(sem razão)') + '</div>'
          + '<div style="font-size:11px;color:#666">' + _escHtml(cidade) + '/' + _escHtml(drillDown) + '</div>'
          + '<div style="font-size:11px;color:#666">Vendedor: ' + _escHtml(info ? info.nome : (v || 'sem atribuição')) + '</div>',
          { direction: 'top' }
        );
        cluster.addLayer(marker);
      });

      cluster.addTo(map);
      markersLayerRef.current = cluster;
      try {
        var bounds = cluster.getBounds();
        if (bounds.isValid()) map.fitBounds(bounds, { padding: [40, 40] });
      } catch (e) {}

      if (semCoord > 0) {
        console.warn('[MapaCarteiras] ' + semCoord + ' clientes em ' + drillDown + ' sem coordenadas (cidade nao encontrada nos centroides IBGE)');
      }
    }
  }, [status, geoBrasil, municipios, clientesFiltrados, drillDown, vendedoresInfo]);

  // -- Cleanup ao unmount --
  useCartEffect(function() {
    return function() {
      if (mapRef.current) {
        try { mapRef.current.remove(); } catch (e) {}
        mapRef.current = null;
      }
    };
  }, []);

  // -- Legenda: top vendedores (geral ou da UF em drill-down) --
  const topVendedores = useCartMemo(function() {
    var fonte = drillDown
      ? clientesFiltrados.filter(function(c) { return (c.uf || '').toUpperCase().slice(0, 2) === drillDown; })
      : clientesFiltrados;
    var totais = {};
    fonte.forEach(function(c) {
      var v = ((c.vendedor_id || c.proprietario || '') + '').toLowerCase().trim();
      if (v) totais[v] = (totais[v] || 0) + 1;
    });
    return Object.keys(totais)
      .map(function(email) { return { email: email, qtd: totais[email], info: vendedoresInfo[email] }; })
      .sort(function(a, b) { return b.qtd - a.qtd; })
      .slice(0, 10);
  }, [clientesFiltrados, vendedoresInfo, drillDown]);

  useCartEffect(function() {
    try { window.lucide && window.lucide.createIcons({ attrs: { 'stroke-width': 1.75 } }); } catch (e) {}
  });

  var totalNoMapa = drillDown
    ? clientesFiltrados.filter(function(c) { return (c.uf || '').toUpperCase().slice(0, 2) === drillDown; }).length
    : clientesFiltrados.length;

  return (
    <div className="panel">
      <div className="panel__hd" style={{ flexWrap: 'wrap', gap: 10 }}>
        <h3 style={{ margin: 0 }}>
          {drillDown ? (UF_NOMES[drillDown] || drillDown) : 'Brasil — distribuicao por estado'}
        </h3>
        {drillDown && (
          <button className="btn btn-secondary" style={{ fontSize: 12, marginLeft: 8 }}
            onClick={function() { setDrillDown(null); }}>
            <i data-lucide="arrow-left" style={{ width: 13, height: 13 }}></i>
            Voltar ao Brasil
          </button>
        )}
        <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginLeft: 'auto' }}>
          <label style={{ font: '500 11px/1 var(--ff-body)', color: 'var(--tx-3)', textTransform: 'uppercase', letterSpacing: '.06em' }}>
            Vendedor:
          </label>
          <select value={filtroVendedor} onChange={function(e){ setFiltroVendedor(e.target.value); }}
            style={{ padding: '4px 8px', fontSize: 12, border: '1px solid var(--border)',
                     borderRadius: 'var(--r-xs)', background: 'var(--surface-1)', color: 'var(--tx)',
                     minWidth: 200, maxWidth: 260 }}>
            <option value="">Todos ({clientes.length.toLocaleString('pt-BR')})</option>
            {vendedoresOptions.map(function(v) {
              return (
                <option key={v.email} value={v.email}>
                  {v.nome} · {v.qtd}
                </option>
              );
            })}
          </select>
          {filtroVendedor && (
            <button onClick={function(){ setFiltroVendedor(''); }}
              title="Limpar filtro"
              style={{ padding: '3px 8px', fontSize: 11, border: '1px solid var(--border)',
                       borderRadius: 'var(--r-xs)', background: 'var(--surface-2)', color: 'var(--tx-3)',
                       cursor: 'pointer' }}>✕</button>
          )}
        </div>
        <div className="meta">
          {totalNoMapa.toLocaleString('pt-BR')} {totalNoMapa === 1 ? 'cliente' : 'clientes'}
        </div>
      </div>
      <div style={{ position: 'relative' }}>
        <div ref={containerRef} style={{ height: 560, width: '100%' }}></div>
        {status === 'loading' && (
          <div style={{
            position: 'absolute', inset: 0, background: 'rgba(255,255,255,.95)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            zIndex: 999, flexDirection: 'column', gap: 12,
          }}>
            <div style={{ font: '600 14px/1 var(--ff-body)', color: 'var(--tx-2)' }}>Carregando mapa...</div>
            <div style={{ width: 180, height: 2, background: 'var(--border)', borderRadius: 2, overflow: 'hidden' }}>
              <div style={{ height: '100%', background: 'var(--grn)', borderRadius: 2, animation: 'crmLoad 1.4s ease-in-out infinite', width: '60%' }}></div>
            </div>
          </div>
        )}
        {status === 'error' && (
          <div style={{
            position: 'absolute', inset: 0, background: 'rgba(255,255,255,.95)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            zIndex: 999, flexDirection: 'column', gap: 10, padding: 20,
          }}>
            <i data-lucide="alert-triangle" style={{ width: 24, height: 24, color: 'var(--danger)' }}></i>
            <div style={{ font: '600 13px/1.4 var(--ff-body)', color: 'var(--tx)', textAlign: 'center', maxWidth: 360 }}>
              {statusMsg || 'Erro ao carregar o mapa'}
            </div>
          </div>
        )}
      </div>
      <div style={{
        padding: '10px 18px', borderTop: '1px solid var(--border)',
        display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap',
        background: 'var(--surface-2)',
      }}>
        <span style={{ font: '600 10px/1 var(--ff-body)', textTransform: 'uppercase', letterSpacing: '.08em', color: 'var(--tx-3)' }}>
          {drillDown ? 'Top vendedores no estado' : 'Top vendedores no Brasil'}
        </span>
        {topVendedores.length === 0 ? (
          <span style={{ font: '400 12px/1 var(--ff-body)', color: 'var(--tx-3)' }}>—</span>
        ) : topVendedores.map(function(t) {
          return (
            <div key={t.email} style={{ display: 'flex', alignItems: 'center', gap: 5, font: '400 12px/1 var(--ff-body)', color: 'var(--tx-2)' }}>
              <span style={{ width: 10, height: 10, borderRadius: '50%', background: t.info ? t.info.cor : '#9ca3af', display: 'inline-block' }}></span>
              <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', maxWidth: 130 }}>
                {t.info ? t.info.nome : t.email.split('@')[0]}
              </span>
              <span style={{ color: 'var(--tx-3)', fontFamily: 'var(--ff-mono)' }}>· {t.qtd}</span>
            </div>
          );
        })}
      </div>
    </div>
  );
}

// ============================================================
// COMPONENTE PRINCIPAL -- Carteiras
// ============================================================
function Carteiras({ onNav }) {
  // Permissão por papel: comercial vê só a própria carteira; BDR/Admin/Gerência veem todas.
  // (Lista, Mapa e Território — todas as 3 views consomem o mesmo `clientes` filtrado.)
  const _podeVerTodas = !!(window.CRM_USER && window.CRM_USER.podeVerOpAlheia);
  const _meuEmailC    = (window.CRM_USER && window.CRM_USER.email)  || '';
  const _meuIdC       = (window.CRM_USER && window.CRM_USER.userId) || null;
  function _filtrarPorCarteira(arr) {
    if (_podeVerTodas) return arr || [];
    return (arr || []).filter(function(c) {
      var vid = (c.vendedor_id || c.proprietario || '');
      return vid === _meuIdC || (vid && vid.toLowerCase && vid.toLowerCase() === _meuEmailC);
    });
  }

  const [clientes, setClientes] = useCartState(function() { return _filtrarPorCarteira(CRM_DATA.clientes); });
  const [selecionado, setSelecionado] = useCartState(null);
  const [transferModal, setTransferModal] = useCartState(null);
  const [view, setView] = useCartState('lista');

  useCartEffect(function() {
    if (clientes.length === 0 && CRM_DATA.clientes && CRM_DATA.clientes.length > 0) {
      setClientes(_filtrarPorCarteira(CRM_DATA.clientes));
    }
  }, [CRM_DATA.clientes && CRM_DATA.clientes.length]);

  useCartEffect(function() {
    try { window.lucide && window.lucide.createIcons({ attrs: { 'stroke-width': 1.75 } }); } catch (e) {}
  });

  const grupos = useCartMemo(function() {
    var map = {};
    var semVend = [];
    clientes.forEach(function(c) {
      var v = getClienteVendedor(c).toLowerCase();
      if (!v) { semVend.push(c); }
      else {
        if (!map[v]) map[v] = [];
        map[v].push(c);
      }
    });
    return { map: map, semVend: semVend };
  }, [clientes]);

  const vendedoresInfo = useCartMemo(getVendedoresAtivosByEmail, []);

  const cards = useCartMemo(function() {
    var arr = Object.keys(grupos.map).map(function(email) {
      var info = vendedoresInfo[email];
      return {
        email: email,
        nome: info ? info.nome : email,
        cor: info ? info.cor : 'var(--tx-3)',
        grupo: info ? info.grupo : 'inativo',
        ativoNaWhitelist: !!info,
        qtd: grupos.map[email].length,
      };
    });
    arr.sort(function(a, b) { return b.qtd - a.qtd; });
    return arr;
  }, [grupos, vendedoresInfo]);

  const totalClientes = clientes.length;
  const totalComVend = totalClientes - grupos.semVend.length;
  const totalSemVend = grupos.semVend.length;
  const numVendedoresAtivos = cards.length;
  const maxQtd = cards.length ? cards[0].qtd : 0;
  const maiorCarteira = cards.length ? cards[0] : null;

  var vendedorInfoSelecionado = null;
  var clientesSelecionados = [];
  if (selecionado === SEM_VENDEDOR_ID) {
    vendedorInfoSelecionado = {
      email: SEM_VENDEDOR_ID, nome: 'Sem vendedor',
      cor: 'var(--warn)', grupo: 'orfaos', ativoNaWhitelist: true,
    };
    clientesSelecionados = grupos.semVend;
  } else if (selecionado) {
    var info = vendedoresInfo[selecionado.toLowerCase()];
    vendedorInfoSelecionado = {
      email: selecionado,
      nome: info ? info.nome : selecionado,
      cor: info ? info.cor : 'var(--tx-3)',
      grupo: info ? info.grupo : 'inativo',
      ativoNaWhitelist: !!info,
    };
    clientesSelecionados = grupos.map[selecionado.toLowerCase()] || [];
  }

  const vendedoresDisp = useCartMemo(getVendedoresParaTransferir, []);

  async function handleTransferir(cliente, novoVendedorEmail) {
    if (!cliente) return;
    if (!cliente._spId) {
      window.CRM_TOAST && window.CRM_TOAST('Cliente sem _spId -- recarregue a pagina', 'error');
      return;
    }
    var emailNorm = (novoVendedorEmail || '').toLowerCase().trim();
    try {
      await CRM_API.updateItem('Clientes', cliente._spId, { vendedor_id: emailNorm });
      var idx = CRM_DATA.clientes.findIndex(function(c) { return c.id === cliente.id; });
      if (idx >= 0) {
        CRM_DATA.clientes[idx] = Object.assign({}, CRM_DATA.clientes[idx], { vendedor_id: emailNorm });
      }
      setClientes(_filtrarPorCarteira(CRM_DATA.clientes));
      setTransferModal(null);
      var msg = emailNorm
        ? 'Cliente transferido para ' + (vendedoresInfo[emailNorm] ? vendedoresInfo[emailNorm].nome : emailNorm)
        : 'Cliente desatribuido';
      window.CRM_TOAST && window.CRM_TOAST(msg, 'ok');
    } catch (e) {
      console.error('[Carteiras] erro transferir:', e);
      window.CRM_TOAST && window.CRM_TOAST('Erro ao transferir: ' + (e.message || e), 'error');
      throw e;
    }
  }

  function abrirClienteNoSCRM(clienteId) {
    if (!onNav) return;
    onNav('clientes');
    setTimeout(function() {
      try { window.dispatchEvent(new CustomEvent('crm_open_cliente', { detail: { id: clienteId } })); } catch (e) {}
    }, 100);
  }

  return (
    <div data-screen-label="03c Carteiras">
      <div className="kpi-grid" style={{ gridTemplateColumns: 'repeat(4, 1fr)', marginBottom: 18 }}>
        <div className="kpi-card">
          <div className="kpi-card__eyebrow">Total na base</div>
          <div className="kpi-card__v kpi-card__v--mono">{totalClientes.toLocaleString('pt-BR')}</div>
          <div className="kpi-card__delta kpi-card__sub">
            {totalComVend.toLocaleString('pt-BR')} com vendedor
          </div>
        </div>
        <div className="kpi-card">
          <div className="kpi-card__eyebrow">Sem vendedor</div>
          <div className="kpi-card__v kpi-card__v--mono"
            style={{ color: totalSemVend > 0 ? 'var(--warn)' : 'var(--tx)' }}>
            {totalSemVend.toLocaleString('pt-BR')}
          </div>
          <div className="kpi-card__delta kpi-card__sub">
            {totalSemVend > 0 ? 'precisam atribuicao' : 'todos atribuidos'}
          </div>
        </div>
        <div className="kpi-card">
          <div className="kpi-card__eyebrow">Vendedores com carteira</div>
          <div className="kpi-card__v kpi-card__v--mono">{numVendedoresAtivos.toLocaleString('pt-BR')}</div>
          <div className="kpi-card__delta kpi-card__sub">de {vendedoresDisp.length} ativos</div>
        </div>
        <div className="kpi-card">
          <div className="kpi-card__eyebrow">Maior carteira</div>
          {maiorCarteira ? (
            <>
              <div className="kpi-card__v kpi-card__v--mono">{maiorCarteira.qtd.toLocaleString('pt-BR')}</div>
              <div className="kpi-card__delta kpi-card__sub" title={maiorCarteira.nome}
                style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                {maiorCarteira.nome}
              </div>
            </>
          ) : (
            <>
              <div className="kpi-card__v kpi-card__v--mono">—</div>
              <div className="kpi-card__delta kpi-card__sub">nenhum cliente atribuido</div>
            </>
          )}
        </div>
      </div>

      <div className="tabs" style={{ marginBottom: 14 }}>
        <button className={view === 'lista' ? 'is-on' : ''} onClick={function() { setView('lista'); }}>
          <i data-lucide="list"></i> Lista
        </button>
        <button className={view === 'mapa' ? 'is-on' : ''} onClick={function() { setView('mapa'); }}>
          <i data-lucide="map"></i> Mapa (estados)
        </button>
        <button className={view === 'territorio' ? 'is-on' : ''} onClick={function() { setView('territorio'); }}>
          <i data-lucide="map-pinned"></i> Território (municípios)
        </button>
      </div>

      {view === 'mapa' && (
        <MapaCarteiras clientes={clientes} vendedoresInfo={vendedoresInfo} />
      )}

      {view === 'territorio' && (
        typeof window.MapaTerritorial === 'function'
          ? <MapaTerritorial clientes={clientes} />
          : <div className="panel"><div className="panel__body" style={{ padding: 32, textAlign: 'center', color: 'var(--tx-3)' }}>
              <i data-lucide="map-off" style={{ width: 24, height: 24, display: 'block', margin: '0 auto 10px' }}></i>
              Componente MapaTerritorial não carregou. Recarregue a página.
            </div></div>
      )}

      {view === 'lista' && (
      <>
      <div className="panel" style={{ marginBottom: 18 }}>
        <div className="panel__hd">
          <h3>Carteiras por vendedor</h3>
          <div className="meta">
            {numVendedoresAtivos + (totalSemVend > 0 ? 1 : 0)} {numVendedoresAtivos === 0 && totalSemVend === 0 ? 'sem dados' : 'cards'}
          </div>
        </div>
        <div className="panel__body" style={{ padding: 14 }}>
          {numVendedoresAtivos === 0 && totalSemVend === 0 ? (
            <div style={{ padding: '32px 0', textAlign: 'center', color: 'var(--tx-3)' }}>
              <i data-lucide="users" style={{ width: 24, height: 24, display: 'block', margin: '0 auto 10px' }}></i>
              <div style={{ font: '500 13px/1 var(--ff-body)', color: 'var(--tx-2)' }}>
                Nenhuma carteira definida ainda
              </div>
              <div style={{ font: '400 12px/1.5 var(--ff-body)', color: 'var(--tx-3)', marginTop: 6 }}>
                Atribua vendedor aos clientes pela tela Clientes -> Editar.
              </div>
            </div>
          ) : (
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(220px, 1fr))', gap: 12 }}>
              {totalSemVend > 0 && (
                <SemVendedorCard
                  qtd={totalSemVend}
                  selecionado={selecionado === SEM_VENDEDOR_ID}
                  onClick={function() { setSelecionado(selecionado === SEM_VENDEDOR_ID ? null : SEM_VENDEDOR_ID); }}
                />
              )}
              {cards.map(function(card) {
                return (
                  <VendedorCard key={card.email}
                    vendedor={card} qtd={card.qtd} maxQtd={maxQtd}
                    selecionado={selecionado === card.email}
                    onClick={function() { setSelecionado(selecionado === card.email ? null : card.email); }}
                  />
                );
              })}
            </div>
          )}
        </div>
      </div>

      {selecionado && vendedorInfoSelecionado && (
        <ListaClientesCarteira
          vendedor={vendedorInfoSelecionado}
          clientes={clientesSelecionados}
          onTransferir={function(cli) { setTransferModal({ cliente: cli, vendedorAtual: vendedorInfoSelecionado }); }}
          onBack={function() { setSelecionado(null); }}
          onOpenCliente={abrirClienteNoSCRM}
        />
      )}
      </>
      )}

      {transferModal && (
        <TransferirCarteiraModal
          cliente={transferModal.cliente}
          vendedorAtual={
            transferModal.vendedorAtual && transferModal.vendedorAtual.email !== SEM_VENDEDOR_ID
              ? transferModal.vendedorAtual : null
          }
          vendedoresDisp={vendedoresDisp}
          onClose={function() { setTransferModal(null); }}
          onConfirm={function(novoEmail) { return handleTransferir(transferModal.cliente, novoEmail); }}
        />
      )}
    </div>
  );
}

window.Carteiras = Carteiras;
