/* =============================================================================
   screen_comercial_rpc_sdr_ai.jsx — Tab SDR AI (isolado para Costa)
   =============================================================================
   Container autónomo: faz os seus próprios fetches, gere o seu próprio estado.
   Entry point: window.SdrAITab({ selAno, sdrList })
   ============================================================================= */

// ─── Constantes locais (não colidem com o parent) ─────────────────────────────

const SDR_AI_MESES = ['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez'];
const SDR_AI_DESDE_MES = 8;

function sdrAiNoPeriodo(lead) {
  return SDR_AI_MESES.indexOf(lead.mes) >= SDR_AI_DESDE_MES;
}

const SDR_AI_METAS = {
  taxa_contacto: 70,
  taxa_qualif:   40,
};

const SDR_AI_SOURCES = [
  { id: 'ADS', label: 'ADS' },
  { id: 'WEB', label: 'WEB' },
  { id: 'NEWSLETTER', label: 'NEWSLETTER' },
];

const SDR_AI_ACTIONS = [
  { id: 'ADS AQUANOSTRA', source: 'ADS' },
  { id: 'ADS DECAL', source: 'ADS' },
  { id: 'ADS MIMAKI', source: 'ADS' },
  { id: 'ADS NETSCREEN', source: 'ADS' },
  { id: 'INBOUND AQUA', source: 'WEB' },
  { id: 'INBOUND BRANDDIGITAL', source: 'WEB' },
  { id: 'INBOUND DECAL', source: 'WEB' },
  { id: 'INBOUND MIMAKI', source: 'WEB' },
  { id: 'INBOUND NETSCREEN', source: 'WEB' },
  { id: 'WEBSITE AQUA', source: 'WEB' },
  { id: 'WEBSITE BRANDDIGITAL', source: 'WEB' },
  { id: 'WEBSITE DECAL', source: 'WEB' },
  { id: 'WEBSITE DIGIDELTA', source: 'WEB' },
  { id: 'WEBSITE NETSCREEN', source: 'WEB' },
  { id: 'NEWSLETTER AQUA', source: 'NEWSLETTER' },
  { id: 'NEWSLETTER BRAND DIGITAL', source: 'NEWSLETTER' },
  { id: 'NEWSLETTER DECAL', source: 'NEWSLETTER' },
  { id: 'NEWSLETTER MIMAKI', source: 'NEWSLETTER' },
  { id: 'NEWSLETTER NETSCREEN', source: 'NEWSLETTER' },
];

const SDR_AI_ACTION_POR_MARCA = {
  ADS: { Mimaki: 'ADS MIMAKI', Decal: 'ADS DECAL', NetScreen: 'ADS NETSCREEN', Aqua: 'ADS AQUANOSTRA' },
  WEB: { Mimaki: 'INBOUND MIMAKI', Decal: 'INBOUND DECAL', NetScreen: 'INBOUND NETSCREEN', Aqua: 'INBOUND AQUA', BrandDigital: 'INBOUND BRANDDIGITAL', Digidelta: 'WEBSITE DIGIDELTA' },
  NEWSLETTER: { Mimaki: 'NEWSLETTER MIMAKI', Decal: 'NEWSLETTER DECAL', NetScreen: 'NEWSLETTER NETSCREEN', Aqua: 'NEWSLETTER AQUA', BrandDigital: 'NEWSLETTER BRAND DIGITAL' },
};

const SDR_AI_STAGES = ['LEAD', 'INTERESSE', 'EVENTO', 'DEMO', 'AG DECISAO', 'AG FINANCEIRO', 'APROVADO FINANCIAMENTO'];

function sdrAiActionId(lead) {
  return SDR_AI_ACTION_POR_MARCA[lead.source]?.[lead.marca] || null;
}

const SDR_AI_STATUS_CFG = {
  atribuido:         { label:'Atribuído',            color:'#64748b', bg:'#f1f5f9', border:'#cbd5e1' },
  contactado:        { label:'Contactado',           color:'#1d4ed8', bg:'#eff6ff', border:'#bfdbfe' },
  em_qualificacao:   { label:'Em Qualificação',      color:'#92400e', bg:'#fffbeb', border:'#fde68a' },
  bant_completo:     { label:'Qualificado BANT',     color:'#166534', bg:'#f0fdf4', border:'#bbf7d0' },
  passado_comercial: { label:'Passado ao Comercial', color:'#1d4ed8', bg:'#eff6ff', border:'#bfdbfe' },
  nao_qualificado:   { label:'Não Qualificado',      color:'#991b1b', bg:'#fef2f2', border:'#fecaca' },
  passado_humano:    { label:'Passado ao Humano',    color:'#166534', bg:'#f0fdf4', border:'#bbf7d0' },
};

function aiSdrPct(num, den) {
  if (!den) return null;
  return Math.round(num / den * 1000) / 10;
}

function aiSdrColor(val, meta, higherIsBetter = true) {
  if (val === null || val === undefined) return 'var(--dgd-fg-3)';
  return higherIsBetter ? (val >= meta ? '#166534' : '#991b1b') : (val <= meta ? '#166534' : '#991b1b');
}

function aiSdrBg(val, meta, higherIsBetter = true) {
  if (val === null || val === undefined) return 'transparent';
  const ok = higherIsBetter ? val >= meta : val <= meta;
  return ok ? 'color-mix(in oklch,#22c55e 8%,transparent)' : 'color-mix(in oklch,#ef4444 8%,transparent)';
}

// ─── Sub-components ───────────────────────────────────────────────────────────

const SdrAISectionRow = ({ children, cols }) => (
  <tr>
    <td colSpan={cols} style={{ background:'var(--dgd-bg-app,#f8fafc)', color:'var(--dgd-fg-3)', fontSize:10, fontFamily:'var(--dgd-font-mono,monospace)', letterSpacing:'0.08em', textTransform:'uppercase', fontWeight:600, padding:'5px 8px', borderBottom:'1px solid var(--dgd-border-1)' }}>{children}</td>
  </tr>
);

// ─── Modal lista de leads SDR AI ──────────────────────────────────────────────

const SdrAILeadsModal = ({ title, leads, onClose }) => (
  <div onClick={e => { if (e.target === e.currentTarget) onClose(); }}
    style={{ position:'fixed', inset:0, zIndex:2000, background:'rgba(0,0,0,0.35)', display:'flex', alignItems:'center', justifyContent:'center', padding:24 }}>
    <div style={{ background:'var(--dgd-bg-card,white)', border:'1px solid var(--dgd-border-1)', borderRadius:10, boxShadow:'0 8px 32px rgba(0,0,0,0.18)', width:'100%', maxWidth:680, maxHeight:'80vh', display:'flex', flexDirection:'column' }}>
      <div style={{ padding:'14px 18px', borderBottom:'1px solid var(--dgd-border-1)', display:'flex', alignItems:'center', justifyContent:'space-between' }}>
        <div style={{ fontSize:13, fontWeight:600, color:'var(--dgd-fg-1)' }}>{title}</div>
        <button onClick={onClose} style={{ background:'none', border:'none', cursor:'pointer', color:'var(--dgd-fg-3)', padding:4 }}>
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
        </button>
      </div>
      <div style={{ overflowY:'auto', flex:1 }}>
        {leads === null ? (
          <div style={{ padding:32, textAlign:'center', color:'var(--dgd-fg-3)', fontSize:13 }}>A carregar...</div>
        ) : leads.length === 0 ? (
          <div style={{ padding:32, textAlign:'center', color:'var(--dgd-fg-3)', fontSize:13 }}>Sem leads para este critério neste mês.</div>
        ) : (
          <table style={{ width:'100%', borderCollapse:'collapse', fontSize:12 }}>
            <thead>
              <tr>
                {['Nome','Empresa','Segmento','Status','Ult. Acção'].map(h => (
                  <th key={h} style={{ padding:'7px 12px', textAlign:'left', fontSize:10.5, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', borderBottom:'1px solid var(--dgd-border-1)', fontWeight:600, whiteSpace:'nowrap' }}>{h}</th>
                ))}
              </tr>
            </thead>
            <tbody>
              {leads.map(l => {
                const sc = SDR_AI_STATUS_CFG[l.status] || {};
                return (
                  <tr key={l.id} style={{ borderBottom:'1px solid var(--dgd-border-1)' }}>
                    <td style={{ padding:'8px 12px', fontWeight:500, color:'var(--dgd-fg-1)' }}>{l.nome}</td>
                    <td style={{ padding:'8px 12px', color:'var(--dgd-fg-2)' }}>{l.empresa}</td>
                    <td style={{ padding:'8px 12px', color:'var(--dgd-fg-3)', fontSize:11 }}>{l.segmento}</td>
                    <td style={{ padding:'8px 12px' }}>
                      <span style={{ display:'inline-block', padding:'2px 8px', borderRadius:99, fontSize:10.5, fontWeight:600, color:sc.color, background:sc.bg, border:`1px solid ${sc.border}`, whiteSpace:'nowrap' }}>{sc.label || l.status}</span>
                    </td>
                    <td style={{ padding:'8px 12px', color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', fontSize:11 }}>{l.ultimo_wa || '—'}</td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        )}
      </div>
      {leads !== null && (
        <div style={{ padding:'10px 18px', borderTop:'1px solid var(--dgd-border-1)', fontSize:11, color:'var(--dgd-fg-3)' }}>
          {leads.length} lead{leads.length !== 1 ? 's' : ''}
        </div>
      )}
    </div>
  </div>
);

// ─── Tabela Funil SDR AI ──────────────────────────────────────────────────────

const SdrAIFunilTable = ({ rows, onCellClick }) => {
  const mesIdx = (() => { const m = SDR_AI_MESES[new Date().getMonth()]; const i = rows.findIndex(r => r.mes === m); return i >= 0 ? i : rows.length - 1; })();
  const nCols  = rows.length + 3;
  const fv = (val, i) => i > mesIdx ? '—' : val;

  const temRegra = rows.some(r => r.nao_qualificados != null);
  const ytd = rows.reduce((s, r) => ({
    atribuidos:   s.atribuidos   + (r.atribuidos || 0),
    contactados:  s.contactados  + (r.contactados || 0),
    qualificados: s.qualificados + (r.qualificados || 0),
    em_qualificacao: s.em_qualificacao + (r.em_qualificacao || 0),
    nao_qualificados: s.nao_qualificados + (r.nao_qualificados != null ? r.nao_qualificados : 0),
    chamadas: s.chamadas + (r.chamadas || 0),
    whatsapp: s.whatsapp + (r.whatsapp || 0),
    sem_contacto: s.sem_contacto + (r.sem_contacto || 0),
    elegiveis: s.elegiveis + (r.elegiveis || 0),
    contactos_digi: s.contactos_digi + (r.contactos_digi || 0),
    na_chamada: s.na_chamada + (r.na_chamada || 0),
    nurturing: s.nurturing + (r.nurturing || 0),
    nurturing_contactos: s.nurturing_contactos + (r.nurturing_contactos || 0),
    nurturing_demos: s.nurturing_demos + (r.nurturing_demos || 0),
    nurturing_ganhas: s.nurturing_ganhas + (r.nurturing_ganhas || 0),
  }), { atribuidos:0, contactados:0, qualificados:0, em_qualificacao:0, nao_qualificados:0, chamadas:0, whatsapp:0, sem_contacto:0, elegiveis:0, contactos_digi:0, na_chamada:0, nurturing:0, nurturing_contactos:0, nurturing_demos:0, nurturing_ganhas:0 });

  const tcYTD = aiSdrPct(ytd.contactados, ytd.elegiveis);
  const tqYTD = aiSdrPct(ytd.qualificados, ytd.na_chamada);
  const tnYTD = aiSdrPct(ytd.nurturing_contactos, ytd.nurturing);

  const th     = { padding:'8px 10px', textAlign:'right', fontSize:11, color:'var(--dgd-fg-3)', fontFamily:'inherit', fontWeight:600, borderBottom:'1px solid var(--dgd-border-1)', whiteSpace:'nowrap' };
  const thL    = { ...th, textAlign:'left' };
  const tdBase = { padding:'9px 10px', fontSize:14, fontFamily:'inherit', fontWeight:600, fontVariantNumeric:'tabular-nums', borderBottom:'1px solid var(--dgd-border-1)', whiteSpace:'nowrap', textAlign:'right', color:'var(--dgd-fg-2)' };
  const tdL    = { ...tdBase, textAlign:'left', fontSize:12.5, color:'var(--dgd-fg-1)' };

  const clickStyle = { cursor:'pointer', textDecoration:'underline', textDecorationStyle:'dotted' };
  const cl = (metric, mes, val) => onCellClick ? { onClick: () => onCellClick(metric, mes, val) } : {};

  return (
    <div style={{ overflowX:'auto' }}>
      <style>{'.sdr-ai-rpc-row:hover td{background:#f8fafc !important}'}</style>
      <table style={{ borderCollapse:'collapse', width:'100%', fontFamily:'inherit', fontWeight:600, fontSize:14 }}>
        <thead>
          <tr>
            <th style={{ ...thL, minWidth:220 }}>Métrica</th>
            <th style={{ ...th, color:'#1d4ed8' }}>Obj.</th>
            {rows.map((r, i) => (
              <th key={r.mes} style={{ ...th, fontWeight:i===mesIdx?800:600, color:i===mesIdx?'var(--dgd-fg-1)':'var(--dgd-fg-3)' }}>{r.mes}</th>
            ))}
            <th style={{ ...th, fontWeight:800, color:'var(--dgd-fg-1)' }}>YTD</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td colSpan={nCols} style={{ background: '#f8fafc', color: '#112954', fontSize: 12, letterSpacing: '0.04em', fontWeight: 800, padding: '8px 10px', borderBottom: '1px solid var(--dgd-border-1)' }}>Qualificação de Leads</td>
          </tr>
          <tr className="sdr-ai-rpc-row">
            <td style={tdL}>Leads Atribuídos</td>
            <td style={{ ...tdBase, color:'var(--dgd-fg-3)' }}>--</td>
            {rows.map((r,i) => <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?800:600, ...(onCellClick?clickStyle:{}) }} {...cl('atribuidos', r.mes, r.atribuidos)}>{fv(r.atribuidos, i)}</td>)}
            <td style={{ ...tdBase, fontWeight:800, color:'var(--dgd-fg-1)' }}>{ytd.atribuidos}</td>
          </tr>
          <tr className="sdr-ai-rpc-row">
            <td style={tdL}>Elegíveis</td>
            <td style={{ ...tdBase, color:'var(--dgd-fg-3)' }}>--</td>
            {rows.map((r,i) => <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?800:600, ...(onCellClick?clickStyle:{}) }} {...cl('elegiveis', r.mes, r.elegiveis || 0)}>{fv(r.elegiveis || 0, i)}</td>)}
            <td style={{ ...tdBase, fontWeight:800, color:'var(--dgd-fg-1)' }}>{ytd.elegiveis}</td>
          </tr>
          <tr className="sdr-ai-rpc-row">
            <td style={tdL}>Leads Contactados</td>
            <td style={{ ...tdBase, color:'var(--dgd-fg-3)' }}>--</td>
            {rows.map((r,i) => <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?800:600, ...(onCellClick?clickStyle:{}) }} {...cl('contactados', r.mes, r.contactados)}>{fv(r.contactados, i)}</td>)}
            <td style={{ ...tdBase, fontWeight:800, color:'var(--dgd-fg-1)' }}>{ytd.contactados}</td>
          </tr>
          <tr className="sdr-ai-rpc-row">
            <td style={tdL}>Taxa de Contacto</td>
            <td style={{ ...tdBase, color:'#1d4ed8', fontWeight:600 }}>&gt;={SDR_AI_METAS.taxa_contacto}%</td>
            {rows.map((r,i) => {
              const v = i > mesIdx ? null : aiSdrPct(r.contactados, r.elegiveis || 0);
              return <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?800:600, color:aiSdrColor(v,SDR_AI_METAS.taxa_contacto), background:i===mesIdx?aiSdrBg(v,SDR_AI_METAS.taxa_contacto):'transparent' }}>{v === null ? '—' : `${v}%`}</td>;
            })}
            <td style={{ ...tdBase, fontWeight:800, color:aiSdrColor(tcYTD,SDR_AI_METAS.taxa_contacto) }}>{tcYTD === null ? '—' : `${tcYTD}%`}</td>
          </tr>
          <tr className="sdr-ai-rpc-row">
            <td style={tdL}>Qualificados BANT</td>
            <td style={{ ...tdBase, color:'var(--dgd-fg-3)' }}>--</td>
            {rows.map((r,i) => <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?800:600, ...(onCellClick?clickStyle:{}) }} {...cl('qualificados', r.mes, r.qualificados)}>{fv(r.qualificados, i)}</td>)}
            <td style={{ ...tdBase, fontWeight:800, color:'var(--dgd-fg-1)' }}>{ytd.qualificados}</td>
          </tr>
          <tr className="sdr-ai-rpc-row">
            <td style={tdL}>Taxa de Qualificação BANT</td>
            <td style={{ ...tdBase, color:'#1d4ed8', fontWeight:600 }}>&gt;={SDR_AI_METAS.taxa_qualif}%</td>
            {rows.map((r,i) => {
              const v = i > mesIdx ? null : aiSdrPct(r.qualificados, r.na_chamada || 0);
              return <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?800:600, color:aiSdrColor(v,SDR_AI_METAS.taxa_qualif), background:i===mesIdx?aiSdrBg(v,SDR_AI_METAS.taxa_qualif):'transparent' }}>{v === null ? '—' : `${v}%`}</td>;
            })}
            <td style={{ ...tdBase, fontWeight:800, color:aiSdrColor(tqYTD,SDR_AI_METAS.taxa_qualif) }}>{tqYTD === null ? '—' : `${tqYTD}%`}</td>
          </tr>
          <tr className="sdr-ai-rpc-row">
            <td style={tdL}>Não Qualificados BANT</td>
            <td style={{ ...tdBase, color:'var(--dgd-fg-3)' }}>--</td>
            {rows.map((r,i) => {
              const v = i > mesIdx ? '—' : (r.nao_qualificados != null ? r.nao_qualificados : r.contactados - r.qualificados);
              return <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?800:600, color:'#991b1b', ...(onCellClick?clickStyle:{}) }} {...cl('nao_qualificados', r.mes, v)}>{v}</td>;
            })}
            <td style={{ ...tdBase, fontWeight:800, color:'#991b1b' }}>{temRegra ? ytd.nao_qualificados : ytd.contactados - ytd.qualificados}</td>
          </tr>
          <tr className="sdr-ai-rpc-row">
            <td style={tdL}>Sem contacto</td>
            <td style={{ ...tdBase, color:'var(--dgd-fg-3)' }}>--</td>
            {rows.map((r,i) => <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?800:600, color:'#991b1b', ...(onCellClick?clickStyle:{}) }} {...cl('sem_contacto', r.mes, r.sem_contacto || 0)}>{fv(r.sem_contacto || 0, i)}</td>)}
            <td style={{ ...tdBase, fontWeight:800, color:'#991b1b' }}>{ytd.sem_contacto}</td>
          </tr>
          <tr>
            <td colSpan={nCols} style={{ background: '#f8fafc', color: '#112954', fontSize: 12, letterSpacing: '0.04em', fontWeight: 800, padding: '8px 10px', borderBottom: '1px solid var(--dgd-border-1)' }}>Nurturing de Oportunidades</td>
          </tr>
          <tr className="sdr-ai-rpc-row">
            <td style={tdL}>Oportunidades em nurturing</td>
            <td style={{ ...tdBase, color:'var(--dgd-fg-3)' }}>--</td>
            {rows.map((r,i) => <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?800:600, ...(onCellClick?clickStyle:{}) }} {...cl('nurturing', r.mes, r.nurturing || 0)}>{fv(r.nurturing || 0, i)}</td>)}
            <td style={{ ...tdBase, fontWeight:800, color:'var(--dgd-fg-1)' }}>{ytd.nurturing}</td>
          </tr>
          <tr className="sdr-ai-rpc-row">
            <td style={tdL}>Contactos feitos</td>
            <td style={{ ...tdBase, color:'var(--dgd-fg-3)' }}>--</td>
            {rows.map((r,i) => <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?800:600, ...(onCellClick?clickStyle:{}) }} {...cl('nurturing_contactos', r.mes, r.nurturing_contactos || 0)}>{fv(r.nurturing_contactos || 0, i)}</td>)}
            <td style={{ ...tdBase, fontWeight:800, color:'var(--dgd-fg-1)' }}>{ytd.nurturing_contactos}</td>
          </tr>
          <tr className="sdr-ai-rpc-row">
            <td style={tdL}>Taxa de Contacto</td>
            <td style={{ ...tdBase, color:'#1d4ed8', fontWeight:600 }}>&gt;={SDR_AI_METAS.taxa_contacto}%</td>
            {rows.map((r,i) => {
              const v = i > mesIdx ? null : aiSdrPct(r.nurturing_contactos || 0, r.nurturing || 0);
              return <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?800:600, color:aiSdrColor(v,SDR_AI_METAS.taxa_contacto), background:i===mesIdx?aiSdrBg(v,SDR_AI_METAS.taxa_contacto):'transparent' }}>{v === null ? '—' : `${v}%`}</td>;
            })}
            <td style={{ ...tdBase, fontWeight:800, color:aiSdrColor(tnYTD,SDR_AI_METAS.taxa_contacto) }}>{tnYTD === null ? '—' : `${tnYTD}%`}</td>
          </tr>
          <tr className="sdr-ai-rpc-row">
            <td style={tdL}>Demos ou visitas confirmadas</td>
            <td style={{ ...tdBase, color:'var(--dgd-fg-3)' }}>--</td>
            {rows.map((r,i) => <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?800:600, ...(onCellClick?clickStyle:{}) }} {...cl('nurturing_demos', r.mes, r.nurturing_demos || 0)}>{fv(r.nurturing_demos || 0, i)}</td>)}
            <td style={{ ...tdBase, fontWeight:800, color:'var(--dgd-fg-1)' }}>{ytd.nurturing_demos}</td>
          </tr>
          <tr className="sdr-ai-rpc-row">
            <td style={tdL}>Ganhas</td>
            <td style={{ ...tdBase, color:'var(--dgd-fg-3)' }}>--</td>
            {rows.map((r,i) => <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?800:600, ...(onCellClick?clickStyle:{}) }} {...cl('nurturing_ganhas', r.mes, r.nurturing_ganhas || 0)}>{fv(r.nurturing_ganhas || 0, i)}</td>)}
            <td style={{ ...tdBase, fontWeight:800, color:'var(--dgd-fg-1)' }}>{ytd.nurturing_ganhas}</td>
          </tr>
        </tbody>
      </table>
    </div>
  );
};

// ─── Revisão humana — não altera a classification nem o handoff ───────────────

const SdrAIRevisao = ({ lead, onRevisao }) => {
  const [aEnviar, setAEnviar] = React.useState(null);
  const [erro, setErro] = React.useState('');
  const actual = lead.revisao?.veredicto || '';

  const marcar = async (veredicto) => {
    setAEnviar(veredicto);
    setErro('');
    let res;
    try {
      res = await fetch('/api/comercial/sdr/ai/revisao', {
        method: 'POST', credentials: 'include',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ visitor_id: lead.id, veredicto }),
      });
    } catch {
      setAEnviar(null);
      setErro('A revisão não ficou gravada.');
      return;
    }
    const body = await res.json().catch(() => ({}));
    setAEnviar(null);
    if (!res.ok) {
      setErro('A revisão não ficou gravada.');
      return;
    }
    onRevisao?.(lead.id, body);
  };

  const btn = (id, label, on) => (
    <button onClick={() => marcar(id)} disabled={!!aEnviar}
      style={{ fontSize:11, padding:'3px 9px', borderRadius:5, cursor: aEnviar ? 'default' : 'pointer', fontWeight:600,
        border: on ? 'none' : '1px solid var(--dgd-border-1)',
        background: on ? (id === 'confere' ? '#166534' : '#991b1b') : 'none',
        color: on ? 'white' : 'var(--dgd-fg-2)' }}>
      {label}
    </button>
  );

  return (
    <div style={{ marginTop:14 }}>
      <div style={{ fontSize:10, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', letterSpacing:'0.07em', textTransform:'uppercase', marginBottom:8 }}>Revisão humana</div>
      <div style={{ display:'flex', gap:6, alignItems:'center', flexWrap:'wrap' }}>
        {btn('confere', 'Confere', actual === 'confere')}
        {btn('nao_confere', 'Não confere', actual === 'nao_confere')}
        {lead.revisao?.revisor_nome && (
          <span style={{ fontSize:11, color:'var(--dgd-fg-3)' }}>{lead.revisao.revisor_nome}</span>
        )}
      </div>
      {erro && <div style={{ fontSize:11, color:'#991b1b', marginTop:6 }}>{erro}</div>}
    </div>
  );
};

// ─── Painel de Leads SDR AI ───────────────────────────────────────────────────

const SdrAILeadsPanel = ({ initialStatus, initialMes, allLeads = [], selAno, sdrList = [], pelaRegra = false, onRevisao, onPassou }) => {
  const [search,      setSearch]      = React.useState('');
  const [filterSt,    setFilterSt]    = React.useState(initialStatus || 'all');
  const [filterMes,   setFilterMes]   = React.useState(initialMes || SDR_AI_MESES[new Date().getMonth()]);
  const [expandedId,  setExpandedId]  = React.useState(null);
  const [leadTab,     setLeadTab]     = React.useState('info');
  const [passando,    setPassando]    = React.useState(null);
  const [selSdrPass,  setSelSdrPass]  = React.useState('');
  const [passOk,      setPassOk]      = React.useState({});

  React.useEffect(() => {
    const currentMes = SDR_AI_MESES[new Date().getMonth()];
    const currentAno = new Date().getFullYear();
    setFilterMes(selAno === currentAno || selAno == null ? currentMes : 'all');
  }, [selAno]);

  const mesesComLeads = [...new Set(allLeads.map(l => l.mes))];

  const handlePassarSDR = async (lead) => {
    if (!selSdrPass) return;
    const r = await fetch('/api/comercial/sdr/ai-to-humano', {
      method: 'POST', credentials: 'include',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ visitor_id: lead.id, sdr_email: selSdrPass }),
    }).then(r => r.json()).catch(() => ({ error: 'network' }));
    if (r.ok) {
      setPassOk(prev => ({ ...prev, [lead.id]: true }));
      setPassando(null);
      setSelSdrPass('');
      onPassou?.(lead.id);
    }
  };

  const filtered = allLeads.filter(l => {
    if (filterSt  !== 'all' && l.status !== filterSt)  return false;
    if (filterMes !== 'all' && l.mes    !== filterMes)  return false;
    if (search) {
      const q = search.toLowerCase();
      if (!l.nome.toLowerCase().includes(q) && !l.empresa.toLowerCase().includes(q)) return false;
    }
    return true;
  });

  const pillBase = { padding:'3px 11px', fontSize:11.5, borderRadius:20, border:'1px solid var(--dgd-border-1)', cursor:'pointer', whiteSpace:'nowrap', background:'none', fontWeight:400, color:'var(--dgd-fg-2)' };
  const pillOn   = { ...pillBase, background:'var(--dgd-fg-1)', color:'white', borderColor:'var(--dgd-fg-1)', fontWeight:600 };

  const statusPills = [
    { id:'all',            label:'Todos' },
    { id:'atribuido',      label:'Atribuído' },
    { id:'contactado',     label:'Contactado' },
    { id:'em_qualificacao',label:'Em Qualificação' },
    ...(pelaRegra ? [{ id:'bant_completo', label:'Qualificado BANT' }] : []),
    { id:'passado_humano', label:'Passado ao Humano' },
    { id:'nao_qualificado',label:'Não Qualificado' },
  ];

  const BantIcon = ({ ok }) => ok === true
    ? <span style={{ color:'#166534', fontWeight:700 }}>S</span>
    : ok === false
      ? <span style={{ color:'#991b1b', fontWeight:700 }}>N</span>
      : <span style={{ color:'var(--dgd-fg-3)' }}>?</span>;

  return (
    <div style={{ marginTop:20, background:'var(--dgd-bg-card,white)', border:'1px solid var(--dgd-border-1)', borderRadius:8, overflow:'hidden' }}>
      {/* Filtros */}
      <div style={{ padding:'12px 14px', borderBottom:'1px solid var(--dgd-border-1)', display:'flex', gap:8, flexWrap:'wrap', alignItems:'center' }}>
        <input
          value={search} onChange={e => setSearch(e.target.value)}
          placeholder="Pesquisar nome / empresa..."
          style={{ padding:'4px 10px', fontSize:12, border:'1px solid var(--dgd-border-1)', borderRadius:6, outline:'none', width:200, color:'var(--dgd-fg-1)', background:'var(--dgd-bg-app,#f8fafc)' }}
        />
        <div style={{ width:1, background:'var(--dgd-border-1)', alignSelf:'stretch' }} />
        {statusPills.map(p => (
          <button key={p.id} onClick={() => setFilterSt(p.id)} style={filterSt===p.id ? pillOn : pillBase}>{p.label}</button>
        ))}
        <div style={{ width:1, background:'var(--dgd-border-1)', alignSelf:'stretch' }} />
        <select value={filterMes} onChange={e => setFilterMes(e.target.value)}
          style={{ padding:'4px 8px', fontSize:12, border:'1px solid var(--dgd-border-1)', borderRadius:6, background:'transparent', color:'var(--dgd-fg-1)', cursor:'pointer' }}>
          <option value="all">Todos os meses</option>
          {mesesComLeads.map(m => <option key={m} value={m}>{m}</option>)}
        </select>
      </div>

      {/* Lista */}
      {filtered.length === 0 ? (
        <div style={{ padding:32, textAlign:'center', color:'var(--dgd-fg-3)', fontSize:13 }}>Sem leads para os filtros seleccionados.</div>
      ) : (
        <div>
          {filtered.map(lead => {
            const sc  = SDR_AI_STATUS_CFG[lead.status] || {};
            const exp = expandedId === lead.id;
            return (
              <React.Fragment key={lead.id}>
                <div
                  onClick={() => { setExpandedId(exp ? null : lead.id); setLeadTab('info'); }}
                  style={{ display:'flex', alignItems:'center', gap:12, padding:'10px 14px', borderBottom:'1px solid var(--dgd-border-1)', cursor:'pointer', background: exp ? 'color-mix(in oklch,#112954 3%,transparent)' : 'transparent' }}
                  onMouseEnter={e => { if (!exp) e.currentTarget.style.background = 'var(--dgd-bg-app,#f8fafc)'; }}
                  onMouseLeave={e => { if (!exp) e.currentTarget.style.background = 'transparent'; }}
                >
                  <div style={{ flex:'0 0 200px', minWidth:0 }}>
                    <div style={{ fontSize:12.5, fontWeight:600, color:'var(--dgd-fg-1)', overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{lead.nome}</div>
                    <div style={{ fontSize:11, color:'var(--dgd-fg-3)', overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{lead.empresa}</div>
                  </div>
                  <div style={{ flex:'0 0 90px', fontSize:11, color:'var(--dgd-fg-3)' }}>{lead.segmento}</div>
                  <div style={{ flex:'0 0 140px' }}>
                    <span style={{ display:'inline-block', padding:'2px 8px', borderRadius:99, fontSize:10.5, fontWeight:600, color:sc.color, background:sc.bg, border:`1px solid ${sc.border}`, whiteSpace:'nowrap' }}>{sc.label}</span>
                    {pelaRegra && typeof lead.bant_n === 'number' && (
                      <div style={{ fontSize:10, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', marginTop:3 }}>{lead.bant_n}/4 BANT</div>
                    )}
                  </div>
                  <div style={{ flex:'0 0 52px', fontFamily:'var(--dgd-font-mono,monospace)', fontSize:12, fontWeight:600,
                    color: lead.score == null ? 'var(--dgd-fg-3)' : lead.score >= 70 ? '#166534' : lead.score >= 40 ? '#92400e' : '#991b1b' }}>
                    {lead.score != null ? lead.score : '—'}
                  </div>
                  <div style={{ flex:'0 0 70px', fontSize:11, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)' }}>{lead.mes}</div>
                  <div style={{ flex:'0 0 70px', fontSize:11, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)' }}>{lead.ultimo_wa || '—'}</div>
                  <div style={{ marginLeft:'auto', display:'flex', alignItems:'center', gap:8 }} onClick={e => e.stopPropagation()}>
                    {passOk[lead.id] ? (
                      <span style={{ fontSize:11, color:'#166534', fontWeight:600 }}>Passado</span>
                    ) : passando === lead.id ? (
                      <div style={{ display:'flex', alignItems:'center', gap:6 }}>
                        <select value={selSdrPass} onChange={e => setSelSdrPass(e.target.value)}
                          style={{ fontSize:11, padding:'3px 6px', border:'1px solid var(--dgd-border-1)', borderRadius:5, background:'var(--dgd-bg-card,white)', color:'var(--dgd-fg-1)', cursor:'pointer' }}>
                          <option value="">SDR...</option>
                          {sdrList.map(s => <option key={s.email} value={s.email}>{s.nome}</option>)}
                        </select>
                        <button onClick={() => handlePassarSDR(lead)}
                          disabled={!selSdrPass}
                          style={{ fontSize:11, padding:'3px 9px', borderRadius:5, border:'none', background: selSdrPass ? '#166534' : 'var(--dgd-border-1)', color: selSdrPass ? 'white' : 'var(--dgd-fg-3)', cursor: selSdrPass ? 'pointer' : 'default', fontWeight:600 }}>
                          Confirmar
                        </button>
                        <button onClick={() => { setPassando(null); setSelSdrPass(''); }}
                          style={{ fontSize:11, padding:'3px 7px', borderRadius:5, border:'1px solid var(--dgd-border-1)', background:'none', color:'var(--dgd-fg-3)', cursor:'pointer' }}>
                          x
                        </button>
                      </div>
                    ) : (
                      <button onClick={() => { setPassando(lead.id); setSelSdrPass(''); }}
                        style={{ fontSize:11, padding:'3px 9px', borderRadius:5, border:'1px solid var(--dgd-border-1)', background:'none', color:'var(--dgd-fg-2)', cursor:'pointer', whiteSpace:'nowrap' }}>
                        SDR
                      </button>
                    )}
                    <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" style={{ transform: exp ? 'rotate(180deg)' : 'none', transition:'transform 0.15s', cursor:'pointer' }} onClick={e => { e.stopPropagation(); setExpandedId(exp ? null : lead.id); setLeadTab('info'); }}><polyline points="6 9 12 15 18 9"/></svg>
                  </div>
                </div>

                {exp && (
                  <div style={{ borderBottom:'1px solid var(--dgd-border-1)', background:'color-mix(in oklch,#112954 2%,transparent)' }}>
                    {/* Mini tabs */}
                    <div style={{ display:'flex', gap:0, borderBottom:'1px solid var(--dgd-border-1)', paddingLeft:14 }}>
                      {[{id:'info',label:'Info Lead'},{id:'conversa',label:'Conversa WA'},{id:'historico',label:'Histórico'}].map(t => (
                        <button key={t.id} onClick={e => { e.stopPropagation(); setLeadTab(t.id); }}
                          style={{ padding:'7px 14px', fontSize:12, fontWeight:leadTab===t.id?700:400, color:leadTab===t.id?'var(--dgd-fg-1)':'var(--dgd-fg-3)', background:'none', border:'none', borderBottom:leadTab===t.id?'2px solid var(--dgd-fg-1)':'2px solid transparent', cursor:'pointer', marginBottom:-1 }}>
                          {t.label}
                        </button>
                      ))}
                    </div>

                    {leadTab === 'info' && (
                      <div style={{ padding:'14px 18px', display:'flex', gap:24, flexWrap:'wrap' }} onClick={e => e.stopPropagation()}>
                        <div style={{ flex:'1 1 220px' }}>
                          <div style={{ fontSize:10, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', letterSpacing:'0.07em', textTransform:'uppercase', marginBottom:8 }}>Dados do Lead</div>
                          {[
                            ['Nome',      lead.nome],
                            ['Empresa',   lead.empresa],
                            ['Cargo',     lead.cargo],
                            ['Marca',     lead.segmento],
                            ['Campanha',  lead.campanha],
                            ['País',      lead.pais],
                            ['Canal',     lead.canal],
                            ['Score',     lead.score != null ? String(lead.score) : null],
                            ['Ult. WA',   lead.ultimo_wa],
                          ].filter(([,v]) => v).map(([k,v]) => (
                            <div key={k} style={{ display:'flex', gap:8, marginBottom:5, fontSize:12 }}>
                              <span style={{ color:'var(--dgd-fg-3)', minWidth:80, flexShrink:0 }}>{k}</span>
                              <span style={{ color:'var(--dgd-fg-1)', fontWeight:500 }}>{v}</span>
                            </div>
                          ))}
                        </div>
                        <div style={{ flex: lead.bant_valores ? '1 1 240px' : '0 0 180px' }}>
                          <div style={{ fontSize:10, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', letterSpacing:'0.07em', textTransform:'uppercase', marginBottom:8 }}>
                            BANT{typeof lead.bant_n === 'number' ? ` ${lead.bant_n}/4` : ''}
                          </div>
                          {[['Budget','budget'],['Authority','authority'],['Need','need'],['Timeline','timeline']].map(([label,key]) => (
                            <div key={key} style={{ display:'flex', alignItems:'flex-start', gap:10, marginBottom:6, fontSize:12 }}>
                              <span style={{ color:'var(--dgd-fg-2)', minWidth:72 }}>{label}</span>
                              {lead.bant_valores ? (
                                <span style={{ color: lead.bant_valores[key] ? 'var(--dgd-fg-1)' : 'var(--dgd-fg-3)', fontWeight: lead.bant_valores[key] ? 500 : 400 }}>{lead.bant_valores[key] || '—'}</span>
                              ) : (
                                <BantIcon ok={lead.bant?.[key]} />
                              )}
                            </div>
                          ))}
                          {pelaRegra && <SdrAIRevisao lead={lead} onRevisao={onRevisao} />}
                        </div>
                        {(lead.recomendacao || lead.objecao || lead.equipamento) && (
                          <div style={{ flex:'1 1 260px' }}>
                            {lead.recomendacao && (<>
                              <div style={{ fontSize:10, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', letterSpacing:'0.07em', textTransform:'uppercase', marginBottom:6 }}>Recomendação Digi</div>
                              <div style={{ fontSize:12, color:'var(--dgd-fg-2)', lineHeight:1.6, marginBottom:12 }}>{lead.recomendacao}</div>
                            </>)}
                            {lead.objecao && (<>
                              <div style={{ fontSize:10, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', letterSpacing:'0.07em', textTransform:'uppercase', marginBottom:4 }}>Objecção Principal</div>
                              <div style={{ fontSize:12, color:'var(--dgd-fg-2)', lineHeight:1.5, marginBottom:10 }}>{lead.objecao}</div>
                            </>)}
                            {lead.equipamento && (<>
                              <div style={{ fontSize:10, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', letterSpacing:'0.07em', textTransform:'uppercase', marginBottom:4 }}>Equipamento Actual</div>
                              <div style={{ fontSize:12, color:'var(--dgd-fg-2)' }}>{lead.equipamento}</div>
                            </>)}
                          </div>
                        )}
                      </div>
                    )}

                    {leadTab === 'conversa' && (
                      <div style={{ padding:'14px 18px', maxHeight:300, overflowY:'auto' }} onClick={e => e.stopPropagation()}>
                        {(!lead.conversa || lead.conversa.length === 0) ? (
                          <div style={{ textAlign:'center', color:'var(--dgd-fg-3)', fontSize:12, padding:'20px 0' }}>Ainda sem conversas iniciadas.</div>
                        ) : (
                          <div style={{ display:'flex', flexDirection:'column', gap:8 }}>
                            {lead.conversa.map((msg, i) => (
                              <div key={i} style={{ display:'flex', flexDirection:'column', alignItems: msg.de === 'ai' ? 'flex-start' : 'flex-end' }}>
                                <div style={{ maxWidth:'75%', padding:'8px 12px', borderRadius: msg.de === 'ai' ? '4px 12px 12px 12px' : '12px 4px 12px 12px', background: msg.de === 'ai' ? '#eff6ff' : '#dcfce7', border: msg.de === 'ai' ? '1px solid #bfdbfe' : '1px solid #bbf7d0', fontSize:12, color:'var(--dgd-fg-1)', lineHeight:1.5 }}>
                                  {msg.msg}
                                </div>
                                <div style={{ fontSize:10, color:'var(--dgd-fg-3)', marginTop:2, fontFamily:'var(--dgd-font-mono,monospace)', paddingLeft:4, paddingRight:4 }}>
                                  {msg.de === 'ai' ? 'digi.ai' : lead.nome} · {msg.ts}
                                </div>
                              </div>
                            ))}
                          </div>
                        )}
                      </div>
                    )}

                    {leadTab === 'historico' && (
                      <div style={{ padding:'14px 18px', maxHeight:300, overflowY:'auto' }} onClick={e => e.stopPropagation()}>
                        {(!lead.historico || lead.historico.length === 0) ? (
                          <div style={{ textAlign:'center', color:'var(--dgd-fg-3)', fontSize:12, padding:'20px 0' }}>Sem interações anteriores registadas.</div>
                        ) : (
                          <table style={{ width:'100%', borderCollapse:'collapse', fontSize:12 }}>
                            <thead>
                              <tr>
                                {['Data','Campanha','Canal','Interação','Resultado'].map(h => (
                                  <th key={h} style={{ padding:'4px 10px', textAlign:'left', fontSize:10.5, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', borderBottom:'1px solid var(--dgd-border-1)', fontWeight:600, whiteSpace:'nowrap' }}>{h}</th>
                                ))}
                              </tr>
                            </thead>
                            <tbody>
                              {lead.historico.map((h, i) => (
                                <tr key={i} style={{ borderBottom:'1px solid var(--dgd-border-1)' }}>
                                  <td style={{ padding:'7px 10px', fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', whiteSpace:'nowrap' }}>{h.data}</td>
                                  <td style={{ padding:'7px 10px', fontWeight:500, color:'var(--dgd-fg-1)' }}>{h.campanha}</td>
                                  <td style={{ padding:'7px 10px', color:'var(--dgd-fg-3)', whiteSpace:'nowrap' }}>
                                    <span style={{ display:'inline-block', padding:'1px 7px', borderRadius:4, fontSize:10.5, fontWeight:500,
                                      background: h.canal==='Meta Ads' ? '#eff6ff' : h.canal==='Email' ? '#fefce8' : '#f0fdf4',
                                      color: h.canal==='Meta Ads' ? '#1d4ed8' : h.canal==='Email' ? '#854d0e' : '#166534' }}>{h.canal}</span>
                                  </td>
                                  <td style={{ padding:'7px 10px', color:'var(--dgd-fg-2)' }}>{h.interacao}</td>
                                  <td style={{ padding:'7px 10px', color:'var(--dgd-fg-3)', fontSize:11 }}>{h.resultado}</td>
                                </tr>
                              ))}
                            </tbody>
                          </table>
                        )}
                      </div>
                    )}
                  </div>
                )}
              </React.Fragment>
            );
          })}
        </div>
      )}
      <div style={{ padding:'8px 14px', borderTop:'1px solid var(--dgd-border-1)', fontSize:11, color:'var(--dgd-fg-3)' }}>
        {filtered.length} lead{filtered.length !== 1 ? 's' : ''}
      </div>
    </div>
  );
};

// ─── Inbound de marketing — a fila que entra para a Digi qualificar ───────────

const SDR_AI_ORDEM_MARCAS = ['Mimaki', 'BIOND', 'Decal', 'AllDecor', 'Sensek', 'NetScreen', 'Digidelta'];
const SDR_AI_MES_LONGO = { Jan:'Janeiro', Fev:'Fevereiro', Mar:'Março', Abr:'Abril', Mai:'Maio', Jun:'Junho', Jul:'Julho', Ago:'Agosto', Set:'Setembro', Out:'Outubro', Nov:'Novembro', Dez:'Dezembro' };

function sdrAiDataLead(lead, ano) {
  const m = String(lead.data || '').match(/^(\d{2})\/(\d{2})$/);
  if (!m) return null;
  return new Date(Number(ano) || new Date().getFullYear(), Number(m[2]) - 1, Number(m[1]));
}

function sdrAiDia(d) {
  return new Date(d.getFullYear(), d.getMonth(), d.getDate());
}

function sdrAiChao(ano) {
  return new Date(Number(ano) || new Date().getFullYear(), SDR_AI_DESDE_MES, 1);
}

function sdrAiTecto(ano) {
  const hoje = sdrAiDia(new Date());
  const fimAno = new Date(Number(ano) || hoje.getFullYear(), 11, 31);
  return hoje < fimAno ? hoje : fimAno;
}

function sdrAiPeriodoTodo(ano) {
  return { preset: 'all', start: sdrAiChao(ano), end: sdrAiTecto(ano) };
}

function sdrAiIntervalo(id, ano) {
  const hoje = sdrAiDia(new Date());
  const chao = sdrAiChao(ano);
  const tecto = sdrAiTecto(ano);
  let s = hoje;
  let e = hoje;
  if (id === 'yesterday') s = e = new Date(hoje.getFullYear(), hoje.getMonth(), hoje.getDate() - 1);
  else if (id === 'last_7d') s = new Date(hoje.getFullYear(), hoje.getMonth(), hoje.getDate() - 6);
  else if (id === 'last_28d') s = new Date(hoje.getFullYear(), hoje.getMonth(), hoje.getDate() - 27);
  else if (id === 'last_30d') s = new Date(hoje.getFullYear(), hoje.getMonth(), hoje.getDate() - 29);
  else if (id === 'last_90d') s = new Date(hoje.getFullYear(), hoje.getMonth(), hoje.getDate() - 89);
  else if (id === 'this_month') s = new Date(hoje.getFullYear(), hoje.getMonth(), 1);
  else if (id === 'last_month') {
    s = new Date(hoje.getFullYear(), hoje.getMonth() - 1, 1);
    e = new Date(hoje.getFullYear(), hoje.getMonth(), 0);
  } else if (id === 'qtd') s = new Date(hoje.getFullYear(), Math.floor(hoje.getMonth() / 3) * 3, 1);
  if (s < chao) s = chao;
  if (e > tecto) e = tecto;
  if (s > e) return null;
  return { preset: id, start: s, end: e };
}

function sdrAiIntervaloMes(mes, ano) {
  const i = SDR_AI_MESES.indexOf(mes);
  if (i < 0) return sdrAiPeriodoTodo(ano);
  const s = new Date(Number(ano), i, 1);
  let e = new Date(Number(ano), i + 1, 0);
  const tecto = sdrAiTecto(ano);
  if (e > tecto && s <= tecto) e = tecto;
  return { preset: 'custom', start: s, end: e };
}

function sdrAiNoPeriodoFiltro(lead, periodo, ano) {
  if (!periodo || periodo.preset === 'all' || !periodo.start || !periodo.end) return true;
  const dia = sdrAiDataLead(lead, ano);
  if (!dia) return false;
  return dia >= sdrAiDia(periodo.start) && dia <= sdrAiDia(periodo.end);
}

function sdrAiContactoDigi(lead) {
  const fase = lead.circuito?.fase;
  return fase === 'atendeu' || fase === 'recusou' || fase === 'wa_respondeu' || lead.circuito?.resultado === 'atendeu';
}

function sdrAiDigitosTel(v) {
  return String(v || '').replace(/\D/g, '');
}

function sdrAiMercado(lead) {
  const d = sdrAiDigitosTel(lead?.telefone);
  const pais = String(lead?.pais || '').toLowerCase();
  const dizEs = /espan|spain|^es$/.test(pais);
  const dizPt = /portug|^pt$/.test(pais);
  let nacional = d;
  let prefixo = '';
  if (d.startsWith('00351')) { prefixo = 'PT'; nacional = d.slice(5); }
  else if (d.startsWith('0034')) { prefixo = 'ES'; nacional = d.slice(4); }
  else if (d.startsWith('351') && d.length >= 12) { prefixo = 'PT'; nacional = d.slice(3); }
  else if (d.startsWith('34') && d.length >= 11) { prefixo = 'ES'; nacional = d.slice(2); }
  if (prefixo === 'PT') return /^[29]\d{8}$/.test(nacional) ? 'PT' : 'OUTRO';
  if (prefixo === 'ES') return /^[6789]\d{8}$/.test(nacional) ? 'ES' : 'OUTRO';
  if (nacional.length === 9) {
    if (dizEs && /^[6789]/.test(nacional)) return 'ES';
    if (/^[67]/.test(nacional) || nacional.startsWith('8')) return 'ES';
    if (nacional.startsWith('2') || nacional.startsWith('9')) return dizEs ? 'ES' : 'PT';
  }
  if (dizEs) return 'ES';
  if (dizPt) return 'PT';
  return 'OUTRO';
}

function sdrAiForaDoPedido(lead) {
  const fase = lead.circuito?.fase;
  const motivo = lead.circuito?.motivo || '';
  if (fase === 'assistencia' || motivo === 'assistencia' || motivo === 'recrutamento' || motivo === 'pediu_email') return true;
  if (lead.source !== 'WEB') return false;
  const texto = `${lead.pedido || ''} ${lead.form_nome || ''}`.toLowerCase();
  if (/recrut|candidat|emprego/.test(texto)) return true;
  if (/avaria|m[aá]quina parada|n[aã]o imprime|assist[eê]ncia|suporte t[eé]cnico/.test(texto)) return true;
  if (/n[aã]o me liguem|s[oó] por e-?mail|prefiro e-?mail/.test(texto)) return true;
  return false;
}

function sdrAiElegivel(lead) {
  const mercado = sdrAiMercado(lead);
  if (mercado !== 'PT' && mercado !== 'ES') return false;
  if (sdrAiDigitosTel(lead.telefone).length < 9) return false;
  return !sdrAiForaDoPedido(lead);
}

function sdrAiFicouNaChamada(lead) {
  const fase = lead.circuito?.fase;
  if (fase === 'recusou' || fase === 'wa_respondeu') return false;
  return fase === 'atendeu' || !!lead.respondeu;
}

function sdrAiQualificadaBant(lead) {
  if ((lead.bant_n || 0) < 4) return false;
  const prazo = String(lead.bant_valores?.timeline || '').trim();
  return /^(0-3m|3-6m|6-12m)$/i.test(prazo);
}

function sdrAiGanha(lead) {
  return lead?.op_status === 'WON' || lead?.oportunidade === 'Ganha';
}

function sdrAiTemOportunidade(lead) {
  return !!(lead?.stage || lead?.oportunidade);
}

function sdrAiEstadoNurturing(lead) {
  if (sdrAiGanha(lead)) return { label: 'Ganha', cor: '#166534' };
  return { label: 'Em nurturing', cor: '#92400e' };
}

function sdrAiEstadoOk(lead, estado) {
  if (!estado || estado === 'all' || estado === 'atribuidos') return true;
  if (estado === 'contactados') return !!lead.respondeu || sdrAiContactoDigi(lead);
  if (estado === 'elegiveis') return sdrAiElegivel(lead);
  if (estado === 'qualificados') return sdrAiQualificadaBant(lead);
  if (estado === 'nao_qualificados') return !!lead.recusa;
  if (estado === 'chamadas') return !!lead.circuito?.chamada;
  if (estado === 'whatsapp') return lead.circuito?.wa_estado === 'enviado';
  if (estado === 'sem_contacto') return lead.circuito?.fase === 'sem_contacto';
  if (estado === 'nurturing') return sdrAiTemOportunidade(lead) && !sdrAiGanha(lead);
  if (estado === 'nurturing_ganhas') return sdrAiGanha(lead);
  if (estado === 'nurturing_contactos' || estado === 'nurturing_demos') return false;
  return true;
}

function sdrAiOportOk(lead, oport) {
  if (!oport || oport === 'all') return true;
  if (oport === 'sem') return !lead.stage && !lead.oportunidade;
  return lead.stage === oport;
}

const SDR_AI_COLUNAS = [
  { id: 'nome', label: 'Nome', w: 160 },
  { id: 'empresa', label: 'Empresa', w: 160 },
  { id: 'email', label: 'Email', w: 200 },
  { id: 'telefone', label: 'Telefone', w: 130 },
  { id: 'origem', label: 'Origem', w: 240 },
  { id: 'estado', label: 'Estado', w: 140 },
  { id: 'bant', label: 'BANT', w: 90 },
  { id: 'oportunidade', label: 'Oportunidade', w: 150 },
];

const SDR_AI_COLUNAS_NURTURING = [
  { id: 'empresa', label: 'Empresa', w: 180 },
  { id: 'contacto', label: 'Contacto', w: 160 },
  { id: 'oportunidade', label: 'Oportunidade', w: 180 },
  { id: 'stage', label: 'Stage', w: 150 },
  { id: 'proximo', label: 'Próximo', w: 120 },
  { id: 'estado', label: 'Estado', w: 140 },
  { id: 'valor', label: 'Valor', w: 110 },
];

function sdrAiDirInicial(ordem) {
  return ordem === 'recentes' || ordem === 'bant' || ordem === 'valor' ? 'desc' : 'asc';
}

function sdrAiLargurasIniciais() {
  const base = {};
  SDR_AI_COLUNAS.concat(SDR_AI_COLUNAS_NURTURING).forEach(c => { base[c.id] = c.w; });
  try {
    const gravado = JSON.parse(localStorage.getItem('sdr-ai-lista-larguras') || '{}');
    SDR_AI_COLUNAS.concat(SDR_AI_COLUNAS_NURTURING).forEach(c => {
      const n = Number(gravado[c.id]);
      if (n >= 56 && n <= 640) base[c.id] = n;
    });
  } catch { /* larguras de origem */ }
  return base;
}

function sdrAiOrdenar(lista, ordem, ano, dir, modo) {
  const out = lista.slice();
  const sentido = dir || sdrAiDirInicial(ordem);
  const vazio = (v) => v == null || v === '' || v === '—';
  const cmp = (a, b) => {
    if (vazio(a) && vazio(b)) return 0;
    if (vazio(a)) return 1;
    if (vazio(b)) return -1;
    const r = typeof a === 'number' && typeof b === 'number'
      ? a - b
      : String(a).localeCompare(String(b), 'pt', { numeric: true, sensitivity: 'base' });
    return sentido === 'asc' ? r : -r;
  };
  const valorDe = (lead) => {
    if (ordem === 'nome') return sdrAiNomeLista(lead);
    if (ordem === 'empresa') return lead.empresa;
    if (ordem === 'email') return lead.email;
    if (ordem === 'telefone') return lead.telefone;
    if (ordem === 'origem') return sdrAiOrigemChave(lead);
    if (ordem === 'estado') return (modo === 'nurturing' ? sdrAiEstadoNurturing(lead) : sdrAiEstadoConsulta(lead)).label;
    if (ordem === 'bant') return lead.bant_n;
    if (ordem === 'contacto') return sdrAiNomeLista(lead);
    if (ordem === 'stage') return lead.stage;
    if (ordem === 'proximo') return null;
    if (ordem === 'valor') return lead.valor > 1 ? Number(lead.valor) : null;
    if (ordem === 'oportunidade') {
      const ganha = lead.op_status === 'WON' || lead.oportunidade === 'Ganha';
      return lead.stage || (ganha ? 'Ganha' : lead.oportunidade) || null;
    }
    return sdrAiDataLead(lead, ano)?.getTime() || null;
  };
  out.sort((a, b) => cmp(valorDe(a), valorDe(b)));
  return out;
}

const SdrAIFiltro = ({ label, value, options, onChange, marcado = false, menuMinWidth = 180, menuMaxHeight = 320 }) => {
  const [open, setOpen] = React.useState(false);
  const [over, setOver] = React.useState(false);
  const [overItem, setOverItem] = React.useState(null);
  const ref = React.useRef(null);
  React.useEffect(() => {
    if (!open) return;
    const fechar = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown', fechar);
    return () => document.removeEventListener('mousedown', fechar);
  }, [open]);
  const current = options.find(o => o.value === value) || { value, label: value || '—' };
  const vazio = options[0]?.value;
  const activoVisual = marcado || open;
  const azul = 'var(--ai-500, #3859D0)';
  return (
    <div ref={ref} style={{ position: 'relative' }}>
      <button type="button" onClick={() => setOpen(v => !v)}
        onMouseEnter={() => setOver(true)} onMouseLeave={() => setOver(false)}
        style={{
          background: activoVisual ? 'color-mix(in oklch, var(--ai-500, #3859D0) 8%, #fff)' : (over ? '#f1f5f9' : '#fff'),
          color: '#112954',
          border: `1px solid ${over || open || marcado ? azul : '#dde3ef'}`,
          borderRadius: 6, padding: '6px 10px', fontSize: 11.5,
          display: 'inline-flex', alignItems: 'center', gap: 8,
          cursor: 'pointer', fontFamily: 'inherit', maxWidth: 320,
        }}>
        <span style={{ color: '#475569', fontSize: 10, textTransform: 'uppercase', letterSpacing: '.06em', fontFamily: 'var(--dgd-font-mono, monospace)', flexShrink: 0 }}>{label}</span>
        <span style={{ fontWeight: marcado ? 600 : 500, color: marcado ? azul : '#112954', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{current.label}</span>
        {marcado && (
          <span aria-hidden="true" title={`Limpar ${label}`}
            onMouseDown={e => { e.preventDefault(); e.stopPropagation(); }}
            onClick={e => { e.preventDefault(); e.stopPropagation(); onChange(vazio); setOpen(false); }}
            style={{ color: azul, fontSize: 14, lineHeight: 1, flexShrink: 0, padding: '0 2px', cursor: 'pointer' }}>×</span>
        )}
        <span style={{ color: '#64748b', fontSize: 9, flexShrink: 0 }}>▾</span>
      </button>
      {open && (
        <div style={{
          position: 'absolute', top: 'calc(100% + 4px)', left: 0, zIndex: 40,
          background: '#fff', border: '1px solid #dde3ef', borderRadius: 6,
          boxShadow: '0 8px 24px rgba(17,41,84,0.12)', minWidth: menuMinWidth, padding: 4, maxHeight: menuMaxHeight, overflowY: 'auto',
        }}>
          {options.map((o, i) => {
            const activo = o.value === value || overItem === o.value;
            const header = o.grupo && o.grupo !== options[i - 1]?.grupo;
            return (
              <React.Fragment key={String(o.value)}>
                {header && <div style={{ padding: '8px 10px 3px', fontSize: 10, fontWeight: 600, letterSpacing: '.06em', textTransform: 'uppercase', color: '#475569', fontFamily: 'var(--dgd-font-mono, monospace)' }}>{o.grupo}</div>}
                <button type="button"
                  onClick={() => { onChange(o.value); setOpen(false); }}
                  onMouseEnter={() => setOverItem(o.value)}
                  onMouseLeave={() => setOverItem(null)}
                  style={{
                    display: 'flex', alignItems: 'center', gap: 8, width: '100%', textAlign: 'left',
                    background: activo ? 'color-mix(in oklch, var(--ai-500, #3859D0) 12%, transparent)' : 'transparent',
                    color: o.value === value ? azul : '#112954',
                    border: 'none', padding: '7px 10px', borderRadius: 4,
                    fontSize: 12, fontWeight: o.value === value ? 600 : 500, cursor: 'pointer', fontFamily: 'inherit',
                  }}>
                  <span style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{o.label}</span>
                  {o.n != null && <span style={{ color: '#64748b', fontVariantNumeric: 'tabular-nums', flexShrink: 0 }}>{Number(o.n).toLocaleString('pt-PT')}</span>}
                </button>
              </React.Fragment>
            );
          })}
        </div>
      )}
    </div>
  );
};

const SDR_AI_PERIODO_PRESETS = [
  { id: 'all', label: 'Todo o período' },
  { id: 'custom', label: 'Personalizado' },
  { id: 'today', label: 'Hoje' },
  { id: 'yesterday', label: 'Ontem' },
  { id: 'last_7d', label: 'Últimos 7 dias' },
  { id: 'last_28d', label: 'Últimos 28 dias' },
  { id: 'last_30d', label: 'Últimos 30 dias' },
  { id: 'this_month', label: 'Este mês' },
  { id: 'last_month', label: 'Mês passado' },
  { id: 'last_90d', label: 'Últimos 90 dias' },
  { id: 'qtd', label: 'Trimestre actual' },
];

const SdrAIPeriodo = ({ value, onChange, ano }) => {
  const ref = React.useRef(null);
  const [open, setOpen] = React.useState(false);
  const [over, setOver] = React.useState(false);
  const [overPreset, setOverPreset] = React.useState(null);
  const [overBtn, setOverBtn] = React.useState(null);
  const [draftStart, setDraftStart] = React.useState(value.start);
  const [draftEnd, setDraftEnd] = React.useState(value.end);
  const [draftPreset, setDraftPreset] = React.useState(value.preset);
  const [pickStart, setPickStart] = React.useState(true);
  const [anchor, setAnchor] = React.useState(() => {
    const d = new Date(value.end || sdrAiTecto(ano));
    return new Date(d.getFullYear(), d.getMonth() - 1, 1);
  });
  const chao = sdrAiChao(ano);
  const tecto = sdrAiTecto(ano);
  const labels = Object.fromEntries(SDR_AI_PERIODO_PRESETS.map(p => [p.id, p.label]));
  const fmt = (d) => d ? d.toLocaleDateString('pt-PT', { day: 'numeric', month: 'short', year: 'numeric' }).replace('.', '') : '—';
  const fmtCurto = (d) => d ? d.toLocaleDateString('pt-PT', { day: 'numeric', month: 'short' }).replace('.', '') : '';

  React.useEffect(() => {
    if (!open) return;
    const fechar = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown', fechar);
    return () => document.removeEventListener('mousedown', fechar);
  }, [open]);
  React.useEffect(() => {
    if (!open) return;
    setDraftStart(value.start || chao);
    setDraftEnd(value.end || tecto);
    setDraftPreset(value.preset || 'all');
    const d = new Date(value.end || tecto);
    setAnchor(new Date(d.getFullYear(), d.getMonth() - 1, 1));
    setPickStart(true);
  }, [open]);

  const aplicarPreset = (id) => {
    if (id === 'custom') { setDraftPreset('custom'); return; }
    if (id === 'all') {
      setDraftPreset('all');
      setDraftStart(chao);
      setDraftEnd(tecto);
      setAnchor(new Date(tecto.getFullYear(), tecto.getMonth() - 1, 1));
      setPickStart(true);
      return;
    }
    const r = sdrAiIntervalo(id, ano);
    if (!r) return;
    setDraftPreset(r.preset);
    setDraftStart(r.start);
    setDraftEnd(r.end);
    setAnchor(new Date(r.end.getFullYear(), r.end.getMonth() - 1, 1));
    setPickStart(true);
  };

  const escolherDia = (d) => {
    if (d < chao || d > tecto) return;
    if (pickStart || !draftStart || (draftEnd && d < draftStart)) {
      setDraftStart(d);
      setDraftEnd(d);
      setPickStart(false);
      setDraftPreset('custom');
    } else {
      setDraftEnd(d < draftStart ? draftStart : d);
      if (d < draftStart) setDraftStart(d);
      setPickStart(true);
      setDraftPreset('custom');
    }
  };

  const aplicar = () => {
    if (draftPreset === 'all') onChange(sdrAiPeriodoTodo(ano));
    else onChange({ preset: draftPreset, start: draftStart, end: draftEnd });
    setOpen(false);
  };

  const marcado = value.preset && value.preset !== 'all';
  const azul = 'var(--ai-500, #3859D0)';
  const trigger = labels[value.preset] || 'Personalizado';
  const intervalo = marcado && value.start && value.end ? `${fmtCurto(value.start)} – ${fmt(value.end)}` : '';

  const Mes = ({ date }) => {
    const y = date.getFullYear();
    const m = date.getMonth();
    const primeiro = new Date(y, m, 1).getDay();
    const dias = new Date(y, m + 1, 0).getDate();
    const cells = [];
    for (let i = 0; i < primeiro; i++) cells.push(null);
    for (let d = 1; d <= dias; d++) cells.push(new Date(y, m, d));
    const noIntervalo = (d) => draftStart && draftEnd && d >= sdrAiDia(draftStart) && d <= sdrAiDia(draftEnd);
    const igual = (d, outro) => outro && d.getTime() === sdrAiDia(outro).getTime();
    return (
      <div style={{ marginBottom: 10 }}>
        <div style={{ fontSize: 10.5, fontFamily: 'var(--dgd-font-mono, monospace)', color: '#64748b', letterSpacing: '.08em', padding: '4px 6px' }}>
          {date.toLocaleDateString('pt-PT', { month: 'long', year: 'numeric' }).toUpperCase()}
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 1 }}>
          {cells.map((d, i) => {
            if (!d) return <div key={i} />;
            const fora = d < chao || d > tecto;
            const dentro = noIntervalo(d);
            const extremo = igual(d, draftStart) || igual(d, draftEnd);
            return (
              <button key={i} type="button" disabled={fora} onClick={() => escolherDia(d)} style={{
                width: 30, height: 30, lineHeight: '30px', textAlign: 'center', padding: 0,
                border: 'none', cursor: fora ? 'default' : 'pointer', fontFamily: 'inherit',
                background: extremo ? azul : (dentro ? 'color-mix(in oklch, var(--ai-500, #3859D0) 18%, transparent)' : 'transparent'),
                color: fora ? '#cbd5e1' : extremo ? '#fff' : (dentro ? azul : '#112954'),
                borderRadius: extremo ? '50%' : 4, fontWeight: extremo ? 600 : 500, fontSize: 11.5,
              }}>{d.getDate()}</button>
            );
          })}
        </div>
      </div>
    );
  };

  const seguinte = new Date(anchor.getFullYear(), anchor.getMonth() + 1, 1);

  return (
    <div ref={ref} style={{ position: 'relative' }}>
      <button type="button" onClick={() => setOpen(v => !v)}
        onMouseEnter={() => setOver(true)} onMouseLeave={() => setOver(false)}
        style={{
          background: marcado || open ? 'color-mix(in oklch, var(--ai-500, #3859D0) 8%, #fff)' : (over ? '#f1f5f9' : '#fff'),
          color: '#112954',
          border: `1px solid ${over || open || marcado ? azul : '#dde3ef'}`,
          borderRadius: 6, padding: '6px 10px', fontSize: 11.5,
          display: 'inline-flex', alignItems: 'center', gap: 8,
          cursor: 'pointer', fontFamily: 'inherit', maxWidth: 360,
        }}>
        <span style={{ color: '#475569', fontSize: 10, textTransform: 'uppercase', letterSpacing: '.06em', fontFamily: 'var(--dgd-font-mono, monospace)', flexShrink: 0 }}>Período</span>
        <span style={{ fontWeight: marcado ? 600 : 500, color: marcado ? azul : '#112954', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{trigger}</span>
        {intervalo && <span style={{ color: '#64748b', fontFamily: 'var(--dgd-font-mono, monospace)', fontSize: 11, flexShrink: 0 }}>{intervalo}</span>}
        {marcado && (
          <span aria-hidden="true" title="Limpar Período"
            onMouseDown={e => { e.preventDefault(); e.stopPropagation(); }}
            onClick={e => { e.preventDefault(); e.stopPropagation(); onChange(sdrAiPeriodoTodo(ano)); setOpen(false); }}
            style={{ color: azul, fontSize: 14, lineHeight: 1, flexShrink: 0, padding: '0 2px', cursor: 'pointer' }}>×</span>
        )}
        <span style={{ color: '#64748b', fontSize: 9, flexShrink: 0 }}>▾</span>
      </button>
      {open && (
        <div style={{
          position: 'absolute', top: 'calc(100% + 6px)', right: 0, zIndex: 60,
          background: '#fff', border: '1px solid #dde3ef', borderRadius: 8,
          boxShadow: '0 12px 32px rgba(17,41,84,0.16)', display: 'flex', minWidth: 580, maxWidth: 640,
        }}>
          <div style={{ width: 200, borderRight: '1px solid #dde3ef', padding: '6px 0', maxHeight: 460, overflowY: 'auto' }}>
            {SDR_AI_PERIODO_PRESETS.map(p => {
              const activo = draftPreset === p.id || overPreset === p.id;
              return (
                <button key={p.id} type="button" onClick={() => aplicarPreset(p.id)}
                  onMouseEnter={() => setOverPreset(p.id)} onMouseLeave={() => setOverPreset(null)}
                  style={{
                    display: 'block', width: '100%', textAlign: 'left',
                    background: activo ? 'color-mix(in oklch, var(--ai-500, #3859D0) 12%, transparent)' : 'transparent',
                    color: activo ? azul : '#112954', border: 'none', padding: '8px 14px',
                    fontSize: 12.5, fontWeight: draftPreset === p.id ? 600 : 500, cursor: 'pointer', fontFamily: 'inherit',
                  }}>{p.label}</button>
              );
            })}
          </div>
          <div style={{ flex: 1, padding: 14, display: 'flex', flexDirection: 'column' }}>
            <div style={{ display: 'flex', gap: 8, marginBottom: 10 }}>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 9.5, color: '#475569', textTransform: 'uppercase', letterSpacing: '.08em', fontFamily: 'var(--dgd-font-mono, monospace)', marginBottom: 3 }}>Data início</div>
                <div style={{ border: `1px solid ${pickStart ? azul : '#dde3ef'}`, borderRadius: 4, padding: '5px 8px', fontSize: 12, background: '#f5f7fa' }}>{fmt(draftStart)}</div>
              </div>
              <div style={{ alignSelf: 'flex-end', padding: '6px 0', color: '#64748b' }}>—</div>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 9.5, color: '#475569', textTransform: 'uppercase', letterSpacing: '.08em', fontFamily: 'var(--dgd-font-mono, monospace)', marginBottom: 3 }}>Data fim</div>
                <div style={{ border: `1px solid ${!pickStart ? azul : '#dde3ef'}`, borderRadius: 4, padding: '5px 8px', fontSize: 12, background: '#f5f7fa' }}>{fmt(draftEnd)}</div>
              </div>
            </div>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 4 }}>
              <button type="button" onClick={() => setAnchor(new Date(anchor.getFullYear(), anchor.getMonth() - 1, 1))} style={{ background: 'none', border: '1px solid #dde3ef', borderRadius: 4, width: 24, height: 24, color: '#64748b', cursor: 'pointer' }}>‹</button>
              <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 1, flex: 1, padding: '0 8px' }}>
                {['D', 'S', 'T', 'Q', 'Q', 'S', 'S'].map((d, i) => (
                  <div key={i} style={{ textAlign: 'center', fontSize: 10, color: '#64748b', fontFamily: 'var(--dgd-font-mono, monospace)' }}>{d}</div>
                ))}
              </div>
              <button type="button" onClick={() => setAnchor(new Date(anchor.getFullYear(), anchor.getMonth() + 1, 1))} style={{ background: 'none', border: '1px solid #dde3ef', borderRadius: 4, width: 24, height: 24, color: '#64748b', cursor: 'pointer' }}>›</button>
            </div>
            <div style={{ flex: 1, overflowY: 'auto', maxHeight: 360, padding: '0 30px' }}>
              <Mes date={anchor} />
              <Mes date={seguinte} />
            </div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 10, paddingTop: 10, borderTop: '1px solid #dde3ef' }}>
              <span style={{ flex: 1, minWidth: 0, fontSize: 10.5, color: '#64748b', fontFamily: 'var(--dgd-font-mono, monospace)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                {draftPreset === 'all' ? 'Sem limite de datas' : (draftStart && draftEnd ? `${Math.round((sdrAiDia(draftEnd) - sdrAiDia(draftStart)) / 86400000) + 1} dias` : '')}
              </span>
              <button type="button" onClick={() => setOpen(false)}
                onMouseEnter={() => setOverBtn('cancelar')} onMouseLeave={() => setOverBtn(null)}
                style={{ height: 28, padding: '0 12px', borderRadius: 6, fontSize: 12, fontWeight: 500, fontFamily: 'inherit', cursor: 'pointer', background: overBtn === 'cancelar' ? '#f1f5f9' : '#fff', color: '#112954', border: '1px solid #dde3ef' }}>Cancelar</button>
              <button type="button" onClick={aplicar}
                onMouseEnter={() => setOverBtn('aplicar')} onMouseLeave={() => setOverBtn(null)}
                style={{ height: 28, padding: '0 14px', borderRadius: 6, fontSize: 12, fontWeight: 600, fontFamily: 'inherit', cursor: 'pointer', background: azul, color: '#fff', border: `1px solid ${azul}`, filter: overBtn === 'aplicar' ? 'brightness(1.08)' : 'none' }}>Aplicar</button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

function sdrAiEntradasDe(leads) {
  return SDR_AI_MESES.map(mes => {
    const rows = leads.filter(l => l.mes === mes);
    return {
      mes,
      entradas: rows.length,
      ads: rows.filter(l => l.source === 'ADS').length,
      web: rows.filter(l => l.source === 'WEB').length,
      newsletter: rows.filter(l => l.source === 'NEWSLETTER').length,
    };
  });
}

const SdrAIInboundTable = ({ rows, onCellClick }) => {
  const mesIdx = (() => { const m = SDR_AI_MESES[new Date().getMonth()]; const i = rows.findIndex(r => r.mes === m); return i >= 0 ? i : rows.length - 1; })();
  const nCols = rows.length + 2;
  const fv = (val, i) => i > mesIdx ? '—' : val;
  const ytd = rows.reduce((s, r) => ({
    entradas: s.entradas + (r.entradas || 0),
    ads: s.ads + (r.ads || 0),
    web: s.web + (r.web || 0),
    newsletter: s.newsletter + (r.newsletter || 0),
  }), { entradas: 0, ads: 0, web: 0, newsletter: 0 });
  const th = { padding: '7px 8px', textAlign: 'right', fontSize: 11, color: 'var(--dgd-fg-3)', fontFamily: 'var(--dgd-font-mono,monospace)', borderBottom: '1px solid var(--dgd-border-1)', whiteSpace: 'nowrap', fontWeight: 600 };
  const thL = { ...th, textAlign: 'left' };
  const tdBase = { padding: '6px 8px', fontSize: 12, fontFamily: 'var(--dgd-font-mono,monospace)', borderBottom: '1px solid var(--dgd-border-1)', whiteSpace: 'nowrap', textAlign: 'right', color: 'var(--dgd-fg-2)' };
  const tdL = { ...tdBase, textAlign: 'left' };
  const clickStyle = { cursor: 'pointer', textDecoration: 'underline', textDecorationStyle: 'dotted' };
  const linha = (label, metric, key) => (
    <tr>
      <td style={tdL}>{label}</td>
      {rows.map((r, i) => (
        <td key={r.mes} style={{ ...tdBase, fontWeight: i === mesIdx ? 700 : 400, ...(onCellClick ? clickStyle : {}) }} onClick={() => onCellClick && onCellClick(metric, r.mes)}>{fv(r[key] || 0, i)}</td>
      ))}
      <td style={{ ...tdBase, fontWeight: 700, color: 'var(--dgd-fg-1)' }}>{ytd[key]}</td>
    </tr>
  );
  return (
    <div style={{ overflowX: 'auto' }}>
      <table style={{ borderCollapse: 'collapse', width: '100%', fontSize: 12 }}>
        <thead>
          <tr>
            <th style={{ ...thL, minWidth: 160 }}>Métrica</th>
            {rows.map((r, i) => (
              <th key={r.mes} style={{ ...th, fontWeight: i === mesIdx ? 700 : 600, color: i === mesIdx ? 'var(--dgd-fg-1)' : 'var(--dgd-fg-3)' }}>{r.mes}</th>
            ))}
            <th style={{ ...th, color: 'var(--dgd-fg-1)' }}>YTD</th>
          </tr>
        </thead>
        <tbody>
          <SdrAISectionRow cols={nCols}>Entradas de marketing</SdrAISectionRow>
          {linha('Entradas', 'entradas', 'entradas')}
          {linha('ADS', 'ADS', 'ads')}
          {linha('WEB', 'WEB', 'web')}
          {linha('NEWSLETTER', 'NEWSLETTER', 'newsletter')}
        </tbody>
      </table>
    </div>
  );
};

function sdrAiNomeLista(lead) {
  if (/^\[your-name\]$/i.test(lead.nome || '')) return lead.email || 'Sem nome';
  return lead.nome;
}

function sdrAiOrigem(lead) {
  const nome = String(lead.action || '').trim();
  return nome && nome !== '—' ? nome : '—';
}

function sdrAiSite(lead) {
  const raw = String(lead.page_url || '').trim();
  if (!raw) return '';
  try {
    return new URL(raw.includes('://') ? raw : `https://${raw}`).hostname.replace(/^www\./i, '');
  } catch {
    return '';
  }
}

function sdrAiOrigemChave(lead) {
  const nome = sdrAiOrigem(lead);
  if (lead.source !== 'WEB') return nome;
  const site = sdrAiSite(lead);
  return site ? `${nome} · ${site}` : nome;
}

function sdrAiOrigemCanal(lead) {
  const source = lead.source_label || lead.source || '';
  const canal = lead.canal || '';
  if (lead.source === 'ADS' && canal && canal !== source) return `${source} · ${canal}`;
  if (lead.source === 'WEB') {
    const site = sdrAiSite(lead);
    return site ? `WEB · ${site}` : 'WEB';
  }
  return source;
}

function sdrAiGrupoOrigem(lead) {
  if (lead.source === 'WEB') return 'Formulários';
  if (lead.source === 'NEWSLETTER') return 'Newsletters';
  return 'Campanhas';
}

function sdrAiDetalhe(lead) {
  if (lead.source === 'ADS') return lead.canal || '—';
  if (lead.source === 'WEB' && /footer/i.test(lead.action || '') && !lead.pedido) return 'Só email';
  const texto = String(lead.pedido || lead.assunto || '').replace(/\s+/g, ' ').trim();
  return texto ? texto.slice(0, 90) : '—';
}

function sdrAiValorCampo(lead, re) {
  for (const c of lead.campos || []) {
    if (re.test(String(c.label || '').trim()) && c.value) return String(c.value).trim();
  }
  return '';
}

function sdrAiCidade(lead) {
  return sdrAiValorCampo(lead, /^(city|cidade)$/i);
}

function sdrAiRespostaForm(lead) {
  const inv = sdrAiValorCampo(lead, /estimativa de investimento/i);
  const prob = sdrAiValorCampo(lead, /informa[cç][õo]es sobre o problema/i);
  if (inv && prob) return `Investimento: ${inv}\nProblema: ${prob}`;
  return inv || prob || '';
}

function SdrAICelula({ texto, style, title }) {
  const v = texto && String(texto).trim() ? String(texto).trim() : '—';
  const tip = title && String(title).trim() ? String(title).trim() : (v !== '—' ? v : undefined);
  return <div title={tip} style={style}>{v}</div>;
}

function sdrAiTemTelefone(lead) {
  return String(lead.telefone || '').replace(/\D/g, '').length >= 9;
}

function sdrAiEuros(valor) {
  if (valor == null || valor <= 1) return '—';
  return new Intl.NumberFormat('pt-PT', { style: 'currency', currency: 'EUR', maximumFractionDigits: 0 }).format(valor);
}

const SdrAIBantLetras = ({ lead }) => {
  const fields = [['B', 'budget', 'Budget'], ['A', 'authority', 'Authority'], ['N', 'need', 'Need'], ['T', 'timeline', 'Timeline']];
  return (
    <div style={{ display: 'flex', gap: 3 }}>
      {fields.map(([label, key, nome]) => {
        const texto = lead.bant_valores?.[key];
        const flag = lead.bant?.[key];
        const v = flag === false ? false : (texto || flag === true ? true : null);
        const color = v === true ? '#166534' : v === false ? '#991b1b' : '#94a3b8';
        const bg = v === true ? '#f0fdf4' : v === false ? '#fef2f2' : '#f1f5f9';
        const border = v === true ? '#bbf7d0' : v === false ? '#fecaca' : '#e2e8f0';
        const title = v === true ? `${nome}: ${texto || 'sim'}` : v === false ? `${nome}: não` : nome;
        return <span key={key} title={title} style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', width: 18, height: 18, borderRadius: 3, fontSize: 9, fontWeight: 700, fontFamily: 'var(--dgd-font-mono,monospace)', color, background: bg, border: `1px solid ${border}` }}>{label}</span>;
      })}
    </div>
  );
};

const SdrAIInboundPanel = ({ leads: leadsTodas = [], sdrList = [], foco, selAno, recorte, onAbrir, onPassou, onLista, passados = {}, modo = 'qualificacao', onModo, nQual = 0, nNurt = 0 }) => {
  const [search, setSearch] = React.useState('');
  const [marca, setMarca] = React.useState('Todas');
  const [source, setSource] = React.useState('all');
  const [action, setAction] = React.useState('all');
  const [origem, setOrigem] = React.useState('all');
  const [estado, setEstado] = React.useState('all');
  const [oport, setOport] = React.useState('all');
  const [pais, setPais] = React.useState('all');
  const [ordem, setOrdem] = React.useState('recentes');
  const [ordemDir, setOrdemDir] = React.useState('desc');
  const [larguras, setLarguras] = React.useState(sdrAiLargurasIniciais);
  const arrastou = React.useRef(false);
  const [periodo, setPeriodo] = React.useState(() => sdrAiPeriodoTodo(selAno));
  const [sel, setSel] = React.useState({});
  const [sdrLote, setSdrLote] = React.useState('');
  const [aPassar, setAPassar] = React.useState(false);
  const [resumoPassar, setResumoPassar] = React.useState('');
  const [verArquivo, setVerArquivo] = React.useState(false);
  const [confirmarApagar, setConfirmarApagar] = React.useState(false);
  const [busca, setBusca] = React.useState(false);
  const [menuAberto, setMenuAberto] = React.useState(false);
  const menuRef = React.useRef(null);
  React.useEffect(() => {
    if (!menuAberto) return undefined;
    const fechar = (e) => { if (menuRef.current && !menuRef.current.contains(e.target)) setMenuAberto(false); };
    document.addEventListener('mousedown', fechar);
    return () => document.removeEventListener('mousedown', fechar);
  }, [menuAberto]);
  const headScrollRef = React.useRef(null);
  const bodyScrollRef = React.useRef(null);
  const leads = leadsTodas.filter(l => {
    if (verArquivo ? !l.arquivada : !!l.arquivada) return false;
    if (modo === 'nurturing' && !sdrAiTemOportunidade(l)) return false;
    return true;
  });

  const modoVisto = React.useRef(modo);
  React.useEffect(() => {
    if (modoVisto.current === modo) return;
    modoVisto.current = modo;
    setEstado('all');
    setOport('all');
    setPais('all');
    setSel({});
    setConfirmarApagar(false);
    setPeriodo(sdrAiPeriodoTodo(selAno));
  }, [modo]);

  const limparLista = () => {
    setMarca('Todas');
    setSource('all');
    setAction('all');
    setOrigem('all');
    setEstado('all');
    setOport('all');
    setPais('all');
    setOrdem('recentes');
    setOrdemDir('desc');
    setPeriodo(sdrAiPeriodoTodo(selAno));
    setSearch('');
  };

  const anoVisto = React.useRef(selAno);
  React.useEffect(() => {
    if (anoVisto.current !== selAno) {
      anoVisto.current = selAno;
      limparLista();
      return;
    }
    if (!recorte) return;
    setMarca('Todas');
    setSource('all');
    setAction('all');
    setOrigem('all');
    setOport('all');
    setPais('all');
    setOrdem('recentes');
    setOrdemDir('desc');
    setSearch('');
    setPeriodo(recorte.mes ? sdrAiIntervaloMes(recorte.mes, selAno) : sdrAiPeriodoTodo(selAno));
    setEstado(['contactados', 'qualificados', 'nao_qualificados', 'chamadas', 'whatsapp', 'sem_contacto', 'elegiveis', 'nurturing', 'nurturing_contactos', 'nurturing_demos', 'nurturing_ganhas'].includes(recorte.metrica) ? recorte.metrica : 'all');
  }, [recorte, selAno]);

  React.useEffect(() => {
    if (!foco) return;
    setSource(foco.source || 'all');
    setPeriodo(foco.mes ? sdrAiIntervaloMes(foco.mes, selAno) : sdrAiPeriodoTodo(selAno));
  }, [foco]);

  const aceita = (lead, skip) => {
    if (skip !== 'marca' && marca !== 'Todas' && lead.marca !== marca) return false;
    if (skip !== 'source' && source !== 'all' && lead.source !== source) return false;
    if (skip !== 'action' && action !== 'all' && sdrAiActionId(lead) !== action) return false;
    if (skip !== 'origem' && origem !== 'all' && sdrAiOrigemChave(lead) !== origem) return false;
    if (skip !== 'estado' && !sdrAiEstadoOk(lead, estado)) return false;
    if (skip !== 'oport' && !sdrAiOportOk(lead, oport)) return false;
    if (skip !== 'pais' && pais !== 'all' && sdrAiMercado(lead) !== pais) return false;
    if (skip !== 'periodo' && !sdrAiNoPeriodoFiltro(lead, periodo, selAno)) return false;
    return true;
  };
  const contar = (skip, pred) => leads.reduce((n, lead) => n + (aceita(lead, skip) && pred(lead) ? 1 : 0), 0);

  const opcoesMarca = [{ value: 'Todas', label: 'Todas', n: contar('marca', () => true) }].concat(
    SDR_AI_ORDEM_MARCAS
      .map(nome => ({ value: nome, label: nome, n: contar('marca', l => l.marca === nome) }))
      .filter(o => o.n > 0)
  );
  const opcoesSource = [{ value: 'all', label: 'Todas', n: contar('source', () => true) }].concat(
    SDR_AI_SOURCES.map(s => ({ value: s.id, label: s.label, n: contar('source', l => l.source === s.id) }))
  );
  const opcoesAction = [{ value: 'all', label: 'Todas', n: contar('action', () => true) }].concat(
    SDR_AI_ACTIONS
      .filter(a => source === 'all' || a.source === source)
      .map(a => ({
        value: a.id,
        label: a.id,
        grupo: source === 'all' ? a.source : undefined,
        n: contar('action', l => sdrAiActionId(l) === a.id),
      }))
  );
  const origemMap = new Map();
  leads.forEach(lead => {
    if (!aceita(lead, 'origem')) return;
    const nome = sdrAiOrigemChave(lead);
    if (!nome || nome === '—') return;
    const prev = origemMap.get(nome) || { n: 0, grupo: sdrAiGrupoOrigem(lead) };
    prev.n += 1;
    origemMap.set(nome, prev);
  });
  const ordemGrupo = { Campanhas: 0, Formulários: 1, Newsletters: 2 };
  const opcoesOrigem = [{ value: 'all', label: 'Todas', n: contar('origem', () => true) }].concat(
    [...origemMap.entries()]
      .sort((a, b) => (source === 'all' ? (ordemGrupo[a[1].grupo] - ordemGrupo[b[1].grupo]) : 0) || b[1].n - a[1].n || a[0].localeCompare(b[0], 'pt'))
      .map(([nome, info]) => ({ value: nome, label: nome, n: info.n, grupo: source === 'all' ? info.grupo : undefined }))
  );
  const etiquetaOrigem = source === 'WEB' ? 'Formulário' : source === 'ADS' ? 'Campanha' : 'Origem';
  const opcoesEstado = (modo === 'nurturing' ? [
    ['all', 'Oportunidades', () => true],
    ['nurturing', 'Em nurturing', l => sdrAiTemOportunidade(l) && !sdrAiGanha(l)],
    ['nurturing_ganhas', 'Ganhas', sdrAiGanha],
    ['nurturing_contactos', 'Contactos feitos', () => false],
    ['nurturing_demos', 'Demos ou visitas', () => false],
  ] : [
    ['all', 'Leads Atribuídos', () => true],
    ['elegiveis', 'Elegíveis', sdrAiElegivel],
    ['contactados', 'Leads Contactados', l => !!l.respondeu || sdrAiContactoDigi(l)],
    ['qualificados', 'Qualificados BANT', sdrAiQualificadaBant],
    ['nao_qualificados', 'Não Qualificados BANT', l => !!l.recusa],
    ['chamadas', 'Chamadas', l => !!l.circuito?.chamada],
    ['whatsapp', 'WhatsApp após falha', l => l.circuito?.wa_estado === 'enviado'],
    ['sem_contacto', 'Sem contacto', l => l.circuito?.fase === 'sem_contacto'],
  ]).map(([value, label, pred]) => ({ value, label, n: contar('estado', pred) }));
  const opcoesOport = [{ value: 'all', label: 'Todas', n: contar('oport', () => true) }]
    .concat(SDR_AI_STAGES.map(st => ({ value: st, label: st, n: contar('oport', l => l.stage === st) })))
    .concat([{ value: 'sem', label: 'Sem oportunidade', n: contar('oport', l => !l.stage && !l.oportunidade) }]);
  const opcoesPais = [
    ['all', 'Todos', () => true],
    ['PT', 'Portugal', l => sdrAiMercado(l) === 'PT'],
    ['ES', 'Espanha', l => sdrAiMercado(l) === 'ES'],
    ['OUTRO', 'Outros', l => sdrAiMercado(l) === 'OUTRO'],
  ].map(([value, label, pred]) => ({ value, label, n: contar('pais', pred) }));
  const mudarOrdem = (key) => {
    setOrdem(key);
    setOrdemDir(sdrAiDirInicial(key));
  };

  React.useEffect(() => {
    if (action !== 'all' && source !== 'all' && !SDR_AI_ACTIONS.some(a => a.id === action && a.source === source)) setAction('all');
  }, [action, source]);

  React.useEffect(() => {
    if (origem === 'all') return;
    const existe = leads.some(l => (marca === 'Todas' || l.marca === marca) && (source === 'all' || l.source === source) && (action === 'all' || sdrAiActionId(l) === action) && sdrAiOrigemChave(l) === origem);
    if (!existe) setOrigem('all');
  }, [origem, marca, source, action, leads]);

  const jaPassadoDe = (lead) => passados[lead.id] || (lead.passado ? { nome: lead.passado_sdr || '' } : null);
  const filtered = sdrAiOrdenar(leads.filter(lead => aceita(lead)).map(lead => {
    const p = jaPassadoDe(lead);
    return p ? { ...lead, passado: true, passado_sdr: p.nome || lead.passado_sdr } : lead;
  }), ordem, selAno, ordemDir, modo);
  const colBox = (id) => ({ flex: `0 0 ${larguras[id]}px`, width: larguras[id], minWidth: 0, maxWidth: larguras[id], overflow: 'hidden' });
  const clicarColuna = (id) => {
    if (arrastou.current) { arrastou.current = false; return; }
    if (ordem !== id) { mudarOrdem(id); return; }
    const inicial = sdrAiDirInicial(id);
    if (ordemDir === inicial) setOrdemDir(inicial === 'asc' ? 'desc' : 'asc');
    else { setOrdem('recentes'); setOrdemDir('desc'); }
  };
  const iniciarArrasto = (id, e) => {
    e.preventDefault();
    e.stopPropagation();
    const inicioX = e.clientX;
    const inicioW = larguras[id];
    arrastou.current = false;
    const mover = (ev) => {
      const dx = ev.clientX - inicioX;
      if (Math.abs(dx) > 2) arrastou.current = true;
      const n = Math.max(56, Math.min(640, inicioW + dx));
      setLarguras(prev => ({ ...prev, [id]: n }));
    };
    const soltar = () => {
      window.removeEventListener('mousemove', mover);
      window.removeEventListener('mouseup', soltar);
      document.body.style.cursor = '';
      document.body.style.userSelect = '';
      setLarguras(prev => {
        try { localStorage.setItem('sdr-ai-lista-larguras', JSON.stringify(prev)); } catch { /* sem gravar */ }
        return prev;
      });
    };
    document.body.style.cursor = 'col-resize';
    document.body.style.userSelect = 'none';
    window.addEventListener('mousemove', mover);
    window.addEventListener('mouseup', soltar);
  };
  const seleccionadas = filtered.filter(lead => sel[lead.id]);
  const allSelected = filtered.length > 0 && seleccionadas.length === filtered.length;

  const toggleSel = (id) => { setResumoPassar(''); setConfirmarApagar(false); setSel(prev => ({ ...prev, [id]: !prev[id] })); };
  const toggleAll = () => {
    setResumoPassar('');
    setConfirmarApagar(false);
    if (allSelected) setSel({});
    else {
      const next = {};
      filtered.forEach(lead => { next[lead.id] = true; });
      setSel(next);
    }
  };

  const aplicarLista = async (accao) => {
    if (!seleccionadas.length) return;
    if (accao === 'apagar' && !confirmarApagar) { setConfirmarApagar(true); return; }
    setAPassar(true);
    setResumoPassar('');
    const ids = seleccionadas.map(lead => lead.id);
    const r = await fetch('/api/comercial/sdr/ai/lista', {
      method: 'POST', credentials: 'include',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ contacto_ids: ids, accao }),
    }).then(res => res.ok ? res.json() : null).catch(() => null);
    setAPassar(false);
    setConfirmarApagar(false);
    if (!r?.ok) { setResumoPassar('Não ficou gravado.'); return; }
    onLista?.(ids, accao);
    setSel({});
    const n = r.n || ids.length;
    setResumoPassar(accao === 'apagar'
      ? `${n} apagada${n === 1 ? '' : 's'} desta lista.`
      : accao === 'arquivar'
        ? `${n} arquivada${n === 1 ? '' : 's'}.`
        : `${n} reposta${n === 1 ? '' : 's'} na lista.`);
  };

  const passarLote = async () => {
    if (!sdrLote || !seleccionadas.length) return;
    setAPassar(true);
    setResumoPassar('');
    const paraPassar = seleccionadas.filter(lead => sdrAiTemTelefone(lead) && !jaPassadoDe(lead));
    const deFora = seleccionadas.length - paraPassar.length;
    if (!paraPassar.length) {
      setAPassar(false);
      setResumoPassar('Nenhuma das seleccionadas pode ser passada. Falta telefone ou já foi passada.');
      return;
    }
    let ok = 0;
    let falha = 0;
    let nome = sdrList.find(s => s.email === sdrLote)?.nome || '';
    for (const lead of paraPassar) {
      const r = await fetch('/api/comercial/sdr/ai/passar', {
        method: 'POST', credentials: 'include',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ contacto_id: lead.id, sdr_email: sdrLote, ano: selAno }),
      }).then(res => res.ok ? res.json() : null).catch(() => null);
      if (r?.ok) {
        ok += 1;
        nome = r.sdr_nome || nome;
        onPassou?.(lead.id, { nome: r.sdr_nome || nome });
      } else falha += 1;
    }
    setAPassar(false);
    setSel({});
    const nOk = `${ok} passada${ok === 1 ? '' : 's'}`;
    const foraTxt = deFora ? `, ${deFora} de fora` : '';
    setResumoPassar(falha === 0
      ? `${nOk} a ${nome}${foraTxt}.`
      : `${nOk}, ${falha} não ${falha === 1 ? 'passou' : 'passaram'}${foraTxt}.`);
  };

  const head = { fontSize: 10, color: 'var(--dgd-fg-3)', fontFamily: 'var(--dgd-font-mono,monospace)', letterSpacing: '0.06em', textTransform: 'uppercase' };
  const cell = { whiteSpace: 'pre-wrap', wordBreak: 'break-word', lineHeight: 1.35 };

  return (
    <div style={{ marginTop: 20 }}>
      <div style={{ position: 'sticky', top: 0, zIndex: 4, background: 'var(--dgd-bg-app,#f8fafc)', paddingTop: 16 }}>
      <div style={{ background: 'var(--dgd-bg-card,white)', border: '1px solid var(--dgd-border-1)', borderBottom: 'none', borderRadius: '8px 8px 0 0' }}>
      <div style={{ display: 'flex', gap: 2, padding: '0 8px', borderBottom: '1px solid var(--dgd-border-1)' }}>
        {[['qualificacao', 'Qualificação', nQual], ['nurturing', 'Nurturing', nNurt]].map(([id, label, n]) => (
          <button key={id} type="button" onClick={() => onModo?.(id)}
            style={{ padding: '10px 14px', border: 'none', borderBottom: modo === id ? '2px solid #112954' : '2px solid transparent', marginBottom: -1, background: 'transparent', cursor: 'pointer', fontFamily: 'inherit', fontSize: 13, fontWeight: modo === id ? 700 : 500, color: modo === id ? '#112954' : 'var(--dgd-fg-2)' }}>
            {label} <span style={{ marginLeft: 4, fontSize: 11, fontWeight: 700, opacity: 0.7 }}>{n}</span>
          </button>
        ))}
      </div>
      <div style={{ padding: '12px 14px', borderBottom: '1px solid var(--dgd-border-1)', display: 'flex', gap: 8, alignItems: 'center' }}>
        <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', alignItems: 'center', flex: 1, minWidth: 0 }}>
        <SdrAIFiltro label="Marca" value={marca} marcado={marca !== 'Todas'} onChange={setMarca} options={opcoesMarca} />
        <SdrAIFiltro label="Source" value={source} marcado={source !== 'all'} onChange={setSource} options={opcoesSource} menuMinWidth={200} />
        <SdrAIFiltro label="Action" value={action} marcado={action !== 'all'} onChange={setAction} options={opcoesAction} menuMinWidth={260} menuMaxHeight={360} />
        <SdrAIFiltro label={etiquetaOrigem} value={origem} marcado={origem !== 'all'} onChange={setOrigem} options={opcoesOrigem} menuMinWidth={280} />
        <SdrAIFiltro label="Estado" value={estado} marcado={estado !== 'all'} onChange={setEstado} options={opcoesEstado} menuMinWidth={230} />
        <SdrAIFiltro label="Oport." value={oport} marcado={oport !== 'all'} onChange={setOport} options={opcoesOport} menuMinWidth={240} />
        <SdrAIFiltro label="País" value={pais} marcado={pais !== 'all'} onChange={setPais} options={opcoesPais} menuMinWidth={180} />
        <SdrAIPeriodo value={periodo} onChange={setPeriodo} ano={selAno} />
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginLeft: 'auto', flexShrink: 0 }}>
          <button type="button" aria-label="Procurar" onClick={() => { setBusca(true); setMenuAberto(false); }}
            style={{ width: 30, height: 30, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', border: '1px solid #dde3ef', borderRadius: 6, background: '#fff', color: '#112954', cursor: 'pointer', padding: 0 }}>
            <svg width="15" height="15" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"><circle cx="7" cy="7" r="4.25" /><path d="M10.5 10.5L13.5 13.5" /></svg>
          </button>
          <div ref={menuRef} style={{ position: 'relative' }}>
            <button type="button" aria-label="Menu" onClick={() => setMenuAberto(v => !v)}
              style={{ width: 30, height: 30, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', border: `1px solid ${menuAberto ? '#4338ca' : '#dde3ef'}`, borderRadius: 6, background: menuAberto ? '#eef2ff' : '#fff', color: menuAberto ? '#4338ca' : '#112954', cursor: 'pointer', padding: 0 }}>
              <svg width="15" height="15" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"><path d="M2.5 4h11M2.5 8h11M2.5 12h11" /></svg>
            </button>
            {menuAberto && (
              <div style={{ position: 'absolute', top: 'calc(100% + 6px)', right: 0, zIndex: 30, background: '#fff', border: '1px solid #dde3ef', borderRadius: 8, boxShadow: '0 12px 32px rgba(17,41,84,0.14)', minWidth: 220, padding: 4 }}>
                <button type="button" onClick={() => { setVerArquivo(v => !v); setSel({}); setConfirmarApagar(false); setResumoPassar(''); setMenuAberto(false); }}
                  style={{ display: 'flex', width: '100%', textAlign: 'left', gap: 8, alignItems: 'center', border: 'none', background: 'transparent', borderRadius: 6, padding: '8px 10px', cursor: 'pointer', fontFamily: 'inherit', color: '#112954' }}>
                  <span style={{ flex: 1 }}>
                    <span style={{ display: 'block', fontSize: 13, fontWeight: 650 }}>{verArquivo ? 'Lista activa' : 'Arquivo'}</span>
                    <span style={{ display: 'block', fontSize: 11, color: 'var(--dgd-fg-3)', fontWeight: 400, marginTop: 1 }}>{verArquivo ? 'Voltar às leads activas' : 'Leads arquivadas'}</span>
                  </span>
                  {verArquivo && <span style={{ color: '#4338ca' }}>✓</span>}
                </button>
              </div>
            )}
          </div>
        </div>
      </div>
      {(seleccionadas.length > 0 || resumoPassar) && (
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, flexWrap: 'wrap', padding: '8px 12px', borderBottom: '1px solid color-mix(in srgb, #3859D0 18%, #dde3ef)', background: 'color-mix(in srgb, #3859D0 6%, white)' }}>
          {seleccionadas.length > 0 && (
            <>
              <div style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 0 }}>
                <span style={{ fontSize: 12, fontWeight: 700, color: '#3859D0', fontFamily: 'var(--dgd-font-mono,monospace)', letterSpacing: '0.02em' }}>{seleccionadas.length} seleccionada{seleccionadas.length === 1 ? '' : 's'}</span>
                <span style={{ width: 1, height: 16, background: '#dde3ef' }} />
                {confirmarApagar ? (
                  <>
                    <span style={{ fontSize: 12, color: '#991b1b' }}>Apagar desta lista?</span>
                    <button onClick={() => aplicarLista('apagar')} disabled={aPassar}
                      style={{ height: 28, padding: '0 12px', borderRadius: 6, border: 'none', background: '#dc2626', color: '#fff', fontSize: 12, fontWeight: 600, cursor: aPassar ? 'default' : 'pointer', fontFamily: 'inherit' }}>
                      Confirmar
                    </button>
                    <button onClick={() => setConfirmarApagar(false)} disabled={aPassar}
                      style={{ height: 28, padding: '0 10px', borderRadius: 6, border: 'none', background: 'transparent', color: '#64748b', fontSize: 12, cursor: 'pointer', fontFamily: 'inherit' }}>
                      Cancelar
                    </button>
                  </>
                ) : (
                  <>
                    <button onClick={() => aplicarLista(verArquivo ? 'repor' : 'arquivar')} disabled={aPassar}
                      style={{ height: 28, padding: '0 10px', borderRadius: 6, border: '1px solid #dde3ef', background: '#fff', color: '#112954', fontSize: 12, cursor: aPassar ? 'default' : 'pointer', fontFamily: 'inherit' }}>
                      {verArquivo ? 'Repor' : 'Arquivar'}
                    </button>
                    <button onClick={() => aplicarLista('apagar')} disabled={aPassar}
                      style={{ height: 28, padding: '0 10px', borderRadius: 6, border: '1px solid #fecaca', background: '#fff', color: '#dc2626', fontSize: 12, cursor: aPassar ? 'default' : 'pointer', fontFamily: 'inherit' }}>
                      Apagar
                    </button>
                  </>
                )}
              </div>
              <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                <div style={{ display: 'flex', alignItems: 'stretch', height: 28, border: '1px solid #dde3ef', borderRadius: 6, overflow: 'hidden', background: '#fff' }}>
                  <select value={sdrLote} onChange={e => setSdrLote(e.target.value)} disabled={aPassar}
                    style={{ border: 'none', outline: 'none', background: '#fff', color: sdrLote ? '#112954' : '#64748b', fontSize: 12, padding: '0 8px', minWidth: 148, fontFamily: 'inherit' }}>
                    <option value="">Escolher SDR</option>
                    {sdrList.map(s => <option key={s.email} value={s.email}>{s.nome}</option>)}
                  </select>
                  <button onClick={passarLote} disabled={!sdrLote || aPassar}
                    style={{ border: 'none', borderLeft: '1px solid #dde3ef', padding: '0 12px', background: sdrLote && !aPassar ? '#166534' : '#f1f5f9', color: sdrLote && !aPassar ? '#fff' : '#94a3b8', fontSize: 12, fontWeight: 600, cursor: sdrLote && !aPassar ? 'pointer' : 'default', fontFamily: 'inherit' }}>
                    {aPassar ? 'A tratar...' : 'Passar'}
                  </button>
                </div>
                <button onClick={() => { setSel({}); setConfirmarApagar(false); }}
                  style={{ height: 28, padding: '0 8px', border: 'none', background: 'transparent', color: '#64748b', fontSize: 12, cursor: 'pointer', fontFamily: 'inherit' }}>
                  Limpar
                </button>
              </div>
            </>
          )}
          {resumoPassar && <span style={{ fontSize: 12, color: '#475569' }}>{resumoPassar}</span>}
        </div>
      )}
      <div ref={headScrollRef} style={{ overflow: 'hidden', background: 'var(--dgd-bg-card,white)', borderBottom: '1px solid var(--dgd-border-1)' }}>
        <div style={{ display: 'flex', alignItems: 'flex-start', gap: 12, padding: '8px 14px', minWidth: 'max-content' }}>
          <div style={{ flex: '0 0 28px', display: 'flex', justifyContent: 'center' }}>
            <input type="checkbox" checked={allSelected} disabled={filtered.length === 0}
              ref={el => { if (el) el.indeterminate = seleccionadas.length > 0 && !allSelected; }}
              onChange={toggleAll}
              style={{ width: 14, height: 14, cursor: filtered.length ? 'pointer' : 'default', accentColor: '#3859D0' }} />
          </div>
          {(modo === 'nurturing' ? SDR_AI_COLUNAS_NURTURING : SDR_AI_COLUNAS).map(col => (
            <div key={col.id} onClick={() => clicarColuna(col.id)}
              style={{ ...head, ...colBox(col.id), position: 'relative', overflow: 'visible', cursor: 'pointer', userSelect: 'none' }}>
              <span style={{ display: 'block', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{col.label}{ordem === col.id ? (ordemDir === 'asc' ? ' ↑' : ' ↓') : ''}</span>
              <span
                onMouseDown={e => iniciarArrasto(col.id, e)}
                onClick={e => e.stopPropagation()}
                title="Arrastar para ajustar a largura"
                style={{ position: 'absolute', top: -8, right: -8, width: 10, bottom: -8, cursor: 'col-resize' }} />
            </div>
          ))}
        </div>
      </div>
      </div>
      </div>
      <div ref={bodyScrollRef} onScroll={() => { if (headScrollRef.current && bodyScrollRef.current) headScrollRef.current.scrollLeft = bodyScrollRef.current.scrollLeft; }} style={{ overflowX: 'auto', background: 'var(--dgd-bg-card,white)', border: '1px solid var(--dgd-border-1)', borderTop: 'none', borderRadius: '0 0 8px 8px' }}>
      {filtered.length === 0 ? (
        <div style={{ padding: 32, textAlign: 'center', color: 'var(--dgd-fg-3)', fontSize: 13 }}>
          {verArquivo
            ? (modo === 'nurturing' ? 'Sem oportunidades arquivadas.' : 'Sem leads arquivadas.')
            : modo === 'nurturing' && leads.length === 0
              ? 'Sem oportunidades em nurturing. Entram quando a lead aceita a demo ou a visita.'
              : modo === 'nurturing'
                ? 'Sem oportunidades para este filtro.'
                : 'Sem leads para os filtros seleccionados.'}
        </div>
      ) : filtered.map(lead => {
        const passadoInfo = jaPassadoDe(lead);
        const jaPassado = !!passadoInfo;
        const estadoLead = sdrAiEstadoConsulta({ ...lead, passado: jaPassado });
        const origemTxt = lead.source === 'NEWSLETTER' && lead.assunto ? lead.assunto : sdrAiOrigem(lead);
        const canalTxt = sdrAiOrigemCanal(lead);
        const ganha = lead.op_status === 'WON' || lead.oportunidade === 'Ganha';
        const oportTxt = lead.stage || (ganha ? 'Ganha' : lead.oportunidade) || '';
        const valorTxt = sdrAiEuros(lead.valor);
        return (
          <div key={lead.id} onClick={() => onAbrir && onAbrir(lead, filtered)}
            style={{ display: 'flex', alignItems: 'flex-start', gap: 12, padding: '10px 14px', borderBottom: '1px solid var(--dgd-border-1)', cursor: 'pointer', background: 'transparent', minWidth: 'max-content' }}
            onMouseEnter={e => { e.currentTarget.style.background = 'var(--dgd-bg-app,#f8fafc)'; }}
            onMouseLeave={e => { e.currentTarget.style.background = 'transparent'; }}>
            <div style={{ flex: '0 0 28px', display: 'flex', justifyContent: 'center', paddingTop: 2 }} onClick={e => e.stopPropagation()}>
              <input type="checkbox" checked={!!sel[lead.id]}
                onChange={() => toggleSel(lead.id)}
                style={{ width: 14, height: 14, cursor: 'pointer', accentColor: '#3859D0' }} />
            </div>
            {modo === 'nurturing' ? (
              <>
                <SdrAICelula texto={lead.empresa} style={{ ...cell, ...colBox('empresa'), fontSize: 12.5, fontWeight: 600, color: 'var(--dgd-fg-1)' }} />
                <SdrAICelula texto={sdrAiNomeLista(lead)} style={{ ...cell, ...colBox('contacto'), fontSize: 12, color: 'var(--dgd-fg-2)' }} />
                <SdrAICelula texto={lead.oportunidade || '—'} style={{ ...cell, ...colBox('oportunidade'), fontSize: 12, fontWeight: 600, color: 'var(--dgd-fg-1)' }} />
                <SdrAICelula texto={lead.stage || '—'} style={{ ...cell, ...colBox('stage'), fontSize: 12, color: lead.stage ? '#92400e' : 'var(--dgd-fg-3)' }} />
                <SdrAICelula texto="—" style={{ ...cell, ...colBox('proximo'), fontSize: 12, color: 'var(--dgd-fg-3)' }} />
                <SdrAICelula texto={sdrAiEstadoNurturing(lead).label} style={{ ...cell, ...colBox('estado'), fontSize: 12, fontWeight: 600, color: sdrAiEstadoNurturing(lead).cor }} />
                <SdrAICelula texto={sdrAiEuros(lead.valor)} style={{ ...cell, ...colBox('valor'), fontSize: 12, color: 'var(--dgd-fg-1)', fontFamily: 'var(--dgd-font-mono,monospace)' }} />
              </>
            ) : (
              <>
            <SdrAICelula texto={sdrAiNomeLista(lead)} style={{ ...cell, ...colBox('nome'), fontSize: 12.5, fontWeight: 600, color: 'var(--dgd-fg-1)' }} />
            <SdrAICelula texto={lead.empresa} style={{ ...cell, ...colBox('empresa'), fontSize: 12, color: 'var(--dgd-fg-2)' }} />
            <SdrAICelula texto={lead.email} style={{ ...cell, ...colBox('email'), fontSize: 12, color: 'var(--dgd-fg-1)' }} />
            {sdrAiTemTelefone(lead)
              ? <SdrAICelula texto={lead.telefone} style={{ ...cell, ...colBox('telefone'), fontSize: 12, color: 'var(--dgd-fg-1)' }} />
              : <SdrAICelula texto="Sem telefone" title={lead.telefone || ''} style={{ ...cell, ...colBox('telefone'), fontSize: 12, color: 'var(--dgd-fg-3)' }} />}
            <div style={colBox('origem')}>
              <SdrAICelula texto={origemTxt} style={{ ...cell, fontSize: 12, fontWeight: 600, color: 'var(--dgd-fg-1)' }} />
              {canalTxt && <div title={lead.source === 'WEB' ? (lead.page_url || canalTxt) : canalTxt} style={{ ...cell, fontSize: 11, color: 'var(--dgd-fg-3)', marginTop: 2 }}>{canalTxt}</div>}
            </div>
            <div style={colBox('estado')}>
              <SdrAICelula texto={estadoLead.label} style={{ ...cell, fontSize: 12, fontWeight: 600, color: estadoLead.cor }} />
              {jaPassado && passadoInfo.nome && <div style={{ ...cell, fontSize: 11, color: '#166534', marginTop: 2 }}>{passadoInfo.nome}</div>}
            </div>
            <div style={colBox('bant')}><SdrAIBantLetras lead={lead} /></div>
            <div style={colBox('oportunidade')}>
              <SdrAICelula texto={oportTxt} title={ganha ? 'Ganha' : (lead.oportunidade || oportTxt)} style={{ ...cell, fontSize: 12, fontWeight: 600, color: ganha ? '#166534' : oportTxt ? '#92400e' : 'var(--dgd-fg-3)' }} />
              {valorTxt !== '—' && <div style={{ ...cell, fontSize: 11, color: 'var(--dgd-fg-3)', marginTop: 2, fontFamily: 'var(--dgd-font-mono,monospace)' }}>{valorTxt}</div>}
            </div>
              </>
            )}
          </div>
        );
      })}
      <div style={{ padding: '8px 14px', borderTop: '1px solid var(--dgd-border-1)', fontSize: 11, color: 'var(--dgd-fg-3)' }}>
        {filtered.length} {modo === 'nurturing' ? `oportunidade${filtered.length === 1 ? '' : 's'}` : `lead${filtered.length === 1 ? '' : 's'}`}
      </div>
      </div>
      {busca && <SdrAIBusca leads={leadsTodas.filter(l => !l.apagada)} onClose={() => setBusca(false)} onAbrir={(lead) => { setBusca(false); onAbrir?.(lead, [lead]); }} />}
    </div>
  );
};

const SdrAIBusca = ({ leads, onClose, onAbrir }) => {
  const [q, setQ] = React.useState('');
  const [foco, setFoco] = React.useState(0);
  const campo = React.useRef(null);
  React.useEffect(() => { campo.current?.focus(); }, []);
  React.useEffect(() => {
    const onKey = (e) => { if (e.key === 'Escape') onClose?.(); };
    document.addEventListener('keydown', onKey);
    return () => document.removeEventListener('keydown', onKey);
  }, [onClose]);
  const termo = q.trim().toLowerCase();
  const rows = termo.length < 2 ? [] : leads.filter(lead => {
    const blob = [sdrAiNomeLista(lead), lead.empresa, lead.email, lead.telefone, lead.pais].filter(Boolean).join(' ').toLowerCase();
    return blob.includes(termo);
  }).slice(0, 8);
  const mercado = (lead) => ({ PT: 'Portugal', ES: 'Espanha', OUTRO: 'Outro' }[sdrAiMercado(lead)] || '');
  const abrir = (lead) => { if (lead) onAbrir?.(lead); };
  const onKeyDown = (e) => {
    if (e.key === 'ArrowDown') { e.preventDefault(); setFoco(i => Math.min(Math.max(rows.length - 1, 0), i + 1)); }
    if (e.key === 'ArrowUp') { e.preventDefault(); setFoco(i => Math.max(0, i - 1)); }
    if (e.key === 'Enter') { e.preventDefault(); abrir(rows[foco]); }
  };
  return (
    <div role="dialog" aria-label="Procurar leads" onMouseDown={onClose} style={{ position: 'fixed', inset: 0, zIndex: 3000, background: 'rgba(0,0,0,.78)', display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 24 }}>
      <button type="button" aria-label="Fechar" onMouseDown={e => e.stopPropagation()} onClick={onClose} style={{ position: 'absolute', top: 18, right: 22, width: 36, height: 36, border: 'none', background: 'transparent', color: '#fff', fontSize: 26, lineHeight: 1, cursor: 'pointer' }}>×</button>
      <div onMouseDown={e => e.stopPropagation()} style={{ width: 'min(920px, 100%)' }}>
        <style>{'.sdr-ai-procurar::placeholder{color:rgba(255,255,255,.65)}'}</style>
        <div style={{ display: 'flex', alignItems: 'center', gap: 16, borderBottom: '1px solid rgba(255,255,255,.85)', paddingBottom: 8 }}>
          <input ref={campo} className="sdr-ai-procurar" value={q} onChange={e => { setQ(e.target.value); setFoco(0); }} onKeyDown={onKeyDown} placeholder="Procurar" aria-label="Procurar"
            style={{ flex: 1, height: 48, border: 'none', outline: 'none', background: 'transparent', color: '#fff', fontSize: 22, fontFamily: 'inherit' }} />
          <svg width="22" height="22" viewBox="0 0 16 16" fill="none" stroke="#fff" strokeWidth="1.6" strokeLinecap="round"><circle cx="7" cy="7" r="4.25" /><path d="M10.5 10.5L13.5 13.5" /></svg>
        </div>
        {termo.length >= 2 && (
          <div style={{ marginTop: 8 }}>
            {!rows.length && <div style={{ padding: '12px 4px', fontSize: 14, color: 'rgba(255,255,255,.75)' }}>Nenhuma lead.</div>}
            {rows.map((lead, i) => (
              <button key={lead.id} type="button" onMouseEnter={() => setFoco(i)} onClick={() => abrir(lead)}
                style={{ display: 'flex', width: '100%', textAlign: 'left', gap: 12, alignItems: 'baseline', background: i === foco ? 'rgba(255,255,255,.14)' : 'transparent', border: 'none', borderRadius: 6, padding: '10px 8px', cursor: 'pointer', fontFamily: 'inherit', color: '#fff' }}>
                <span style={{ fontSize: 16, fontWeight: 600 }}>{sdrAiNomeLista(lead)}</span>
                <span style={{ fontSize: 13, color: 'rgba(255,255,255,.72)' }}>{[lead.empresa, lead.email, mercado(lead)].filter(v => v && v !== '—').join(' · ')}</span>
              </button>
            ))}
          </div>
        )}
      </div>
    </div>
  );
};

// ─── Entry point — exportado para window ──────────────────────────────────────

function sdrAiFunilDe(leads) {
  return SDR_AI_MESES.map(mes => {
    const rows = leads.filter(l => l.mes === mes);
    const contactados = rows.filter(l => l.respondeu || l.status !== 'atribuido');
    return {
      mes,
      atribuidos: rows.length,
      contactados: contactados.length,
      qualificados: rows.filter(l => (l.bant_n || 0) >= 4).length,
      em_qualificacao: rows.filter(l => l.status === 'em_qualificacao').length,
      nao_qualificados: rows.filter(l => l.status === 'nao_qualificado').length,
    };
  });
}

function sdrAiFunilDaLista(leads) {
  return SDR_AI_MESES.map(mes => {
    const rows = leads.filter(l => l.mes === mes);
    const elegiveis = rows.filter(sdrAiElegivel);
    return {
      mes,
      atribuidos: rows.length,
      contactados: rows.filter(l => l.respondeu || sdrAiContactoDigi(l)).length,
      qualificados: rows.filter(sdrAiQualificadaBant).length,
      nao_qualificados: rows.filter(l => l.recusa || (l.circuito?.fase === 'atendeu' && !sdrAiQualificadaBant(l))).length,
      chamadas: rows.filter(l => l.circuito?.chamada).length,
      whatsapp: rows.filter(l => l.circuito?.wa_estado === 'enviado').length,
      sem_contacto: rows.filter(l => l.circuito?.fase === 'sem_contacto').length,
      elegiveis: elegiveis.length,
      na_chamada: rows.filter(sdrAiFicouNaChamada).length,
      contactos_digi: rows.filter(sdrAiContactoDigi).length,
      nurturing: rows.filter(l => sdrAiTemOportunidade(l) && !sdrAiGanha(l)).length,
      nurturing_contactos: 0,
      nurturing_demos: 0,
      nurturing_ganhas: rows.filter(sdrAiGanha).length,
    };
  });
}

const SDR_AI_CARDS_ACTIVOS = false;

function sdrAiCards(leads) {
  if (!SDR_AI_CARDS_ACTIVOS) {
    return [
      { l:'Taxa de Contacto', v:'0%', d:'Obj. >= 70%', c: aiSdrColor(0, 70) },
      { l:'Qualificação BANT', v:'0%', d:'Obj. >= 40%', c: aiSdrColor(0, 40) },
      { l:'Oportunidades Passadas', v:0, d:'0 desde Set · 0 demos', c:'var(--dgd-fg-1)' },
      { l:'Taxa qualif. comercial', v:'0%', d:'Obj. >= 40%', c: aiSdrColor(0, 40) },
      { l:'Pipeline Gerado', v:'0k', d:'0k desde Set', c:'#1d4ed8' },
    ];
  }
  const mes = SDR_AI_MESES[new Date().getMonth()];
  const agora = leads.filter(l => l.mes === mes);
  const conta = (rows) => ({
    a: rows.length,
    c: rows.filter(l => l.respondeu).length,
    q: rows.filter(l => (l.bant_n || 0) >= 4).length,
    p: rows.filter(l => l.passado).length,
  });
  const m = conta(agora);
  const y = conta(leads);
  const tc = aiSdrPct(m.c, m.a) ?? 0;
  const tq = aiSdrPct(m.q, m.c) ?? 0;
  const tqc = aiSdrPct(m.p, m.q) ?? 0;
  return [
    { l:'Taxa de Contacto', v:`${tc}%`, d:'Obj. >= 70%', c: aiSdrColor(tc, 70) },
    { l:'Qualificação BANT', v:`${tq}%`, d:'Obj. >= 40%', c: aiSdrColor(tq, 40) },
    { l:'Oportunidades Passadas', v: m.p, d:`${y.p} desde Set · 0 demos`, c:'var(--dgd-fg-1)' },
    { l:'Taxa qualif. comercial', v:`${tqc}%`, d:'Obj. >= 40%', c: aiSdrColor(tqc, 40) },
    { l:'Pipeline Gerado', v:'0k', d:'0k desde Set', c:'#1d4ed8' },
  ];
}

const SDR_AI_DIAS = ['Domingo', 'Segunda', 'Terça', 'Quarta', 'Quinta', 'Sexta', 'Sábado'];

function sdrAiDiaUtilAnterior(hoje = new Date()) {
  const d = new Date(hoje.getFullYear(), hoje.getMonth(), hoje.getDate());
  d.setDate(d.getDate() - 1);
  while (d.getDay() === 0 || d.getDay() === 6) d.setDate(d.getDate() - 1);
  return d;
}

function sdrAiIso(d) {
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
}

function sdrAiJuntar(items) {
  if (items.length <= 1) return items[0] || '';
  return `${items.slice(0, -1).join(', ')} e ${items[items.length - 1]}`;
}

function sdrAiResumoTexto(leads, ano) {
  const dia = sdrAiDiaUtilAnterior();
  const nome = SDR_AI_DIAS[dia.getDay()];
  const doDia = leads.filter(l => {
    const d = sdrAiDataLead(l, ano);
    return d && d.getFullYear() === dia.getFullYear() && d.getMonth() === dia.getMonth() && d.getDate() === dia.getDate();
  });
  const n = doDia.length;
  const partes = ['ADS', 'WEB', 'NEWSLETTER'].map(s => ({ s, n: doDia.filter(l => l.source === s).length })).filter(p => p.n > 0);
  const detalhe = partes.length === 0 ? ''
    : partes.length === 1 ? (n === 1 ? `, de ${partes[0].s}` : ` de ${partes[0].s}`)
    : `, ${sdrAiJuntar(partes.map(p => `${p.n} ${p.s}`))}`;
  const entrada = n === 0 ? `${nome} não entrou nenhuma lead.` : n === 1 ? `${nome} entrou 1 lead${detalhe}.` : `${nome} entraram ${n} leads${detalhe}.`;
  if (!SDR_AI_CARDS_ACTIVOS) {
    return { data: sdrAiIso(dia), texto: `${entrada} A Digi não contactou nenhuma. Nada passou a humano. Nenhuma qualificação nova.` };
  }
  const c = doDia.filter(l => l.respondeu).length;
  const q = doDia.filter(l => (l.bant_n || 0) >= 4).length;
  const rec = doDia.filter(l => l.recusa).length;
  const p = doDia.filter(l => l.passado).length;
  const op = doDia.filter(l => l.stage || l.oportunidade).length;
  return {
    data: sdrAiIso(dia),
    texto: `${entrada} A Digi contactou ${c} por WhatsApp, ${q} com BANT completo e ${rec} não qualificadas. ${p} passaram a humano. ${op} com oportunidade no Gestor.`,
  };
}

const SdrAIResumo = ({ leads, ano }) => {
  const r = sdrAiResumoTexto(leads, ano);
  return (
    <div style={{ borderLeft: '3px solid #6366f1', background: 'color-mix(in oklch,#6366f1 5%,transparent)', padding: '12px 16px', borderRadius: 8, margin: '16px 0' }}>
      <div style={{ fontSize: 10, fontWeight: 700, color: '#4338ca', fontFamily: 'var(--dgd-font-mono,monospace)', textTransform: 'uppercase', letterSpacing: '0.08em', marginBottom: 6 }}>
        DIGI AI · {r.data}
      </div>
      <p style={{ margin: 0, fontSize: 13, color: 'var(--dgd-fg-1)', lineHeight: 1.6 }}>{r.texto}</p>
    </div>
  );
};

const SdrAIListaModal = ({ title, leads, onClose, onAbrir }) => (
  <div onClick={e => { if (e.target === e.currentTarget) onClose(); }}
    style={{ position: 'fixed', inset: 0, zIndex: 2000, background: 'rgba(0,0,0,0.35)', display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 24 }}>
    <div style={{ background: 'var(--dgd-bg-card,white)', border: '1px solid var(--dgd-border-1)', borderRadius: 10, boxShadow: '0 8px 32px rgba(0,0,0,0.18)', width: '100%', maxWidth: 820, maxHeight: '80vh', display: 'flex', flexDirection: 'column' }}>
      <div style={{ padding: '14px 18px', borderBottom: '1px solid var(--dgd-border-1)', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--dgd-fg-1)' }}>{title}</div>
        <button onClick={onClose} style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--dgd-fg-3)', padding: 4 }}>
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
        </button>
      </div>
      <div style={{ overflowY: 'auto', flex: 1 }}>
        {leads.length === 0 ? (
          <div style={{ padding: 32, textAlign: 'center', color: 'var(--dgd-fg-3)', fontSize: 13 }}>Sem leads para este critério neste mês.</div>
        ) : (
          <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12 }}>
            <thead>
              <tr>
                {['Nome', 'Empresa', 'Source', 'Origem', 'BANT', 'Data'].map(h => (
                  <th key={h} style={{ padding: '7px 12px', textAlign: 'left', fontSize: 10.5, color: 'var(--dgd-fg-3)', fontFamily: 'var(--dgd-font-mono,monospace)', borderBottom: '1px solid var(--dgd-border-1)', fontWeight: 600, whiteSpace: 'nowrap' }}>{h}</th>
                ))}
              </tr>
            </thead>
            <tbody>
              {leads.map(l => (
                <tr key={l.id} onClick={() => onAbrir(l, leads)} style={{ borderBottom: '1px solid var(--dgd-border-1)', cursor: 'pointer' }}
                  onMouseEnter={e => { e.currentTarget.style.background = 'var(--dgd-bg-app,#f8fafc)'; }}
                  onMouseLeave={e => { e.currentTarget.style.background = 'transparent'; }}>
                  <td style={{ padding: '8px 12px', fontWeight: 600, color: 'var(--dgd-fg-1)' }}>{sdrAiNomeLista(l)}</td>
                  <td style={{ padding: '8px 12px', color: 'var(--dgd-fg-2)' }}>{l.empresa}</td>
                  <td style={{ padding: '8px 12px', color: 'var(--dgd-fg-3)', fontSize: 11 }}>{l.source_label}</td>
                  <td style={{ padding: '8px 12px', color: 'var(--dgd-fg-1)', maxWidth: 220, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{sdrAiOrigem(l)}</td>
                  <td style={{ padding: '8px 12px', fontFamily: 'var(--dgd-font-mono,monospace)', fontSize: 11 }}>{l.bant_n == null ? '—' : `${l.bant_n}/4`}</td>
                  <td style={{ padding: '8px 12px', color: 'var(--dgd-fg-3)', fontFamily: 'var(--dgd-font-mono,monospace)', fontSize: 11 }}>{l.data || '—'}</td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>
      <div style={{ padding: '10px 18px', borderTop: '1px solid var(--dgd-border-1)', fontSize: 11, color: 'var(--dgd-fg-3)' }}>
        {leads.length} lead{leads.length !== 1 ? 's' : ''}
      </div>
    </div>
  </div>
);

function sdrAiEstadoConsulta(lead) {
  const fase = lead.circuito?.fase;
  if ((lead.bant_n || 0) >= 4) return { label: 'Qualificada', cor: '#166534', bg: '#f0fdf4' };
  if (lead.recusa) return { label: 'Não qualificada', cor: '#991b1b', bg: '#fef2f2' };
  if (fase === 'sem_contacto') return { label: 'Sem contacto', cor: '#991b1b', bg: '#fef2f2' };
  if (fase === 'assistencia') return { label: 'Assistência', cor: '#9a3412', bg: '#fff7ed' };
  if (fase === 'recusou') return { label: 'Recusou a Digi', cor: '#9a3412', bg: '#fff7ed' };
  if (fase === 'wa_respondeu') return { label: 'Respondeu no WhatsApp', cor: '#1d4ed8', bg: '#eff6ff' };
  if (lead.passado) return { label: 'Passada ao SDR', cor: '#166534', bg: '#f0fdf4' };
  if ((lead.bant_n || 0) >= 1 || fase === 'atendeu') return { label: 'Em qualificação', cor: '#92400e', bg: '#fffbeb' };
  if (lead.respondeu) return { label: 'Contactada', cor: '#1d4ed8', bg: '#eff6ff' };
  if (lead.circuito?.wa_estado === 'enviado') return { label: 'WhatsApp enviado', cor: '#1d4ed8', bg: '#eff6ff' };
  if (lead.circuito?.chamada) return { label: 'Chamada sem resposta', cor: '#92400e', bg: '#fffbeb' };
  if (fase === 'fora') return { label: 'Sem chamada automática', cor: '#64748b', bg: '#f1f5f9' };
  if (fase === 'espera' || fase === 'espera_2') return { label: 'À espera da hora', cor: '#64748b', bg: '#f1f5f9' };
  return { label: 'Por qualificar', cor: '#64748b', bg: '#f1f5f9' };
}

function sdrAiEntradaCampos(lead) {
  const promoNome = [
    [/estimativa de investimento/i, 'Investimento'],
    [/informa[cç][õo]es sobre o problema/i, 'Problema'],
  ];
  const extraAds = [/^city$/i, /^cidade$/i, /^mercado$/i];
  const promo = [];
  const extra = [];
  for (const c of lead.campos || []) {
    const label = String(c.label || '').trim();
    if (!label || !c.value) continue;
    if (/job title|inbox url|first name|last name|^your message$|^cargo$/i.test(label)) continue;
    const nome = promoNome.find(([re]) => re.test(label));
    if (lead.source === 'ADS' && nome) promo.push({ label: nome[1], value: c.value });
    else if (lead.source === 'ADS' && extraAds.some(re => re.test(label))) extra.push({ label: /^city$/i.test(label) ? 'Cidade' : label.charAt(0).toUpperCase() + label.slice(1), value: c.value });
    else if (lead.source !== 'ADS') extra.push({ label: label.charAt(0).toUpperCase() + label.slice(1), value: c.value });
  }
  return { promo, extra };
}

function sdrAiQuando(ts) {
  if (!ts) return '';
  const d = new Date(ts);
  if (Number.isNaN(d.getTime())) return '';
  const dia = d.toLocaleDateString('pt-PT', { day: '2-digit', month: '2-digit', timeZone: 'Europe/Lisbon' });
  const hora = d.toLocaleTimeString('pt-PT', { hour: '2-digit', minute: '2-digit', timeZone: 'Europe/Lisbon' });
  return hora && hora !== 'Invalid Date' ? `${dia} · ${hora}` : dia;
}

function sdrAiEventosFala(data) {
  if (Array.isArray(data?.eventos)) return data.eventos;
  const canais = Array.isArray(data?.canais) ? data.canais : [];
  return canais.flatMap(c => (c.mensagens || []).map(m => ({
    tipo: 'mensagem', ts: m.ts || null, canal: c.canal, de: m.de, titulo: c.canal, detalhe: m.msg,
  })));
}

function sdrAiQuem(de) {
  if (de === 'ai') return 'Digi';
  if (de === 'humano') return 'Humano';
  return 'Lead';
}

const SdrAIFicha = ({ lead, sdrList = [], ano, navLeads = [], onIr, onClose, onNota, onPassou, onRevisao, vista = 'qualificacao' }) => {
  const [nota, setNota] = React.useState(lead.nota?.texto || '');
  const [notaEstado, setNotaEstado] = React.useState('idle');
  const [fala, setFala] = React.useState(null);
  const [revisao, setRevisao] = React.useState(lead.revisao || null);
  const [revErro, setRevErro] = React.useState('');
  const [tab, setTab] = React.useState('qualificacao');
  const raiz = React.useRef(null);
  React.useEffect(() => {
    raiz.current?.scrollIntoView({ block: 'start' });
  }, [lead.id]);
  const head = { fontSize: 10, color: 'var(--dgd-fg-3)', fontFamily: 'var(--dgd-font-mono,monospace)', letterSpacing: '0.06em', textTransform: 'uppercase', fontWeight: 600, marginBottom: 8 };
  const linha = (k, v) => v ? (
    <div key={k} style={{ display: 'flex', gap: 8, marginBottom: 6, fontSize: 12.5 }}>
      <span style={{ color: 'var(--dgd-fg-3)', minWidth: 88, flexShrink: 0 }}>{k}</span>
      <span style={{ color: 'var(--dgd-fg-1)', fontWeight: 500, wordBreak: 'break-word' }}>{v}</span>
    </div>
  ) : null;

  React.useEffect(() => {
    let vivo = true;
    fetch(`/api/comercial/sdr/ai/fala?contacto_id=${encodeURIComponent(lead.id)}`, { credentials: 'include' })
      .then(r => r.ok ? r.json() : { canais: [] })
      .catch(() => ({ canais: [] }))
      .then(data => { if (vivo) setFala(data && typeof data === 'object' ? data : { canais: [], eventos: [] }); });
    return () => { vivo = false; };
  }, [lead.id]);

  const guardarNota = async () => {
    setNotaEstado('a-guardar');
    const r = await fetch('/api/comercial/sdr/ai/nota', {
      method: 'POST', credentials: 'include',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ contacto_id: lead.id, nota }),
    }).then(res => res.ok ? res.json() : null).catch(() => null);
    if (!r) { setNotaEstado('erro'); return; }
    setNotaEstado('gravada');
    onNota?.(lead.id, r);
  };

  const marcar = async (veredicto) => {
    setRevErro('');
    const res = await fetch('/api/comercial/sdr/ai/revisao', {
      method: 'POST', credentials: 'include',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ contacto_id: lead.id, visitor_id: lead.visitor_id || '', veredicto }),
    }).then(r => r.ok ? r.json() : null).catch(() => null);
    if (!res) { setRevErro('A revisão não ficou gravada.'); return; }
    setRevisao(res);
    onRevisao?.(lead.id, res);
  };

  const estado = sdrAiEstadoConsulta(lead);
  const entrada = sdrAiEntradaCampos(lead);
  const fichaCampanha = lead.ficha_campanha || null;
  const campanhaLista = sdrAiOrigem(lead);
  const origemLista = lead.source === 'NEWSLETTER' && lead.assunto ? lead.assunto : campanhaLista;
  const navIdx = navLeads.findIndex(l => String(l.id) === String(lead.id));
  const anterior = navIdx > 0 ? navLeads[navIdx - 1] : null;
  const seguinte = navIdx >= 0 && navIdx < navLeads.length - 1 ? navLeads[navIdx + 1] : null;
  React.useEffect(() => {
    const onKey = (e) => {
      const tag = document.activeElement && document.activeElement.tagName;
      if (tag === 'TEXTAREA' || tag === 'INPUT' || tag === 'SELECT') return;
      if (e.key === 'Escape') { onClose?.(); return; }
      if (e.key === 'ArrowLeft' && anterior) onIr?.(anterior);
      if (e.key === 'ArrowRight' && seguinte) onIr?.(seguinte);
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [anterior, seguinte, onIr, onClose]);
  const titulo = lead.empresa && lead.empresa !== '—' ? lead.empresa : sdrAiNomeLista(lead);
  const subtitulo = [
    titulo !== sdrAiNomeLista(lead) ? sdrAiNomeLista(lead) : null,
    origemLista !== '—' ? origemLista : null,
    lead.source === 'WEB' ? sdrAiSite(lead) : null,
    lead.source === 'ADS' && lead.canal && lead.canal !== (lead.source_label || lead.source) ? lead.canal : null,
  ].filter(Boolean).join(' · ');
  const seta = (activo) => ({
    width: 28, height: 28, borderRadius: 6, border: '1px solid #dde3ef', background: '#fff',
    color: activo ? '#112954' : '#cbd5e1', cursor: activo ? 'pointer' : 'default', fontSize: 16, lineHeight: 1,
  });
  const btn = { padding: '7px 14px', borderRadius: 6, fontSize: 12.5, cursor: 'pointer', fontWeight: 600 };
  const bloco = (k, v) => v ? (
    <div key={k} style={{ marginBottom: 10 }}>
      <div style={{ fontSize: 11, color: 'var(--dgd-fg-3)', marginBottom: 2 }}>{k}</div>
      <div style={{ fontSize: 12.5, color: 'var(--dgd-fg-1)', lineHeight: 1.45, whiteSpace: 'pre-wrap' }}>{v}</div>
    </div>
  ) : null;
  const listaTxt = (titulo, itens) => itens?.length ? (
    <div style={{ marginBottom: 10 }}>
      <div style={{ fontSize: 11, color: 'var(--dgd-fg-3)', marginBottom: 4 }}>{titulo}</div>
      {itens.map(item => <div key={item} style={{ fontSize: 12.5, color: 'var(--dgd-fg-1)', lineHeight: 1.45, marginBottom: 4 }}>{item}</div>)}
    </div>
  ) : null;

  const caixa = { border: '1px solid var(--dgd-border-1)', borderRadius: 8, padding: 14, background: '#fff' };
  const jaMostrado = /^(p[aá]gina|page|pa[ií]s|country|cidade|city|assunto|an[uú]ncio|formul[aá]rio|pedido)$/i;
  const letraBant = (key, label) => {
    const texto = lead.bant_valores?.[key];
    const flag = lead.bant?.[key];
    const v = flag === false ? false : (texto || flag === true ? true : null);
    const color = v === true ? '#166534' : v === false ? '#991b1b' : '#94a3b8';
    const bg = v === true ? '#f0fdf4' : v === false ? '#fef2f2' : '#f1f5f9';
    const border = v === true ? '#bbf7d0' : v === false ? '#fecaca' : '#e2e8f0';
    return <span style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', width: 18, height: 18, borderRadius: 3, fontSize: 9, fontWeight: 700, fontFamily: 'var(--dgd-font-mono,monospace)', color, background: bg, border: `1px solid ${border}`, flexShrink: 0 }}>{label}</span>;
  };

  return (
    <div ref={raiz} style={{ marginTop: 20, scrollMarginTop: 12, background: 'var(--dgd-bg-card,white)', border: '1px solid var(--dgd-border-1)', borderRadius: 8, overflow: 'hidden' }}>
        <div style={{ padding: '16px 20px 12px', display: 'flex', alignItems: 'flex-start', gap: 16, flexShrink: 0, background: '#fff' }}>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 10, fontFamily: 'var(--dgd-font-mono,monospace)', color: 'var(--dgd-fg-3)', letterSpacing: '0.08em', marginBottom: 6 }}>SDR AI · {estado.label}</div>
            {lead.circuito?.nota && <div style={{ fontSize: 12, color: 'var(--dgd-fg-2)', marginBottom: 6, lineHeight: 1.45 }}>{lead.circuito.nota}</div>}
            <div style={{ fontSize: 20, fontWeight: 700, color: 'var(--dgd-fg-1)', letterSpacing: '-0.01em' }}>{titulo}</div>
            {subtitulo && <div style={{ fontSize: 13, color: 'var(--dgd-fg-2)', marginTop: 4 }}>{subtitulo}</div>}
          </div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexShrink: 0 }}>
            {navLeads.length > 1 && navIdx >= 0 && (
              <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
                <button type="button" aria-label="Lead anterior" disabled={!anterior} onClick={() => anterior && onIr?.(anterior)} style={seta(!!anterior)}>‹</button>
                <span style={{ fontSize: 11, color: 'var(--dgd-fg-3)', fontFamily: 'var(--dgd-font-mono,monospace)', minWidth: 52, textAlign: 'center' }}>{navIdx + 1} / {navLeads.length}</span>
                <button type="button" aria-label="Lead seguinte" disabled={!seguinte} onClick={() => seguinte && onIr?.(seguinte)} style={seta(!!seguinte)}>›</button>
              </div>
            )}
            <button type="button" onClick={onClose} style={{ ...btn, border: '1px solid var(--dgd-border-1)', background: '#fff', color: 'var(--dgd-fg-2)', fontWeight: 600 }}>Voltar à lista</button>
          </div>
        </div>
        <div style={{ display: 'flex', gap: 2, padding: '0 12px', borderBottom: '1px solid var(--dgd-border-1)', background: '#fff', flexShrink: 0 }}>
          {[['qualificacao', 'Qualificação'], ['contacto', 'Contacto'], ['origem', 'Origem'], ['conversao', 'Conversão'], ['notas', 'Notas']].map(([id, label]) => (
            <button key={id} type="button" onClick={() => setTab(id)}
              style={{ padding: '11px 14px', border: 'none', borderBottom: tab === id ? '2px solid #112954' : '2px solid transparent', marginBottom: -1, background: 'transparent', cursor: 'pointer', fontFamily: 'inherit', fontSize: 13, fontWeight: tab === id ? 700 : 400, color: tab === id ? '#112954' : 'var(--dgd-fg-2)' }}>
              {label}
            </button>
          ))}
        </div>
        <div style={{ flex: 1, overflowY: 'auto', padding: 20, background: 'var(--dgd-bg,#f8fafc)' }}>
          {tab === 'contacto' && (
          <div style={{ display: 'grid', gridTemplateColumns: 'minmax(220px, 0.9fr) minmax(0, 1.1fr)', gap: 16, alignItems: 'start' }}>
            <div style={caixa}>
              <div style={head}>Contacto</div>
              {linha('Nome', sdrAiNomeLista(lead) || '—')}
              {linha('Cargo', lead.cargo || '—')}
              {linha('Email', lead.email || '—')}
              {linha('Telefone', sdrAiTemTelefone(lead) ? lead.telefone : 'Sem telefone')}
              {linha('País', lead.pais || '—')}
              {linha('Empresa', lead.empresa || '—')}
            </div>
            <div style={caixa}>
              <div style={head}>Entrada</div>
              {linha('Marca', lead.marca !== '—' ? lead.marca : '—')}
              {linha('Origem', origemLista !== '—' ? origemLista : '—')}
              {linha('Canal', sdrAiOrigemCanal(lead) || '—')}
            </div>
          </div>
          )}
          {tab === 'origem' && (
          <div style={{ display: 'grid', gridTemplateColumns: 'minmax(0, 1fr) minmax(0, 1fr)', gap: 16, alignItems: 'start' }}>
            <div style={caixa}>
              <div style={head}>Origem</div>
              {linha('Marca', lead.marca !== '—' ? lead.marca : null)}
              {linha('Source', lead.source_label)}
              {linha('Action', sdrAiActionId(lead))}
              {linha('Origem', origemLista !== '—' ? origemLista : null)}
              {linha('Canal', sdrAiOrigemCanal(lead))}
              {linha('Página', lead.page_url)}
              {linha('País', lead.pais)}
              {linha('Cidade', sdrAiCidade(lead))}
              {linha('Anúncio', lead.ad_nome && lead.ad_nome !== campanhaLista ? lead.ad_nome : null)}
              {linha('Assunto', lead.assunto && lead.assunto !== origemLista ? lead.assunto : null)}
              {bloco('Pedido', lead.pedido)}
              {entrada.promo.map(c => bloco(c.label, c.value))}
              {entrada.extra.filter(c => !jaMostrado.test(c.label)).map(c => linha(c.label, c.value))}
            </div>
            <div style={caixa}>
              <div style={head}>Ficha da campanha</div>
              {fichaCampanha ? (
                <>
                  <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--dgd-fg-1)', marginBottom: 8 }}>{fichaCampanha.titulo}{fichaCampanha.versao ? ` · v${fichaCampanha.versao}` : ''}</div>
                  {bloco('Oferta', fichaCampanha.oferta)}
                  {bloco('Mensagem-chave', fichaCampanha.mensagem)}
                  {listaTxt('Perguntas', fichaCampanha.perguntas)}
                  {listaTxt('Não dizer', fichaCampanha.nao_dizer)}
                  {bloco('Critério de handoff', fichaCampanha.handoff)}
                </>
              ) : (
                <div style={{ fontSize: 13, color: 'var(--dgd-fg-3)', lineHeight: 1.5 }}>Sem ficha de campanha. A Digi qualifica só com o framework.</div>
              )}
            </div>
          </div>
          )}
          {tab === 'qualificacao' && (
          <div style={{ display: 'grid', gridTemplateColumns: 'minmax(0, 1.15fr) minmax(280px, 0.85fr)', gap: 16, alignItems: 'start' }}>
            <div style={caixa}>
              <div style={head}>Histórico</div>
              {fala === null ? (
                <div style={{ fontSize: 13, color: 'var(--dgd-fg-3)' }}>A carregar o histórico...</div>
              ) : (
                <SdrAITimeline lead={lead} origem={origemLista} eventos={sdrAiEventosFala(fala)} vista={vista} />
              )}
              {!SDR_AI_CARDS_ACTIVOS && sdrAiEventosFala(fala || {}).some(e => e.tipo === 'mensagem') && (
                <div style={{ fontSize: 12.5, color: '#92400e', lineHeight: 1.5, marginTop: 12 }}>Conversa de teste. A qualificação da Digi ainda não está ligada.</div>
              )}
            </div>
            <div style={caixa}>
              {vista === 'nurturing' ? (
                <>
                  <div style={head}>Oportunidade</div>
                  {linha('Stage', lead.stage || '—')}
                  {linha('Oportunidade', lead.oportunidade || '—')}
                  {linha('Valor', sdrAiEuros(lead.valor))}
                  {linha('Estado', sdrAiEstadoNurturing(lead).label)}
                  <div style={{ height: 1, background: 'var(--dgd-border-1)', margin: '12px 0' }} />
                </>
              ) : null}
              <div style={head}>BANT · {lead.bant_n == null ? '—' : `${lead.bant_n}/4`}</div>
              {[['B', 'Budget', 'budget'], ['A', 'Authority', 'authority'], ['N', 'Need', 'need'], ['T', 'Timeline', 'timeline']].map(([letra, label, key]) => (
                <div key={key} style={{ display: 'flex', gap: 8, marginBottom: 12, alignItems: 'flex-start' }}>
                  {letraBant(key, letra)}
                  <div style={{ minWidth: 0 }}>
                    <div style={{ fontSize: 11, color: 'var(--dgd-fg-3)', marginBottom: 2 }}>{label}</div>
                    <div style={{ fontSize: 13, color: lead.bant_valores?.[key] ? 'var(--dgd-fg-1)' : 'var(--dgd-fg-3)', fontWeight: 500, lineHeight: 1.45, whiteSpace: 'pre-wrap' }}>{lead.bant_valores?.[key] || '—'}</div>
                  </div>
                </div>
              ))}
              {linha('Classificação', lead.classificacao)}
              {bloco('Recomendação', lead.recomendacao)}
              {bloco('Objecção', lead.objecao)}
              {bloco('Equipamento', lead.equipamento)}
            </div>
          </div>
          )}
          {tab === 'conversao' && (
          <div style={{ ...caixa, maxWidth: 560 }}>
            <div style={head}>Conversão</div>
            <div style={{ display: 'flex', gap: 8, marginBottom: 6, fontSize: 12.5 }}>
              <span style={{ color: 'var(--dgd-fg-3)', minWidth: 88, flexShrink: 0 }}>Estado</span>
              <span style={{ color: estado.cor, fontWeight: 600 }}>{estado.label}</span>
            </div>
            {lead.passado && <div style={{ fontSize: 12.5, color: '#166534', fontWeight: 600, marginBottom: 8 }}>Passada ao SDR{lead.passado_sdr ? ` · ${lead.passado_sdr}` : ''}</div>}
            {(lead.stage || lead.oportunidade) ? (
              <>
                {linha('Stage', lead.stage)}
                {linha('Oportunidade', lead.oportunidade)}
                {linha('Valor', lead.valor ? sdrAiEuros(lead.valor) : null)}
              </>
            ) : (
              <div style={{ fontSize: 13, color: 'var(--dgd-fg-3)' }}>Sem oportunidade no Gestor.</div>
            )}
          </div>
          )}
          {tab === 'notas' && (
          <div style={{ ...caixa, maxWidth: 640 }}>
            <div style={head}>Notas</div>
            <textarea value={nota} onChange={e => { setNota(e.target.value); setNotaEstado('idle'); }} rows={6}
              placeholder="O que viste nesta lead."
              style={{ width: '100%', boxSizing: 'border-box', padding: '8px 10px', border: '1px solid var(--dgd-border-1)', borderRadius: 6, fontSize: 13, color: 'var(--dgd-fg-1)', fontFamily: 'inherit', resize: 'vertical' }} />
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 8, flexWrap: 'wrap' }}>
              <button onClick={guardarNota} disabled={notaEstado === 'a-guardar'} style={{ ...btn, border: 'none', background: '#112954', color: '#fff' }}>{notaEstado === 'a-guardar' ? 'A guardar...' : notaEstado === 'gravada' ? 'Guardada' : 'Guardar nota'}</button>
              {lead.nota?.autor_nome && notaEstado !== 'gravada' && <span style={{ fontSize: 11, color: 'var(--dgd-fg-3)' }}>{lead.nota.autor_nome}</span>}
              {notaEstado === 'erro' && <span style={{ fontSize: 11, color: '#991b1b' }}>A nota não ficou gravada.</span>}
            </div>
          </div>
          )}
        </div>
    </div>
  );
};

const SdrAITimeline = ({ lead, origem, eventos = [], vista = 'qualificacao' }) => {
  const cor = (item) => {
    if (item.tipo === 'entrada') return '#112954';
    if (item.tipo === 'passagem') return '#166534';
    if (item.tipo === 'whatsapp' || item.canal === 'WhatsApp') return '#1d4ed8';
    if (item.tipo === 'chamada' || item.canal === 'Telemóvel') return '#92400e';
    if (item.de === 'ai') return '#4338ca';
    if (item.tipo === 'vazio') return '#cbd5e1';
    return '#0f766e';
  };
  const itens = [
    { tipo: 'entrada', ts: lead.ts || null, titulo: 'Entrada', detalhe: origem && origem !== '—' ? origem : 'Entrou na lista SDR AI' },
    ...eventos,
  ];
  if (!eventos.length && vista !== 'nurturing') itens.push({ tipo: 'vazio', ts: null, titulo: 'Qualificação', detalhe: 'A Digi ainda não falou com esta lead.' });
  if (vista === 'nurturing') itens.push({ tipo: 'vazio', ts: null, titulo: 'Nurturing', detalhe: 'A Digi ainda não acompanhou esta oportunidade.' });
  return (
    <div style={{ position: 'relative', paddingLeft: 18 }}>
      <div style={{ position: 'absolute', left: 4, top: 4, bottom: 4, width: 1, background: '#e2e8f0' }} />
      {itens.map((item, i) => {
        const quando = sdrAiQuando(item.ts);
        const quem = item.tipo === 'mensagem' ? sdrAiQuem(item.de) : '';
        const titulo = quem ? `${item.titulo} · ${quem}` : item.titulo;
        return (
          <div key={`${item.tipo}-${i}`} style={{ position: 'relative', padding: '0 0 16px 12px' }}>
            <span style={{ position: 'absolute', left: -18, top: 3, width: 9, height: 9, borderRadius: 99, background: item.tipo === 'vazio' ? '#fff' : cor(item), border: `2px solid ${item.tipo === 'vazio' ? '#cbd5e1' : '#fff'}`, boxShadow: '0 0 0 1px #e2e8f0' }} />
            {([quando, item.tipo === 'mensagem' ? null : item.canal].filter(Boolean).join(' · ')) && (
              <div style={{ fontSize: 11, color: 'var(--dgd-fg-3)', fontFamily: 'var(--dgd-font-mono,monospace)', marginBottom: 2 }}>
                {[quando, item.tipo === 'mensagem' ? null : item.canal].filter(Boolean).join(' · ')}
              </div>
            )}
            <div style={{ fontSize: 13, fontWeight: 600, color: cor(item), marginBottom: item.detalhe ? 2 : 0 }}>{titulo}</div>
            {item.detalhe && <div style={{ fontSize: 12.5, color: 'var(--dgd-fg-1)', lineHeight: 1.45, whiteSpace: 'pre-wrap' }}>{item.detalhe}</div>}
          </div>
        );
      })}
    </div>
  );
};

function sdrAiLeadsDaCelula(leads, metric, mes) {
  const doMes = leads.filter(l => l.mes === mes);
  if (metric === 'contactados') return doMes.filter(l => l.respondeu || sdrAiContactoDigi(l));
  if (metric === 'qualificados') return doMes.filter(l => (l.bant_n || 0) >= 4);
  if (metric === 'nao_qualificados') return doMes.filter(l => l.recusa);
  if (metric === 'chamadas') return doMes.filter(l => l.circuito?.chamada);
  if (metric === 'whatsapp') return doMes.filter(l => l.circuito?.wa_estado === 'enviado');
  if (metric === 'sem_contacto') return doMes.filter(l => l.circuito?.fase === 'sem_contacto');
  return doMes;
}

const SdrAIComando = () => {
  const [controlo, setControlo] = React.useState(null);
  const [aConfirmar, setAConfirmar] = React.useState(false);
  const [destinos, setDestinos] = React.useState([]);
  const [campanhas, setCampanhas] = React.useState([]);
  const [leadsTeste, setLeadsTeste] = React.useState([]);
  const [origem, setOrigem] = React.useState('ADS MIMAKI');
  const [campanhaId, setCampanhaId] = React.useState('');
  const [empresa, setEmpresa] = React.useState('');
  const [destino, setDestino] = React.useState('fc');
  const [ensaio, setEnsaio] = React.useState(null);
  const [erro, setErro] = React.useState('');
  const [aLigar, setALigar] = React.useState(false);
  const [aCriar, setACriar] = React.useState(false);

  const carregarLeadsTeste = React.useCallback(() => {
    fetch('/api/comercial/sdr/ai/ensaio/leads', { credentials: 'include' })
      .then(r => r.ok ? r.json() : Promise.reject())
      .then(d => setLeadsTeste(Array.isArray(d.leads) ? d.leads : []))
      .catch(() => {});
  }, []);

  React.useEffect(() => {
    let vivo = true;
    fetch('/api/comercial/sdr/ai/controlo', { credentials: 'include' })
      .then(r => r.ok ? r.json() : Promise.reject())
      .then(d => { if (vivo) setControlo(d); })
      .catch(() => { if (vivo) setControlo({ activa: false }); });
    fetch('/api/comercial/sdr/ai/ensaio/destinos', { credentials: 'include' })
      .then(r => r.ok ? r.json() : Promise.reject())
      .then(d => {
        if (!vivo) return;
        const lista = Array.isArray(d.destinos) ? d.destinos : [];
        setDestinos(lista);
        if (lista[0]?.id) setDestino(actual => lista.some(x => x.id === actual) ? actual : lista[0].id);
      })
      .catch(() => {});
    fetch('/api/comercial/sdr/ai/ensaio/campanhas', { credentials: 'include' })
      .then(r => r.ok ? r.json() : Promise.reject())
      .then(d => {
        if (!vivo) return;
        const lista = Array.isArray(d.campanhas) ? d.campanhas : [];
        setCampanhas(lista);
        setCampanhaId(actual => actual || lista[0]?.id || '');
      })
      .catch(() => {});
    carregarLeadsTeste();
    return () => { vivo = false; };
  }, [carregarLeadsTeste]);

  React.useEffect(() => {
    if (!ensaio?.id || ensaio.fase === 'terminada' || ensaio.fase === 'falhou') return undefined;
    let vivo = true;
    const tick = () => {
      fetch('/api/comercial/sdr/ai/ensaio?id=' + encodeURIComponent(ensaio.id), { credentials: 'include' })
        .then(r => r.ok ? r.json() : Promise.reject())
        .then(d => { if (vivo) setEnsaio(prev => prev ? { ...prev, ...d } : prev); })
        .catch(() => {});
    };
    const t = setInterval(tick, 2000);
    tick();
    return () => { vivo = false; clearInterval(t); };
  }, [ensaio?.id, ensaio?.fase]);

  const gravar = async (activa) => {
    setErro('');
    const r = await fetch('/api/comercial/sdr/ai/controlo', {
      method: 'POST', credentials: 'include', headers: { 'content-type': 'application/json' },
      body: JSON.stringify({ activa }),
    });
    const d = await r.json().catch(() => ({}));
    if (!r.ok) { setErro(d.error || 'Não foi possível gravar'); return; }
    setControlo(d);
    setAConfirmar(false);
  };

  const criarLead = async () => {
    setErro('');
    setACriar(true);
    try {
      const r = await fetch('/api/comercial/sdr/ai/ensaio/leads', {
        method: 'POST', credentials: 'include', headers: { 'content-type': 'application/json' },
        body: JSON.stringify({ destino, origem, campanha_id: campanhaId, empresa }),
      });
      const d = await r.json().catch(() => ({}));
      if (!r.ok) { setErro(d.error || 'Não foi possível criar a lead'); return; }
      setEmpresa('');
      carregarLeadsTeste();
    } finally { setACriar(false); }
  };

  const retirarLead = async (id) => {
    setErro('');
    const r = await fetch('/api/comercial/sdr/ai/ensaio/leads/' + encodeURIComponent(id), { method: 'DELETE', credentials: 'include' });
    const d = await r.json().catch(() => ({}));
    if (!r.ok) { setErro(d.error || 'Não foi possível retirar a lead'); return; }
    setLeadsTeste(prev => prev.filter(l => l.id !== id));
  };

  const ligar = async (lead) => {
    setErro('');
    setALigar(true);
    try {
      const r = await fetch('/api/comercial/sdr/ai/ensaio', {
        method: 'POST', credentials: 'include', headers: { 'content-type': 'application/json' },
        body: JSON.stringify({ lead_id: lead.id }),
      });
      const d = await r.json().catch(() => ({}));
      if (!r.ok) { setErro(d.error || 'A chamada não saiu'); return; }
      setEnsaio({ id: d.id, nome: d.nome, origem: d.origem, campanha: d.campanha, empresa: d.empresa, fase: 'a-chamar', mensagem: 'A Digi está a chamar', linhas: [] });
    } finally { setALigar(false); }
  };

  const ligado = !!controlo?.activa;
  return (
    <div style={{ background: 'var(--dgd-bg-card,white)', border: '1px solid var(--dgd-border-1)', borderRadius: 8, padding: '14px 16px', marginBottom: 16 }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap' }}>
        <div style={{ fontSize: 13, fontWeight: 650, color: 'var(--dgd-fg-1)' }}>Qualificação das leads novas</div>
        <button onClick={() => ligado ? gravar(false) : setAConfirmar(true)} disabled={!controlo} style={{ border: '1px solid ' + (ligado ? '#bbf7d0' : 'var(--dgd-border-1)'), background: ligado ? '#f0fdf4' : '#fff', color: ligado ? '#166534' : 'var(--dgd-fg-2)', borderRadius: 6, padding: '4px 10px', fontSize: 12, fontWeight: 650, cursor: 'pointer' }}>
          {ligado ? 'Ligada' : 'Desligada'}
        </button>
        <span style={{ fontSize: 12, color: 'var(--dgd-fg-3)' }}>
          {ligado ? 'Ainda não liga aos clientes. O questionário de WhatsApp está parado.' : 'A Digi não qualifica as leads que entram. O ensaio interno continua disponível.'}
        </span>
      </div>
      {aConfirmar && (
        <div style={{ marginTop: 10, display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }}>
          <span style={{ fontSize: 12, color: '#92400e' }}>Ligar a qualificação? Nesta fase a Digi ainda não marca clientes.</span>
          <button onClick={() => gravar(true)} style={{ border: 'none', background: '#166534', color: '#fff', borderRadius: 6, padding: '4px 10px', fontSize: 12, cursor: 'pointer' }}>Confirmar</button>
          <button onClick={() => setAConfirmar(false)} style={{ border: '1px solid var(--dgd-border-1)', background: '#fff', borderRadius: 6, padding: '4px 10px', fontSize: 12, cursor: 'pointer' }}>Cancelar</button>
        </div>
      )}
      <div style={{ marginTop: 14, paddingTop: 12, borderTop: '1px solid var(--dgd-border-1)' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
          <div style={{ fontSize: 12, fontWeight: 650, color: 'var(--dgd-fg-1)' }}>Leads de teste</div>
          <span style={{ fontSize: 10, fontWeight: 700, letterSpacing: '0.06em', color: '#991b1b', background: '#fef2f2', border: '1px solid #fecaca', borderRadius: 999, padding: '2px 8px' }}>TESTE</span>
        </div>
        <div style={{ fontSize: 12, color: 'var(--dgd-fg-3)', marginBottom: 10 }}>Ficam só neste ensaio. Não entram na lista nem no quadro. A chamada sai do 918 780 180 para o telemóvel de quem escolheres.</div>
        <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', alignItems: 'end' }}>
          <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 11, color: 'var(--dgd-fg-3)' }}>
            Origem
            <select value={origem} onChange={e => setOrigem(e.target.value)} style={{ fontSize: 12, padding: '5px 8px', borderRadius: 6, border: '1px solid var(--dgd-border-1)', background: '#fff', color: 'var(--dgd-fg-1)' }}>
              {SDR_AI_ACTIONS.map(a => <option key={a.id} value={a.id}>{a.id}</option>)}
            </select>
          </label>
          <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 11, color: 'var(--dgd-fg-3)' }}>
            Campanha
            <select value={campanhaId} onChange={e => setCampanhaId(e.target.value)} style={{ fontSize: 12, padding: '5px 8px', borderRadius: 6, border: '1px solid var(--dgd-border-1)', background: '#fff', color: 'var(--dgd-fg-1)', maxWidth: 280 }}>
              {campanhas.map(c => <option key={c.id} value={c.id}>{c.titulo}</option>)}
            </select>
          </label>
          <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 11, color: 'var(--dgd-fg-3)' }}>
            Empresa
            <input value={empresa} onChange={e => setEmpresa(e.target.value)} placeholder="Opcional" maxLength={80} style={{ fontSize: 12, padding: '5px 8px', borderRadius: 6, border: '1px solid var(--dgd-border-1)', width: 160 }} />
          </label>
          <label style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 11, color: 'var(--dgd-fg-3)' }}>
            Quem atende
            <select value={destino} onChange={e => setDestino(e.target.value)} style={{ fontSize: 12, padding: '5px 8px', borderRadius: 6, border: '1px solid var(--dgd-border-1)', background: '#fff', color: 'var(--dgd-fg-1)' }}>
              {destinos.map(d => <option key={d.id} value={d.id}>{d.nome}</option>)}
            </select>
          </label>
          <button onClick={criarLead} disabled={aCriar || !campanhaId || destinos.length === 0} style={{ border: 'none', background: '#312e81', color: '#fff', borderRadius: 6, padding: '6px 12px', fontSize: 12, cursor: aCriar ? 'wait' : 'pointer' }}>
            Criar lead
          </button>
        </div>
        {destinos.length === 0 && <div style={{ marginTop: 8, fontSize: 12, color: 'var(--dgd-fg-3)' }}>Os números internos ainda não estão disponíveis.</div>}
        {campanhas.length === 0 && <div style={{ marginTop: 8, fontSize: 12, color: 'var(--dgd-fg-3)' }}>Não há campanhas com ficha activa.</div>}
        <div style={{ marginTop: 12, display: 'flex', flexDirection: 'column', gap: 6 }}>
          {leadsTeste.map(l => {
            const quem = destinos.find(d => d.id === l.destino)?.nome || '';
            return (
              <div key={l.id} style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap', fontSize: 12, color: 'var(--dgd-fg-1)' }}>
                <span style={{ fontWeight: 650 }}>{l.origem}</span>
                <span>{l.campanha_titulo}</span>
                {l.empresa ? <span style={{ color: 'var(--dgd-fg-3)' }}>{l.empresa}</span> : null}
                {quem ? <span style={{ color: 'var(--dgd-fg-3)' }}>{quem}</span> : null}
                <button disabled={aLigar} onClick={() => ligar(l)} style={{ border: '1px solid #c7d2fe', background: '#eef2ff', color: '#312e81', borderRadius: 6, padding: '3px 8px', fontSize: 12, cursor: aLigar ? 'wait' : 'pointer' }}>Ligar</button>
                <button onClick={() => retirarLead(l.id)} style={{ border: '1px solid var(--dgd-border-1)', background: '#fff', color: 'var(--dgd-fg-2)', borderRadius: 6, padding: '3px 8px', fontSize: 12, cursor: 'pointer' }}>Retirar</button>
              </div>
            );
          })}
        </div>
        {erro && <div style={{ marginTop: 8, fontSize: 12, color: '#991b1b' }}>{erro}</div>}
        {ensaio && (
          <div style={{ marginTop: 10 }}>
            <div style={{ fontSize: 12, color: '#312e81', marginBottom: 6 }}>{ensaio.mensagem || ensaio.fase}{ensaio.nome ? ` · ${ensaio.nome}` : ''}{ensaio.origem ? ` · ${ensaio.origem}` : ''}{ensaio.campanha ? ` · ${ensaio.campanha}` : ''}</div>
            {(ensaio.linhas || []).map(l => (
              <div key={l.id} style={{ fontSize: 12, marginBottom: 4, color: 'var(--dgd-fg-1)' }}>
                <span style={{ fontWeight: 650 }}>{l.lado === 'lead' ? 'Lead' : 'Digi'}</span>
                {l.hora ? ` · ${l.hora}` : ''} — {l.text}
              </div>
            ))}
          </div>
        )}
      </div>
    </div>
  );
};

window.SdrAITab = ({ selAno, sdrList }) => {
  const defaultFunil = SDR_AI_MESES.map(mes => ({ mes, atribuidos:0, contactados:0, qualificados:0, nao_qualificados:0, chamadas:0, whatsapp:0, sem_contacto:0, elegiveis:0, contactos_digi:0 }));
  const titulos = {
    atribuidos: 'Leads Atribuídos',
    contactados: 'Leads Contactados',
    qualificados: 'Qualificados BANT',
    nao_qualificados: 'Não Qualificados BANT',
    chamadas: 'Chamadas',
    whatsapp: 'WhatsApp após falha',
    sem_contacto: 'Sem contacto',
  };

  const [inboundLeads, setInboundLeads] = React.useState([]);
  const [inboundEstado, setInboundEstado] = React.useState('a-carregar');
  const [lista, setLista] = React.useState(null);
  const [ficha, setFicha] = React.useState(null);
  const [navLeads, setNavLeads] = React.useState([]);
  const [passados, setPassados] = React.useState({});
  const [modo, setModo] = React.useState('qualificacao');
  const [recorte, setRecorte] = React.useState(null);
  const scrollLista = React.useRef(0);

  React.useEffect(() => {
    let vivo = true;
    setInboundEstado('a-carregar');
    setLista(null);
    setFicha(null);
    fetch(`/api/comercial/sdr/ai/inbound?ano=${selAno}`, { credentials:'include' })
      .then(r => r.ok ? r.json() : Promise.reject())
      .then(data => {
        if (!vivo || !Array.isArray(data?.leads)) return;
        setInboundLeads(data.leads);
        setInboundEstado('ok');
      })
      .catch(() => { if (vivo) setInboundEstado('erro'); });
    return () => { vivo = false; };
  }, [selAno]);

  React.useEffect(() => {
    const detail = inboundEstado === 'ok' ? sdrAiCards(inboundLeads.filter(l => sdrAiNoPeriodo(l) && !l.arquivada && !l.apagada)) : null;
    window.dispatchEvent(new CustomEvent('sdr-ai-kpis', { detail }));
  }, [inboundEstado, inboundLeads]);

  const leadsPeriodo = inboundLeads.filter(l => sdrAiNoPeriodo(l) && !l.apagada);
  const leadsActivas = leadsPeriodo.filter(l => !l.arquivada);
  const funilRows = inboundEstado === 'ok' ? sdrAiFunilDaLista(leadsActivas) : defaultFunil;

  const handleCellClick = (metric, mes) => {
    const nurturing = ['nurturing', 'nurturing_contactos', 'nurturing_demos', 'nurturing_ganhas'].includes(metric);
    setFicha(null);
    setModo(nurturing ? 'nurturing' : 'qualificacao');
    setRecorte({ metrica: metric, mes, id: Date.now() });
  };

  const mudarModo = (seguinte) => {
    setFicha(null);
    setModo(seguinte);
    setRecorte(null);
  };

  const abrir = (lead, contexto) => {
    const actual = inboundLeads.find(l => String(l.id) === String(lead.id)) || lead;
    scrollLista.current = window.scrollY;
    setNavLeads(Array.isArray(contexto) ? contexto : []);
    setLista(null);
    setFicha(actual);
  };

  const fecharFicha = () => {
    setFicha(null);
    requestAnimationFrame(() => window.scrollTo(0, scrollLista.current));
  };

  const irFicha = (lead) => {
    const actual = inboundLeads.find(l => String(l.id) === String(lead.id)) || lead;
    setFicha(actual);
  };

  const gravarNota = (id, nota) => {
    setInboundLeads(prev => prev.map(l => l.id === id ? { ...l, nota } : l));
    setFicha(f => f && f.id === id ? { ...f, nota } : f);
    setLista(v => v ? { ...v, leads: v.leads.map(l => l.id === id ? { ...l, nota } : l) } : v);
  };

  const gravarRevisao = (id, revisao) => {
    setInboundLeads(prev => prev.map(l => l.id === id ? { ...l, revisao } : l));
    setFicha(f => f && f.id === id ? { ...f, revisao } : f);
  };

  const marcarLista = (ids, accao) => {
    const setIds = new Set(ids.map(id => String(id)));
    setInboundLeads(prev => prev.flatMap(l => {
      if (!setIds.has(String(l.id))) return [l];
      if (accao === 'apagar') return [];
      if (accao === 'arquivar') return [{ ...l, arquivada: true }];
      return [{ ...l, arquivada: false }];
    }));
    setFicha(f => f && setIds.has(String(f.id)) && accao !== 'repor' ? null : f);
    setLista(v => {
      if (!v || accao === 'repor') return v;
      return { ...v, leads: v.leads.filter(l => !setIds.has(String(l.id))) };
    });
  };

  const marcarPassado = (id, info) => {
    const nome = info?.nome || '';
    setPassados(prev => ({ ...prev, [id]: { nome } }));
    setInboundLeads(prev => prev.map(l => l.id === id ? { ...l, passado: true, passado_sdr: nome || l.passado_sdr } : l));
    setFicha(f => f && f.id === id ? { ...f, passado: true, passado_sdr: nome || f.passado_sdr } : f);
    setLista(v => v ? { ...v, leads: v.leads.map(l => l.id === id ? { ...l, passado: true, passado_sdr: nome || l.passado_sdr } : l) } : v);
  };

  return (
    <>
      <SdrAIComando />
      <div style={{ background:'var(--dgd-bg-card,white)', border:'1px solid var(--dgd-border-1)', borderRadius:8, overflow:'hidden' }}>
        <SdrAIFunilTable rows={funilRows} onCellClick={inboundEstado === 'ok' ? handleCellClick : null} />
      </div>
      {inboundEstado === 'ok'
        ? <div style={{ display: ficha ? 'none' : 'block' }}><SdrAIInboundPanel leads={leadsPeriodo} sdrList={sdrList} selAno={selAno} recorte={recorte} modo={modo} onModo={mudarModo} nQual={leadsActivas.length} nNurt={leadsActivas.filter(sdrAiTemOportunidade).length} onAbrir={abrir} onPassou={marcarPassado} onLista={marcarLista} passados={passados} /></div>
        : <div style={{ marginTop:20, padding:24, fontSize:13, color:'var(--dgd-fg-3)', background:'var(--dgd-bg-card,white)', border:'1px solid var(--dgd-border-1)', borderRadius:8 }}>{inboundEstado === 'erro' ? 'A lista de inbound não carregou.' : 'A carregar a lista…'}</div>}
      {lista && !ficha && <SdrAIListaModal title={lista.title} leads={lista.leads} onClose={() => setLista(null)} onAbrir={abrir} />}
      {ficha && <SdrAIFicha key={ficha.id} lead={ficha} vista={modo} sdrList={sdrList} ano={selAno} navLeads={navLeads} onIr={irFicha} onClose={fecharFicha} onNota={gravarNota} onRevisao={gravarRevisao} onPassou={marcarPassado} />}
    </>
  );
};
