/* =============================================================================
   screen_comercial_rpc_sdr.jsx — RPC SDR · Outbound & Prospecção
   =============================================================================
   Fase 1: dados mock. Ligações à BD a fazer numa fase seguinte.
   ============================================================================= */

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

const SDR_TABS = [
  { id: 'sdr-ai',        label: 'SDR AI' },
  { id: 'sdr-humano',    label: 'SDR Humano' },
  { id: 'por-sdr',       label: 'Por SDR' },
  { id: 'qualificadas',  label: 'Qualificadas' },
  { id: 'definicoes',    label: 'Definições' },
  { id: 'coach',         label: 'Coach' },
];

const SDR_METAS = {
  taxa_contacto:  70,
  taxa_qualif:    40,
  agendadas_mes:  17,
  noshow_pct:     15,
  tempo_resp:       4,
  conv_pct:       40,
};

// SDR_LIST carregada dinamicamente via /api/comercial/sdr/list

// ─── Mock data — por SDR ──────────────────────────────────────────────────────
const SDR_FUNIL_BY_SDR = {
  carina: [
    { mes:'Jan', atribuidos_sdr:26, atribuidos_prospect:16, contactados_sdr:20, contactados_prospect:12, qualificados:28, agendadas:18, noshow_pct:11, tempo_resp:3.1, passados:16, pipeline_k:58,  conv_pct:57.1 },
    { mes:'Fev', atribuidos_sdr:24, atribuidos_prospect:14, contactados_sdr:18, contactados_prospect:11, qualificados:25, agendadas:16, noshow_pct:13, tempo_resp:3.4, passados:14, pipeline_k:50,  conv_pct:56.0 },
    { mes:'Mar', atribuidos_sdr:28, atribuidos_prospect:17, contactados_sdr:22, contactados_prospect:13, qualificados:30, agendadas:20, noshow_pct:10, tempo_resp:2.9, passados:18, pipeline_k:65,  conv_pct:60.0 },
    { mes:'Abr', atribuidos_sdr:25, atribuidos_prospect:15, contactados_sdr:19, contactados_prospect:11, qualificados:26, agendadas:15, noshow_pct:16, tempo_resp:4.2, passados:13, pipeline_k:46,  conv_pct:50.0 },
    { mes:'Mai', atribuidos_sdr:30, atribuidos_prospect:18, contactados_sdr:24, contactados_prospect:14, qualificados:33, agendadas:22, noshow_pct: 9, tempo_resp:2.7, passados:20, pipeline_k:72,  conv_pct:60.6 },
    { mes:'Jun', atribuidos_sdr:29, atribuidos_prospect:17, contactados_sdr:23, contactados_prospect:13, qualificados:31, agendadas:20, noshow_pct:12, tempo_resp:3.0, passados:18, pipeline_k:65,  conv_pct:58.1 },
    { mes:'Jul', atribuidos_sdr:24, atribuidos_prospect:14, contactados_sdr:17, contactados_prospect:10, qualificados:20, agendadas:12, noshow_pct:18, tempo_resp:4.5, passados:10, pipeline_k:36,  conv_pct:50.0 },
    { mes:'Ago', atribuidos_sdr:18, atribuidos_prospect:10, contactados_sdr:11, contactados_prospect: 7, qualificados:12, agendadas: 7, noshow_pct:24, tempo_resp:5.8, passados: 5, pipeline_k:18,  conv_pct:41.7 },
    { mes:'Set', atribuidos_sdr:32, atribuidos_prospect:18, contactados_sdr:27, contactados_prospect:15, qualificados:38, agendadas:26, noshow_pct: 8, tempo_resp:1.8, passados:24, pipeline_k:86,  conv_pct:63.2 },
    { mes:'Out', atribuidos_sdr: 8, atribuidos_prospect: 5, contactados_sdr: 6, contactados_prospect: 3, qualificados: 5, agendadas: 4, noshow_pct: 7, tempo_resp:2.1, passados: 3, pipeline_k:14,  conv_pct:60.0 },
    { mes:'Nov', atribuidos_sdr: 0, atribuidos_prospect: 0, contactados_sdr: 0, contactados_prospect: 0, qualificados: 0, agendadas: 0, noshow_pct: 0, tempo_resp: 0,  passados: 0, pipeline_k: 0,  conv_pct: 0   },
    { mes:'Dez', atribuidos_sdr: 0, atribuidos_prospect: 0, contactados_sdr: 0, contactados_prospect: 0, qualificados: 0, agendadas: 0, noshow_pct: 0, tempo_resp: 0,  passados: 0, pipeline_k: 0,  conv_pct: 0   },
  ],
  ai: [
    { mes:'Jan', atribuidos:120, contactados:95,  qualificados:20 },
    { mes:'Fev', atribuidos:115, contactados:90,  qualificados:18 },
    { mes:'Mar', atribuidos:128, contactados:103, qualificados:22 },
    { mes:'Abr', atribuidos:122, contactados:98,  qualificados:21 },
    { mes:'Mai', atribuidos:135, contactados:110, qualificados:24 },
    { mes:'Jun', atribuidos:130, contactados:105, qualificados:23 },
    { mes:'Jul', atribuidos:118, contactados:94,  qualificados:19 },
    { mes:'Ago', atribuidos:108, contactados:85,  qualificados:15 },
    { mes:'Set', atribuidos:130, contactados:105, qualificados:25 },
    { mes:'Out', atribuidos: 35, contactados: 28, qualificados: 6  },
    { mes:'Nov', atribuidos:  0, contactados:  0, qualificados:  0 },
    { mes:'Dez', atribuidos:  0, contactados:  0, qualificados:  0 },
  ],
};

const SDR_FUNIL_ALL = SDR_FUNIL_BY_SDR.carina;

const SDR_POR_SDR = [
  { nome:'SDR AI · digi.ai', isAI:true,  atribuidos:130, contactados:105, qualificados:25, agendadas: 7, pipeline_k:26 },
  { nome:'Carina Reis',               isAI:false, atribuidos: 50, contactados: 42, qualificados:38, agendadas:26, pipeline_k:86 },
];

const SDR_DEFINICOES = [
  { kpi:'Taxa de Contacto',                formula:'Contactados / Atribuidos',                                  meta:`>= ${SDR_METAS.taxa_contacto}%`,    regra:'Conta qualquer tentativa registada na ficha (WhatsApp) com resposta do lead.' },
  { kpi:'Taxa de Qualificação BANT',       formula:'Qualificados BANT / Contactados',                          meta:`>= ${SDR_METAS.taxa_qualif}%`,      regra:'So conta como qualificado o lead com nota BANT de 4 campos preenchidos.' },
  { kpi:'Oportunidades Passadas',          formula:'Leads qualificados passados à equipa comercial (total)',   meta:'--',                                regra:'Inclui demos realizadas e passagens directas sem demo. O handoff fica registado na ficha CRM.' },
  { kpi:'↳ Demos Agendadas',              formula:'Subconjunto de Oportunidades Passadas com demo agendada',  meta:`>= ${SDR_METAS.agendadas_mes}/mês`, regra:'Agendamento com data confirmada e comercial responsável. Meta definida no Daily Prospect.' },
  { kpi:'Taxa de qualificação comercial', formula:'Oportunidades Passadas / Qualificados BANT',               meta:`>= ${SDR_METAS.conv_pct}%`,         regra:'Mede se a qualificação BANT resulta em oportunidade real para o comercial. Meta >= 40%.' },
  { kpi:'Taxa de No-Show (Demos)',         formula:'Não Compareceu / Demos Agendadas',                         meta:`<= ${SDR_METAS.noshow_pct}%`,       regra:'Aplica-se apenas a demos agendadas. Resultado registado até 24h após a data da demo.' },
  { kpi:'Tempo de Resposta a Lead Novo',   formula:'1 contacto - hora de atribuicao do lead',                  meta:`<= ${SDR_METAS.tempo_resp}h uteis`, regra:'Timestamp automatico da ficha; SDR AI responde em minutos.' },
  { kpi:'Pipeline Gerado',                 formula:'Valor total das OPs nascidas de oportunidades SDR',        meta:'--',                                regra:'Soma de todas as oportunidades passadas (demos + directas). Herdado do RPC no momento da criacao da OP.' },
];

// ─── Mock Leads SDR AI (amostra representativa) ───────────────────────────────
// status: atribuido | contactado | em_qualificacao | passado_humano | nao_qualificado
const SDR_AI_LEADS = [
  { id:1,  mes:'Set', nome:'Pedro Monteiro',  empresa:'Grafica Norte Lda',     telefone:'+351 912 345 678', segmento:'Impressao Digital', status:'passado_humano',  atribuido:'02/09', ultimo_wa:'05/09', bant:{budget:true,authority:true,need:true,timeline:true},    notas:'Interesse Mimaki JV300. Budget ~40k confirmado. Urgente.', conversa:[{de:'ai',msg:'Ola Pedro, sou a Digi da Digidelta. Vi que a vossa grafica trabalha com impressao de grande formato — posso mostrar uma solucao que reduz custos em 30%?',ts:'03/09 09:15'},{de:'lead',msg:'Bom dia. Sim pode falar, estamos a avaliar equipamento novo.',ts:'03/09 09:22'},{de:'ai',msg:'Otimo! Tem budget aprovado para este ano ou sera 2027?',ts:'03/09 09:23'},{de:'lead',msg:'Temos verba aprovada ate Dezembro, a volta de 40 mil.',ts:'03/09 09:31'},{de:'ai',msg:'Perfeito. Vou passar o contacto a Carina Reis que vai agendar uma demo convosco. Ela entra em contacto hoje.',ts:'03/09 09:32'}], historico:[{data:'Fev 2025',campanha:'Mimaki JV300 — Lançamento PT',canal:'Meta Ads',interacao:'Clicou no anúncio',resultado:'Sem conversão'},{data:'Jun 2025',campanha:'Decal Verão 2025',canal:'Email',interacao:'Email aberto (2×) — não respondeu',resultado:'Sem resposta'},{data:'Nov 2025',campanha:'Mimaki End of Year',canal:'Meta Ads',interacao:'Clicou e visitou landing page',resultado:'Formulário não submetido'},{data:'Mar 2026',campanha:'Gráficas — Prospecção Q1',canal:'WhatsApp',interacao:'Contacto WA — não respondeu',resultado:'Sem resposta'}] },
  { id:2,  mes:'Set', nome:'Ana Fonseca',     empresa:'Estudio Criativo AF',   telefone:'+351 962 111 222', segmento:'Design & Print',    status:'passado_humano',  atribuido:'03/09', ultimo_wa:'06/09', bant:{budget:true,authority:true,need:true,timeline:false},   notas:'Timeline incerta mas necessidade clara. Recomendado followup Q1.', conversa:[{de:'ai',msg:'Ola Ana, vi o vosso trabalho. Estao a pensar renovar o parque de impressao?',ts:'04/09 10:00'},{de:'lead',msg:'Sim, o equipamento atual tem 6 anos.',ts:'04/09 10:15'},{de:'ai',msg:'Qual o prazo ideal para a decisao?',ts:'04/09 10:16'},{de:'lead',msg:'Nao temos pressa, talvez Q1 2027.',ts:'04/09 10:20'},{de:'ai',msg:'Entendido. A Carina vai apresentar-vos as opcoes com calma.',ts:'04/09 10:21'}], historico:[{data:'Abr 2025',campanha:'Decal Design Studios',canal:'Meta Ads',interacao:'Clicou no anúncio',resultado:'Sem conversão'},{data:'Set 2025',campanha:'Mimaki Print Quality',canal:'Email',interacao:'Email aberto — link clicado',resultado:'Visitou site, sem contacto'}] },
  { id:3,  mes:'Set', nome:'Rui Carvalho',    empresa:'Print Express',         telefone:'+351 933 444 555', segmento:'Impressao Digital', status:'passado_humano',  atribuido:'01/09', ultimo_wa:'04/09', bant:{budget:true,authority:true,need:true,timeline:true},    notas:'Urgente. Equipamento avariado. Budget 60k.', conversa:[{de:'ai',msg:'Bom dia Rui, soube que estao a procura de solucao de impressao UV?',ts:'02/09 08:45'},{de:'lead',msg:'Sim, o nosso equipamento avariou e precisamos de solucao rapida.',ts:'02/09 08:50'},{de:'ai',msg:'Temos stock disponivel. Budget aprovado?',ts:'02/09 08:51'},{de:'lead',msg:'Sim, ate 60k.',ts:'02/09 08:53'},{de:'ai',msg:'Passo ja a Carina Reis — ela liga em menos de 2 horas.',ts:'02/09 08:54'}], historico:[] },
  { id:4,  mes:'Set', nome:'Marta Sousa',     empresa:'Fotografia MS Studio',  telefone:'+351 916 777 888', segmento:'Fotografia',        status:'passado_humano',  atribuido:'04/09', ultimo_wa:'08/09', bant:{budget:true,authority:true,need:true,timeline:true},    notas:'Quer impressao fine art. Demo quinta/sexta.', conversa:[{de:'ai',msg:'Ola Marta! Estao a considerar impressao fine art de qualidade para os clientes?',ts:'05/09 11:00'},{de:'lead',msg:'Sim, temos muitos clientes a pedir isso.',ts:'05/09 11:10'},{de:'ai',msg:'A Carina vai apresentar-vos o Mimaki UJF — disponivel esta semana?',ts:'05/09 11:11'},{de:'lead',msg:'Sim, quinta ou sexta.',ts:'05/09 11:15'}], historico:[{data:'Mai 2025',campanha:'Mimaki UJF Fine Art',canal:'Meta Ads',interacao:'Clicou no anúncio (2×)',resultado:'Sem conversão'},{data:'Jan 2026',campanha:'Fotografia Pro — Q1',canal:'Email',interacao:'Email aberto (3×) — respondeu a pedir info',resultado:'Info enviada, sem seguimento'}] },
  { id:5,  mes:'Set', nome:'Carlos Dias',     empresa:'Digicolor Lda',         telefone:'+351 969 321 000', segmento:'Sinaletica',        status:'passado_humano',  atribuido:'05/09', ultimo_wa:'09/09', bant:{budget:true,authority:true,need:true,timeline:true},    notas:'Expansao de negocio. Volume 500m2/mes.', conversa:[{de:'ai',msg:'Carlos, estao a expandir o servico de sinaletica?',ts:'06/09 09:30'},{de:'lead',msg:'Exatamente, precisamos de aumentar capacidade.',ts:'06/09 09:35'},{de:'ai',msg:'Que volume mensal preveem?',ts:'06/09 09:36'},{de:'lead',msg:'Duplicar o atual, a volta de 500m2/mes.',ts:'06/09 09:40'},{de:'ai',msg:'A Carina vai mostrar a solucao ideal. Posso agendar para esta semana?',ts:'06/09 09:41'},{de:'lead',msg:'Sim, pode.',ts:'06/09 09:42'}], historico:[{data:'Out 2024',campanha:'Decal Sinalética — Outono',canal:'Meta Ads',interacao:'Clicou no anúncio',resultado:'Sem conversão'},{data:'Mar 2025',campanha:'Mimaki CJV — Gráficas',canal:'WhatsApp',interacao:'Contacto WA — não respondeu',resultado:'Sem resposta'},{data:'Jul 2026',campanha:'Biond Sinalética Verão',canal:'Meta Ads',interacao:'Clicou — preencheu formulário',resultado:'Lead gerado, sem seguimento'}] },
  { id:6,  mes:'Set', nome:'Sofia Pinto',     empresa:'Artes e Letras',        telefone:'+351 912 654 321', segmento:'Editorial',         status:'nao_qualificado', atribuido:'02/09', ultimo_wa:'04/09', bant:{budget:false,authority:true,need:true,timeline:false},   notas:'Sem budget aprovado. Pipeline 2027.', conversa:[{de:'ai',msg:'Ola Sofia, a vossa editora esta a considerar impressao digital de tiragens curtas?',ts:'03/09 14:00'},{de:'lead',msg:'E algo que queremos explorar sim.',ts:'03/09 14:20'},{de:'ai',msg:'Qual o orcamento disponivel para este ano?',ts:'03/09 14:21'},{de:'lead',msg:'Honestamente nao temos nada aprovado. E para o proximo ano.',ts:'03/09 14:30'},{de:'ai',msg:'Entendido, vamos retomar em Janeiro.',ts:'03/09 14:31'}], historico:[{data:'Set 2025',campanha:'Mimaki Print — Editorial',canal:'Meta Ads',interacao:'Clicou no anúncio',resultado:'Sem conversão'}] },
  { id:7,  mes:'Set', nome:'Jose Ferreira',   empresa:'Grafica Central',       telefone:'+351 966 123 456', segmento:'Impressao Digital', status:'nao_qualificado', atribuido:'03/09', ultimo_wa:'05/09', bant:{budget:true,authority:false,need:true,timeline:true},   notas:'Decisor e o socio, recusa contacto.', conversa:[{de:'ai',msg:'Bom dia Jose, e o responsavel pelas decisoes de equipamento?',ts:'04/09 10:00'},{de:'lead',msg:'Nao, isso e com o meu socio.',ts:'04/09 10:15'},{de:'ai',msg:'Pode passar-me o contacto dele?',ts:'04/09 10:16'},{de:'lead',msg:'Prefiro nao. Ele nao atende chamadas.',ts:'04/09 10:30'}], historico:[{data:'Jan 2025',campanha:'Decal Digital — Gráficas',canal:'Meta Ads',interacao:'Clicou no anúncio',resultado:'Sem conversão'},{data:'Mai 2026',campanha:'Mimaki Q2 — Impressão Digital',canal:'Email',interacao:'Email aberto — não respondeu',resultado:'Sem resposta'}] },
  { id:8,  mes:'Set', nome:'Luisa Rodrigues', empresa:'LR Comunicacao',        telefone:'+351 934 987 654', segmento:'Agencia',           status:'nao_qualificado', atribuido:'04/09', ultimo_wa:'06/09', bant:{budget:false,authority:true,need:false,timeline:false},  notas:'Sem necessidade atual. Externalizam tudo.', conversa:[{de:'ai',msg:'Ola Luisa, a vossa agencia gere producao grafica internamente?',ts:'05/09 09:00'},{de:'lead',msg:'Nao, externalizamos tudo.',ts:'05/09 09:20'},{de:'ai',msg:'Estao satisfeitos com os fornecedores atuais?',ts:'05/09 09:21'},{de:'lead',msg:'Sim, sem planos de mudar.',ts:'05/09 09:22'}], historico:[] },
  { id:9,  mes:'Set', nome:'Antonio Silva',   empresa:'TecPrint Solutions',    telefone:'+351 912 111 333', segmento:'Impressao Digital', status:'em_qualificacao',  atribuido:'06/09', ultimo_wa:'10/09', bant:{budget:null,authority:true,need:true,timeline:null},    notas:'A clarificar budget e timeline. Potencial alto.', conversa:[{de:'ai',msg:'Ola Antonio, tem interesse em solucoes de sublimacao textil?',ts:'07/09 11:00'},{de:'lead',msg:'Sim, estamos a avaliar entrar nesse mercado.',ts:'07/09 11:20'},{de:'ai',msg:'E em termos de orcamento, tem ja uma referencia?',ts:'07/09 14:01'}], historico:[{data:'Fev 2026',campanha:'Mimaki Tx300P — Têxtil',canal:'Meta Ads',interacao:'Clicou no anúncio — preencheu formulário',resultado:'Lead gerado (campanha anterior, não seguido'},{data:'Jun 2026',campanha:'Sublimação Q2',canal:'Email',interacao:'Email aberto (2×)',resultado:'Sem resposta'}] },
  { id:10, mes:'Set', nome:'Filipa Costa',    empresa:'VisuArt Lda',           telefone:'+351 963 222 111', segmento:'Decoracao',         status:'em_qualificacao',  atribuido:'07/09', ultimo_wa:'11/09', bant:{budget:null,authority:true,need:true,timeline:true},    notas:'Budget a confirmar com CFO. Resposta semana seguinte.', conversa:[{de:'ai',msg:'Filipa, estao a considerar impressao UV para paineis decorativos?',ts:'08/09 10:00'},{de:'lead',msg:'Sim, temos varios projectos de interiores.',ts:'08/09 10:30'},{de:'ai',msg:'O orcamento para equipamento ja esta aprovado?',ts:'08/09 10:31'},{de:'lead',msg:'Estou a tratar com o nosso CFO, respondo na proxima semana.',ts:'08/09 10:45'}], historico:[{data:'Nov 2025',campanha:'Mimaki UV — Decoração',canal:'Meta Ads',interacao:'Clicou no anúncio',resultado:'Sem conversão'},{data:'Abr 2026',campanha:'Interiores & Decoração Q2',canal:'Email',interacao:'Email aberto — link clicado',resultado:'Visitou landing page, sem conversão'}] },
  { id:11, mes:'Set', nome:'Miguel Alves',    empresa:'Packaging Pro',         telefone:'+351 936 555 777', segmento:'Embalagem',         status:'em_qualificacao',  atribuido:'08/09', ultimo_wa:'12/09', bant:{budget:true,authority:null,need:true,timeline:null},   notas:'A confirmar decisor e prazo. Budget confirmado.', conversa:[{de:'ai',msg:'Miguel, procuram solucoes para impressao de embalagens curtas?',ts:'09/09 09:00'},{de:'lead',msg:'Sim, e uma necessidade real.',ts:'09/09 09:25'},{de:'ai',msg:'Quem toma a decisao final na empresa?',ts:'09/09 09:31'},{de:'lead',msg:'Sou eu e o meu director geral.',ts:'09/09 09:35'}], historico:[{data:'Mar 2026',campanha:'Biond Embalagem — Q1',canal:'Meta Ads',interacao:'Clicou no anúncio — visitou site',resultado:'Sem conversão'}] },
  { id:12, mes:'Set', nome:'Beatriz Lopes',   empresa:'Studio B',              telefone:'+351 912 888 999', segmento:'Fotografia',        status:'contactado',       atribuido:'09/09', ultimo_wa:'10/09', bant:{budget:null,authority:null,need:null,timeline:null},     notas:'Primeiro contacto positivo. Aguarda seguimento.', conversa:[{de:'ai',msg:'Ola Beatriz! Vi o vosso portfolio. Estao a considerar impressao fine art para os clientes?',ts:'10/09 09:00'},{de:'lead',msg:'Ola! Sim pode contar mais.',ts:'10/09 10:30'}], historico:[] },
  { id:13, mes:'Set', nome:'Ricardo Nunes',   empresa:'Nunes Sign & Display',  telefone:'+351 966 444 888', segmento:'Sinaletica',        status:'contactado',       atribuido:'10/09', ultimo_wa:'11/09', bant:{budget:null,authority:null,need:null,timeline:null},     notas:'Quer conversa mais detalhada. Agendado proximo contacto.', conversa:[{de:'ai',msg:'Ricardo, bom dia! A Nunes Sign esta a expandir a capacidade de producao?',ts:'11/09 08:45'},{de:'lead',msg:'Pode ser. Quando posso falar com mais calma?',ts:'11/09 09:00'},{de:'ai',msg:'Diga quando e melhor para si!',ts:'11/09 09:01'}], historico:[{data:'Jun 2026',campanha:'Decal Sinalética — Verão',canal:'Meta Ads',interacao:'Clicou no anúncio',resultado:'Sem conversão'}] },
  { id:14, mes:'Set', nome:'Clara Mendes',    empresa:'Print & Go',            telefone:'+351 912 765 432', segmento:'Impressao Digital', status:'atribuido',        atribuido:'11/09', ultimo_wa:null,    bant:{budget:null,authority:null,need:null,timeline:null},     notas:'Atribuido. Primeiro contacto WA pendente.', conversa:[], historico:[] },
  { id:15, mes:'Set', nome:'Hugo Teixeira',   empresa:'ImageFactory',          telefone:'+351 963 111 222', segmento:'Fotografia',        status:'atribuido',        atribuido:'12/09', ultimo_wa:null,    bant:{budget:null,authority:null,need:null,timeline:null},     notas:'Atribuido. Primeiro contacto WA pendente.', conversa:[], historico:[] },
];

// ─── Mock data — SDR Humano leads (tipo: 'sdr' | 'prospect') ─────────────────
const SDR_HUMANO_LEADS = [
  // ── Set — SDR (tipo:'sdr') ──────────────────────────────────────────────────
  { id:101, mes:'Set', tipo:'sdr', nome:'Fernando Baptista',  empresa:'Gráfica Rápida Lda',      segmento:'Impressão Digital', status:'passado_humano',  ultimo_wa:'04/09' },
  { id:102, mes:'Set', tipo:'sdr', nome:'Inês Moreira',       empresa:'Print & Brand Studio',    segmento:'Design & Print',    status:'passado_humano',  ultimo_wa:'05/09' },
  { id:103, mes:'Set', tipo:'sdr', nome:'Gonçalo Azevedo',    empresa:'AzPrint Solutions',       segmento:'Impressão Digital', status:'passado_humano',  ultimo_wa:'03/09' },
  { id:104, mes:'Set', tipo:'sdr', nome:'Mariana Figueiredo', empresa:'Studio MF',               segmento:'Fotografia',        status:'passado_humano',  ultimo_wa:'07/09' },
  { id:105, mes:'Set', tipo:'sdr', nome:'Tiago Correia',      empresa:'Correia & Associados',    segmento:'Sinaletica',        status:'passado_humano',  ultimo_wa:'08/09' },
  { id:106, mes:'Set', tipo:'sdr', nome:'Vera Santos',        empresa:'VS Comunicação',          segmento:'Agencia',           status:'nao_qualificado', ultimo_wa:'05/09' },
  { id:107, mes:'Set', tipo:'sdr', nome:'Nuno Pacheco',       empresa:'Grafismundo',             segmento:'Impressão Digital', status:'nao_qualificado', ultimo_wa:'06/09' },
  { id:108, mes:'Set', tipo:'sdr', nome:'Catarina Lima',      empresa:'Lima & Partners',         segmento:'Editorial',         status:'nao_qualificado', ultimo_wa:'04/09' },
  { id:109, mes:'Set', tipo:'sdr', nome:'Diogo Mendes',       empresa:'ImageTech Lda',           segmento:'Fotografia',        status:'nao_qualificado', ultimo_wa:'07/09' },
  { id:110, mes:'Set', tipo:'sdr', nome:'Sara Oliveira',      empresa:'Oliva Print',             segmento:'Embalagem',         status:'em_qualificacao', ultimo_wa:'09/09' },
  { id:111, mes:'Set', tipo:'sdr', nome:'Paulo Neves',        empresa:'Neves Sign Lda',          segmento:'Sinaletica',        status:'em_qualificacao', ultimo_wa:'10/09' },
  { id:112, mes:'Set', tipo:'sdr', nome:'Ana Guerreiro',      empresa:'AGuerreiro Branding',     segmento:'Design & Print',    status:'em_qualificacao', ultimo_wa:'11/09' },
  { id:113, mes:'Set', tipo:'sdr', nome:'Bruno Cardoso',      empresa:'Cardoso Display',         segmento:'Sinaletica',        status:'em_qualificacao', ultimo_wa:'09/09' },
  { id:114, mes:'Set', tipo:'sdr', nome:'Lara Vieira',        empresa:'Vieira & Filhos',         segmento:'Impressão Digital', status:'em_qualificacao', ultimo_wa:'12/09' },
  { id:115, mes:'Set', tipo:'sdr', nome:'Ricardo Pires',      empresa:'PiresPrint',              segmento:'Impressão Digital', status:'em_qualificacao', ultimo_wa:'10/09' },
  { id:116, mes:'Set', tipo:'sdr', nome:'Susana Costa',       empresa:'SC Estúdio',              segmento:'Fotografia',        status:'contactado',       ultimo_wa:'11/09' },
  { id:117, mes:'Set', tipo:'sdr', nome:'Hélder Martins',     empresa:'HM Publicidade',          segmento:'Agencia',           status:'contactado',       ultimo_wa:'12/09' },
  { id:118, mes:'Set', tipo:'sdr', nome:'Filomena Ramos',     empresa:'Ramos & Ramos',           segmento:'Embalagem',         status:'contactado',       ultimo_wa:'11/09' },
  { id:119, mes:'Set', tipo:'sdr', nome:'Jorge Pereira',      empresa:'Pereira Gráfica',         segmento:'Impressão Digital', status:'contactado',       ultimo_wa:'13/09' },
  { id:120, mes:'Set', tipo:'sdr', nome:'Alice Moura',        empresa:'Moura Studio',            segmento:'Design & Print',    status:'contactado',       ultimo_wa:'12/09' },
  { id:121, mes:'Set', tipo:'sdr', nome:'Rui Ferreira',       empresa:'Ferreira & Print',        segmento:'Impressão Digital', status:'contactado',       ultimo_wa:'14/09' },
  { id:122, mes:'Set', tipo:'sdr', nome:'Madalena Cruz',      empresa:'Cruz Comunicação',        segmento:'Agencia',           status:'contactado',       ultimo_wa:'13/09' },
  { id:123, mes:'Set', tipo:'sdr', nome:'Afonso Tavares',     empresa:'Tavares Display',         segmento:'Sinaletica',        status:'contactado',       ultimo_wa:'14/09' },
  { id:124, mes:'Set', tipo:'sdr', nome:'Dora Antunes',       empresa:'DA Print Shop',           segmento:'Impressão Digital', status:'atribuido',        ultimo_wa:null },
  { id:125, mes:'Set', tipo:'sdr', nome:'Eduardo Reis',       empresa:'Reis & Gráfica',          segmento:'Impressão Digital', status:'atribuido',        ultimo_wa:null },
  { id:126, mes:'Set', tipo:'sdr', nome:'Fátima Sousa',       empresa:'Sousa Editora',           segmento:'Editorial',         status:'atribuido',        ultimo_wa:null },
  { id:127, mes:'Set', tipo:'sdr', nome:'Guilherme Luz',      empresa:'Luz e Cor Lda',           segmento:'Decoracao',         status:'atribuido',        ultimo_wa:null },
  { id:128, mes:'Set', tipo:'sdr', nome:'Helena Braga',       empresa:'Braga Sign',              segmento:'Sinaletica',        status:'atribuido',        ultimo_wa:null },
  // ── Set — Prospect (tipo:'prospect') ────────────────────────────────────────
  { id:201, mes:'Set', tipo:'prospect', nome:'Álvaro Melo',       empresa:'Melo & Associados',    segmento:'Impressão Digital', status:'passado_humano',  ultimo_wa:'05/09' },
  { id:202, mes:'Set', tipo:'prospect', nome:'Beatriz Cunha',      empresa:'BC Packaging',         segmento:'Embalagem',         status:'passado_humano',  ultimo_wa:'06/09' },
  { id:203, mes:'Set', tipo:'prospect', nome:'César Rodrigues',    empresa:'CésarPrint',           segmento:'Impressão Digital', status:'passado_humano',  ultimo_wa:'07/09' },
  { id:204, mes:'Set', tipo:'prospect', nome:'Diana Lemos',        empresa:'Lemos Brand Studio',   segmento:'Design & Print',    status:'nao_qualificado', ultimo_wa:'05/09' },
  { id:205, mes:'Set', tipo:'prospect', nome:'Estêvão Carvalho',   empresa:'EC Gráfica',           segmento:'Impressão Digital', status:'nao_qualificado', ultimo_wa:'06/09' },
  { id:206, mes:'Set', tipo:'prospect', nome:'Francisca Brito',    empresa:'Brito Publicidade',    segmento:'Agencia',           status:'nao_qualificado', ultimo_wa:'07/09' },
  { id:207, mes:'Set', tipo:'prospect', nome:'Gastão Pinto',       empresa:'GastãoSign',           segmento:'Sinaletica',        status:'em_qualificacao', ultimo_wa:'10/09' },
  { id:208, mes:'Set', tipo:'prospect', nome:'Hildegarda Nunes',   empresa:'HN Decoração',         segmento:'Decoracao',         status:'em_qualificacao', ultimo_wa:'11/09' },
  { id:209, mes:'Set', tipo:'prospect', nome:'Isidro Marques',     empresa:'Marques & Filhos',     segmento:'Impressão Digital', status:'em_qualificacao', ultimo_wa:'12/09' },
  { id:210, mes:'Set', tipo:'prospect', nome:'Joana Simões',       empresa:'JS Criativos',         segmento:'Design & Print',    status:'contactado',       ultimo_wa:'11/09' },
  { id:211, mes:'Set', tipo:'prospect', nome:'Kevin Araújo',       empresa:'KA Print',             segmento:'Impressão Digital', status:'contactado',       ultimo_wa:'12/09' },
  { id:212, mes:'Set', tipo:'prospect', nome:'Leonor Pais',        empresa:'LP Editorial',         segmento:'Editorial',         status:'contactado',       ultimo_wa:'11/09' },
  { id:213, mes:'Set', tipo:'prospect', nome:'Marcos Veiga',       empresa:'Veiga Sinalética',     segmento:'Sinaletica',        status:'contactado',       ultimo_wa:'13/09' },
  { id:214, mes:'Set', tipo:'prospect', nome:'Natasha Fontes',     empresa:'Fontes Studio',        segmento:'Fotografia',        status:'contactado',       ultimo_wa:'12/09' },
  { id:215, mes:'Set', tipo:'prospect', nome:'Olímpio Gomes',      empresa:'Gomes Gráfica',        segmento:'Impressão Digital', status:'contactado',       ultimo_wa:'14/09' },
  { id:216, mes:'Set', tipo:'prospect', nome:'Patrícia Esteves',   empresa:'PE Comunicação',       segmento:'Agencia',           status:'atribuido',        ultimo_wa:null },
  { id:217, mes:'Set', tipo:'prospect', nome:'Quirino Andrade',    empresa:'QA Display',           segmento:'Sinaletica',        status:'atribuido',        ultimo_wa:null },
  { id:218, mes:'Set', tipo:'prospect', nome:'Rosária Teles',      empresa:'RT Print & Pack',      segmento:'Embalagem',         status:'atribuido',        ultimo_wa:null },
];

// ─── Status config ────────────────────────────────────────────────────────────
const SDR_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:'BANT Completo',      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' },
};

// ─── Helpers ─────────────────────────────────────────────────────────────────

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

function sdrColor(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 sdrBg(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 SdrKpiTile = ({ label, value, sub, color }) => (
  <div style={{ flex:'1 1 140px', padding:'10px 18px', borderRadius:8, background:'var(--dgd-bg-card,white)', border:'1px solid var(--dgd-border-1)' }}>
    <div style={{ fontSize:10, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', letterSpacing:'0.08em', marginBottom:3 }}>{label}</div>
    <div className="font-display" style={{ fontSize:22, fontWeight:700, color:color||'var(--dgd-fg-1)', letterSpacing:'-0.02em', lineHeight:1.1 }}>{value}</div>
    <div style={{ fontSize:10.5, color:'var(--dgd-fg-3)', marginTop:4 }}>{sub}</div>
  </div>
);

const SdrSectionRow = ({ 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 ─────────────────────────────────────────────────────

const SdrLeadListModal = ({ title, leads, onClose }) => {
  return (
    <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 criterio neste mes.</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_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>
  );
};

// ─── SdrAIFunilTable e SdrLeadsPanel → movidos para screen_comercial_rpc_sdr_ai.jsx ─

const _SdrAIFunilTable_unused = ({ rows, onCellClick }) => {
  const mesIdx = (() => { const m = SDR_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 ytd = rows.reduce((s, r) => ({
    atribuidos:   s.atribuidos   + r.atribuidos,
    contactados:  s.contactados  + r.contactados,
    qualificados: s.qualificados + r.qualificados,
  }), { atribuidos:0, contactados:0, qualificados:0 });

  const tcYTD = sdrPct(ytd.contactados, ytd.atribuidos);
  const tqYTD = sdrPct(ytd.qualificados, ytd.contactados);

  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 cl = (metric, mes, val) => onCellClick ? { onClick: () => onCellClick(metric, mes, val) } : {};

  return (
    <div style={{ overflowX:'auto' }}>
      <table style={{ borderCollapse:'collapse', width:'100%', fontSize:12 }}>
        <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?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>
          <SdrSectionRow cols={nCols}>Funil de Prospecção — WhatsApp</SdrSectionRow>
          <tr>
            <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?700:400, ...(onCellClick?clickStyle:{}) }} {...cl('atribuidos', r.mes, r.atribuidos)}>{fv(r.atribuidos, i)}</td>)}
            <td style={{ ...tdBase, fontWeight:700, color:'var(--dgd-fg-1)' }}>{ytd.atribuidos}</td>
          </tr>
          <tr>
            <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?700:400, ...(onCellClick?clickStyle:{}) }} {...cl('contactados', r.mes, r.contactados)}>{fv(r.contactados, i)}</td>)}
            <td style={{ ...tdBase, fontWeight:700, color:'var(--dgd-fg-1)' }}>{ytd.contactados}</td>
          </tr>
          <tr>
            <td style={tdL}>Taxa de Contacto</td>
            <td style={{ ...tdBase, color:'#1d4ed8', fontWeight:600 }}>&gt;={SDR_METAS.taxa_contacto}%</td>
            {rows.map((r,i) => {
              const v = i > mesIdx ? null : sdrPct(r.contactados, r.atribuidos);
              return <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?700:400, color:sdrColor(v,SDR_METAS.taxa_contacto), background:i===mesIdx?sdrBg(v,SDR_METAS.taxa_contacto):'transparent' }}>{v === null ? '—' : `${v}%`}</td>;
            })}
            <td style={{ ...tdBase, fontWeight:700, color:sdrColor(tcYTD,SDR_METAS.taxa_contacto) }}>{tcYTD === null ? '—' : `${tcYTD}%`}</td>
          </tr>
          <tr>
            <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?700:400, ...(onCellClick?clickStyle:{}) }} {...cl('qualificados', r.mes, r.qualificados)}>{fv(r.qualificados, i)}</td>)}
            <td style={{ ...tdBase, fontWeight:700, color:'var(--dgd-fg-1)' }}>{ytd.qualificados}</td>
          </tr>
          <tr>
            <td style={tdL}>Taxa de Qualificação BANT</td>
            <td style={{ ...tdBase, color:'#1d4ed8', fontWeight:600 }}>&gt;={SDR_METAS.taxa_qualif}%</td>
            {rows.map((r,i) => {
              const v = i > mesIdx ? null : sdrPct(r.qualificados, r.contactados);
              return <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?700:400, color:sdrColor(v,SDR_METAS.taxa_qualif), background:i===mesIdx?sdrBg(v,SDR_METAS.taxa_qualif):'transparent' }}>{v === null ? '—' : `${v}%`}</td>;
            })}
            <td style={{ ...tdBase, fontWeight:700, color:sdrColor(tqYTD,SDR_METAS.taxa_qualif) }}>{tqYTD === null ? '—' : `${tqYTD}%`}</td>
          </tr>
          <tr>
            <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.contactados - r.qualificados;
              return <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?700:400, color:'#991b1b', ...(onCellClick?clickStyle:{}) }} {...cl('nao_qualificados', r.mes, v)}>{v}</td>;
            })}
            <td style={{ ...tdBase, fontWeight:700, color:'#991b1b' }}>{ytd.contactados - ytd.qualificados}</td>
          </tr>
        </tbody>
      </table>
    </div>
  );
};

// ─── SdrLeadsPanel → movido para screen_comercial_rpc_sdr_ai.jsx ─────────────

const _SdrLeadsPanel_unused = ({ initialStatus, initialMes, allLeads = [], selAno, sdrList = [] }) => {
  const [search,      setSearch]      = React.useState('');
  const [filterSt,    setFilterSt]    = React.useState(initialStatus || 'all');
  const [filterMes,   setFilterMes]   = React.useState(initialMes || SDR_MESES[new Date().getMonth()]);
  const [expandedId,  setExpandedId]  = React.useState(null);
  const [leadTab,     setLeadTab]     = React.useState('info');
  const [passando,    setPassando]    = React.useState(null);  // visitor_id a passar
  const [selSdrPass, setSelSdrPass]   = React.useState('');
  const [passOk,     setPassOk]       = React.useState({});   // { visitor_id: true } após sucesso

  React.useEffect(() => {
    const currentMes = SDR_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('');
    }
  };

  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' },
    { 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_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>
                  </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' }}>
                          ✕
                        </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:'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</div>
                          {[['Budget','budget'],['Authority','authority'],['Need','need'],['Timeline','timeline']].map(([label,key]) => (
                            <div key={key} style={{ display:'flex', alignItems:'center', gap:10, marginBottom:6, fontSize:12 }}>
                              <span style={{ color:'var(--dgd-fg-2)', minWidth:72 }}>{label}</span>
                              <BantIcon ok={lead.bant?.[key]} />
                            </div>
                          ))}
                        </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>
  );
};

// ─── Mock data — SDR Humano Daily Prospect ───────────────────────────────────
const SDR_HUMANO_DAILY = [
  { id:301, tipo:'bant_completo', nome:'Fernando Baptista',  telefone:'+351 912 301 001', empresa:'Gráfica Rápida Lda',   segmento:'Impressão Digital', origem:'Inbound',  campanha:null,                        atribuido:'08/10 09:15', ultima_act:'08/10 10:30', bant:{budget:true,  authority:true,  need:true,  timeline:true},  notas:'Budget 45k aprovado. Quer demo esta semana. Referiu que equipamento actual tem 7 anos.',
    conversa:[
      { de:'ai', msg:'Bom dia Fernando! Recebi o vosso contacto pelo site. Trabalham com impressão de grande formato?', ts:'09:16' },
      { de:'lead', msg:'Sim, temos uma HP Latex mas está a dar problemas. Queremos renovar.', ts:'09:18' },
      { de:'ai', msg:'Entendo. Que volume mensal produzem aproximadamente?', ts:'09:18' },
      { de:'lead', msg:'Umas 800 folhas A0 por mês. Maioritariamente banners e vinil.', ts:'09:20' },
      { de:'ai', msg:'Têm orçamento aprovado para este investimento?', ts:'09:21' },
      { de:'lead', msg:'Sim, 40-50k. O sócio já aprovou. Queremos fechar antes do fim do ano.', ts:'09:22' },
      { de:'ai', msg:'Perfeito Fernando, vou passar para a nossa equipa técnica para marcar uma demo. Pode ser esta semana?', ts:'09:23' },
      { de:'lead', msg:'Quinta ou sexta de manhã.', ts:'09:25' },
    ],
  },
  { id:302, tipo:'bant_completo', nome:'Inês Moreira',       telefone:'+351 966 302 002', empresa:'Print & Brand Studio', segmento:'Design & Print',    origem:'Outbound', campanha:'Mimaki JV300 — Outono PT',  atribuido:'07/10 14:20', ultima_act:'08/10 09:45', bant:{budget:true,  authority:true,  need:true,  timeline:true},  notas:'Expansão de negócio. Timeline Q4 2026. Já conhece Mimaki da concorrência.',
    conversa:[
      { de:'ai', msg:'Boa tarde Inês, somos da Digidelta. Vi que a Print & Brand trabalha com impressão de grande formato — temos uma campanha especial para a JV300 este outono.', ts:'14:21' },
      { de:'lead', msg:'Sim? O que tem de especial?', ts:'14:35' },
      { de:'ai', msg:'Financiamento em 36 meses com taxa reduzida e formação técnica incluída. Está a considerar renovar equipamento?', ts:'14:36' },
      { de:'lead', msg:'Estamos sim. Temos duas máquinas a precisar de substituição em Q4.', ts:'14:40' },
      { de:'ai', msg:'Sou eu a decisora, confirmo. Budget aprovado pela gestão para fim de ano.', ts:'14:42' },
    ],
  },
  { id:303, tipo:'bant_completo', nome:'Tiago Correia',      telefone:'+351 933 303 003', empresa:'Correia & Associados', segmento:'Sinaletica',        origem:'Inbound',  campanha:null,                        atribuido:'08/10 08:00', ultima_act:'08/10 09:10', bant:{budget:true,  authority:true,  need:true,  timeline:true},  notas:'Equipa nova de sinalética. Decisão até fim do mês. Pediu proposta formal.',
    conversa:[
      { de:'ai', msg:'Bom dia Tiago! Recebemos o vosso pedido de informação sobre equipamento de corte e impressão para sinalética.', ts:'08:01' },
      { de:'lead', msg:'Sim, montámos uma divisão nova de sinalética e precisamos de equipar. Somos 3 pessoas na equipa.', ts:'08:05' },
      { de:'ai', msg:'Qual o volume previsto de produção mensal?', ts:'08:06' },
      { de:'lead', msg:'Começamos com umas 200-300 peças/mês. Queremos crescer rápido.', ts:'08:08' },
      { de:'ai', msg:'Têm budget aprovado e prazo para a decisão?', ts:'08:09' },
      { de:'lead', msg:'Budget aprovado pelo conselho, até 35k. Precisamos de começar em Novembro.', ts:'08:10' },
    ],
  },
  { id:304, tipo:'sem_contacto',  nome:'Gonçalo Azevedo',    telefone:'+351 912 304 004', empresa:'AzPrint Solutions',    segmento:'Impressão Digital', origem:'Inbound',  campanha:null,                        atribuido:'08/10 08:30', ultima_act:'08/10 08:35', bant:{budget:null,  authority:null,  need:null,  timeline:null},  notas:'3 tentativas AI. Número válido confirmado pelo site. Melhor janela: manhã 9h-11h.',
    conversa:[
      { de:'ai', msg:'Bom dia! Tentei contactar via WhatsApp — está disponível?', ts:'08:31' },
      { de:'ai', msg:'Gonçalo, volto a tentar. Recebemos o vosso pedido de informação.', ts:'08:33' },
      { de:'ai', msg:'Última tentativa por hoje. Fico disponível para resposta sempre que quiser.', ts:'08:35' },
    ],
  },
  { id:305, tipo:'sem_contacto',  nome:'Mariana Figueiredo', telefone:'+351 966 305 005', empresa:'Studio MF',            segmento:'Fotografia',        origem:'Outbound', campanha:'Decal Sinalética — Outono', atribuido:'07/10 16:00', ultima_act:'07/10 16:05', bant:{budget:null,  authority:null,  need:null,  timeline:null},  notas:'Fora do horário. Perfil LinkedIn activo — fotógrafa e proprietária. Tentar manhã 09h-11h.',
    conversa:[
      { de:'ai', msg:'Boa tarde Mariana! Contactamos estúdios fotográficos sobre soluções de impressão de qualidade fotográfica. Tem 2 minutos?', ts:'16:01' },
      { de:'ai', msg:'Ficamos disponíveis para resposta quando for mais conveniente.', ts:'16:05' },
    ],
  },
  { id:306, tipo:'sem_resposta',  nome:'Vera Santos',        telefone:'+351 933 306 006', empresa:'VS Comunicação',       segmento:'Agencia',           origem:'Inbound',  campanha:null,                        atribuido:'08/10 10:15', ultima_act:'08/10 10:20', bant:{budget:null,  authority:null,  need:true,  timeline:null},  notas:'Confirmou necessidade de impressão grande formato. Depois silêncio. Pode estar em reuniões.',
    conversa:[
      { de:'ai', msg:'Bom dia Vera! Recebemos o vosso contacto — trabalham com produção de materiais de comunicação?', ts:'10:16' },
      { de:'lead', msg:'Sim, somos uma agência. Precisamos de impressão de qualidade para campanhas.', ts:'10:17' },
      { de:'ai', msg:'Que tipo de materiais produzem principalmente — banners, expositores, lonas?', ts:'10:18' },
      { de:'ai', msg:'Vera, ainda está disponível?', ts:'10:20' },
    ],
  },
  { id:307, tipo:'sem_resposta',  nome:'Ricardo Nunes',      telefone:'+351 912 307 007', empresa:'Nunes Sign & Display', segmento:'Sinaletica',        origem:'Outbound', campanha:'Mimaki JV300 — Outono PT',  atribuido:'08/10 09:00', ultima_act:'08/10 09:08', bant:{budget:null,  authority:true,  need:null,  timeline:null},  notas:'Confirmou que é o decisor. Depois deixou de responder. Possível distracção.',
    conversa:[
      { de:'ai', msg:'Bom dia Ricardo! Temos uma proposta especial de outono para a Mimaki JV300 — linha de topos de gama wide format.', ts:'09:01' },
      { de:'lead', msg:'Sim, sou eu que decido. O que tem?', ts:'09:04' },
      { de:'ai', msg:'Financiamento 36 meses, formação e garantia alargada. Produzem quanto por mês actualmente?', ts:'09:05' },
      { de:'ai', msg:'Ricardo? Pode continuar?', ts:'09:08' },
    ],
  },
  { id:308, tipo:'parada',        nome:'Sara Oliveira',      telefone:'+351 966 308 008', empresa:'Oliva Print',          segmento:'Embalagem',         origem:'Outbound', campanha:'Biond Embalagem Q4',        atribuido:'06/10 11:00', ultima_act:'06/10 14:30', bant:{budget:null,  authority:true,  need:true,  timeline:null},  notas:'Need e authority confirmados. Budget e timeline pendentes. Disse que volta depois de falar com financeiro.',
    conversa:[
      { de:'ai', msg:'Boa tarde Sara! Contactamos sobre soluções de impressão de embalagem sustentável Biond.', ts:'11:01' },
      { de:'lead', msg:'Interessante. Trabalho com embalagem alimentar. Que especificações têm?', ts:'11:15' },
      { de:'ai', msg:'Certificação FSC, conformidade REACH, impressão variável para short-runs. Têm equipamento actual?', ts:'11:16' },
      { de:'lead', msg:'Temos mas é antigo. Sou eu a responsável pela decisão de compra, sim.', ts:'11:30' },
      { de:'ai', msg:'Têm budget previsto para este ano?', ts:'11:31' },
      { de:'lead', msg:'Preciso de confirmar com o financeiro. Falo consigo mais tarde.', ts:'14:28' },
      { de:'ai', msg:'Claro Sara, fico à espera. Posso tentar de novo amanhã de manhã?', ts:'14:30' },
    ],
  },
  { id:309, tipo:'parada',        nome:'Paulo Neves',        telefone:'+351 933 309 009', empresa:'Neves Sign Lda',       segmento:'Sinaletica',        origem:'Inbound',  campanha:null,                        atribuido:'05/10 09:00', ultima_act:'06/10 10:00', bant:{budget:true,  authority:true,  need:true,  timeline:null},  notas:'BANT quase completo — só falta timeline. CFO em reuniões toda a semana. Retomar segunda-feira.',
    conversa:[
      { de:'ai', msg:'Bom dia Paulo! Recebemos o vosso interesse em equipamento de sinalética.', ts:'09:01' },
      { de:'lead', msg:'Sim, precisamos de uma máquina nova. Somos uma empresa familiar, sou o sócio-gerente.', ts:'09:10' },
      { de:'ai', msg:'Budget disponível para este investimento?', ts:'09:11' },
      { de:'lead', msg:'Sim, aprovado. Entre 30-40k.', ts:'09:15' },
      { de:'ai', msg:'E quando pretendem tomar a decisão?', ts:'09:16' },
      { de:'lead', msg:'O meu CFO está em reuniões esta semana toda. Ligo-vos na segunda.', ts:'09:20' },
      { de:'ai', msg:'Perfeito Paulo! Fico à espera. Posso enviar a proposta por email?', ts:'09:21' },
      { de:'lead', msg:'Pode, paulo.neves@nevessign.pt', ts:'10:00' },
    ],
  },
];

// ─── Mock data — Prospects em Campanha ───────────────────────────────────────
// IDs reais da BD prospeccao.empresas
const SDR_PROSPECTS_CAMPANHA = [
  { id:79,  empresa:'Sign - Wide Format Printing',                   segmento:'SignGraphics',     localidade:'Maia',         campanha:'Mimaki JV300 — Outono PT',  estado:'novo' },
  { id:87,  empresa:'Workstation — Soluções Gráficas',               segmento:'SignGraphics',     localidade:'Porto',        campanha:'Mimaki JV300 — Outono PT',  estado:'contactado' },
  { id:88,  empresa:'Orgal Impressores',                             segmento:'SignGraphics',     localidade:'Porto',        campanha:'Mimaki JV300 — Outono PT',  estado:'novo' },
  { id:84,  empresa:'Anassisgraf | Soluções Digitais p/ Artes Gráf', segmento:'SignGraphics',     localidade:'—',            campanha:'Decal Sinalética — Outono', estado:'novo' },
  { id:82,  empresa:'L2, S.A.',                                      segmento:'Impressão Digital',localidade:'Sintra',       campanha:'Decal Sinalética — Outono', estado:'contactado' },
  { id:76,  empresa:'The Navigator Company',                         segmento:'Embalagem',        localidade:'Lisboa',       campanha:'Biond Embalagem Q4',        estado:'novo' },
];

// ─── BANT dots ────────────────────────────────────────────────────────────────
const SdrBantDots = ({ bant }) => {
  const fields = [['B','budget'],['A','authority'],['N','need'],['T','timeline']];
  return (
    <div style={{ display:'flex', gap:3 }}>
      {fields.map(([label, key]) => {
        const v      = bant[key];
        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 key={key} 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>
  );
};

// ─── Modal Lead AI (Daily Prospect) ──────────────────────────────────────────
const SDR_GRUPO_CFG = {
  bant_completo:   { label:'BANT Completo',    color:'#166534', bg:'#f0fdf4', border:'#bbf7d0', acao:'Agendar Demo' },
  em_qualificacao: { label:'Em Qualificação',  color:'#0369a1', bg:'#f0f9ff', border:'#bae6fd', acao:'Continuar' },
  excluido:        { label:'Excluído',         color:'#94a3b8', bg:'#f1f5f9', border:'#e2e8f0', acao:'Excluído' },
  arquivada:       { label:'Arquivada',        color:'#78716c', bg:'#fafaf9', border:'#d6d3d1', acao:'Arquivada' },
  sem_contacto:    { label:'Sem Contacto',     color:'#92400e', bg:'#fffbeb', border:'#fde68a', acao:'Contactar Agora' },
  sem_resposta:    { label:'Sem Resposta',     color:'#1d4ed8', bg:'#eff6ff', border:'#bfdbfe', acao:'Retomar Contacto' },
  parada:          { label:'Parada',           color:'#64748b', bg:'#f1f5f9', border:'#cbd5e1', acao:'Desbloquear' },
};

// ─── Briefing estruturado — blocos do Marketing ───────────────────────────────
// ─── Tab Notas Troubleshooting (dentro do modal BANT) ─────────────────────────
const SdrTroubleshootingTab = ({ prospectId, empresaNome, campanha, contactoNome, user, bantNotas }) => {
  const [notes, setNotes]                 = React.useState([]);
  const [loading, setLoading]             = React.useState(true);
  const [cat, setCat]                     = React.useState('chamada');
  const [texto, setTexto]                 = React.useState('');
  const [saving, setSaving]               = React.useState(false);
  const [transcricaoModal, setTranscricaoModal] = React.useState(null); // { text, header } | null
  const [transcricaoLoading, setTranscricaoLoading] = React.useState(false);

  const verTranscricao = async (header) => {
    if (!prospectId) return;
    setTranscricaoLoading(true);
    setTranscricaoModal({ text: null, header });
    try {
      const r = await fetch(`/api/comercial/sdr/chamada/historico?prospect_id=${encodeURIComponent(prospectId)}`, { credentials: 'include' });
      const lista = await r.json();
      const m = header.match(/(\d{2})\/(\d{2}),?\s+(\d{2}):(\d{2})/);
      let melhor = null;
      if (m && Array.isArray(lista)) {
        const ano = new Date().getFullYear();
        const alvo = new Date(ano, parseInt(m[2]) - 1, parseInt(m[1]), parseInt(m[3]), parseInt(m[4])).getTime();
        let menorDiff = Infinity;
        for (const c of lista) {
          const diff = Math.abs(new Date(c.created_at).getTime() - alvo);
          if (diff < menorDiff) { menorDiff = diff; melhor = c; }
        }
      } else if (Array.isArray(lista) && lista.length > 0) {
        melhor = lista[0];
      }
      setTranscricaoModal({ text: melhor?.transcricao || '', header });
    } catch (_) {
      setTranscricaoModal({ text: '', header });
    } finally {
      setTranscricaoLoading(false);
    }
  };

  const load = React.useCallback(() => {
    fetch('/api/comercial/sdr/troubleshooting?empresa_nome=' + encodeURIComponent(empresaNome || ''), { credentials:'include' })
      .then(r => r.ok ? r.json() : [])
      .then(notes => setNotes(notes))
      .catch(() => {})
      .finally(() => setLoading(false));
  }, [empresaNome]);

  React.useEffect(load, [load]);

  // Parse bantNotas para extrair blocos [CHAMADA AI ...] individuais
  const chamadaBlocks = React.useMemo(() => {
    if (!bantNotas) return [];
    const blocks = bantNotas.split(/(?=\[CHAMADA AI)/).filter(b => b.trim());
    return blocks.map(b => b.trim());
  }, [bantNotas]);

  const handleSave = async () => {
    if (!texto.trim()) return;
    setSaving(true);
    try {
      const r = await fetch('/api/comercial/sdr/troubleshooting', {
        method:'POST', credentials:'include',
        headers:{ 'Content-Type':'application/json' },
        body: JSON.stringify({ prospect_id: String(prospectId), empresa_nome: empresaNome, campanha, categoria: cat, nota: texto, contacto_nome: contactoNome || null }),
      });
      const d = await r.json();
      if (r.ok) { setNotes(prev => [d, ...prev]); setTexto(''); }
    } catch (e) {}
    setSaving(false);
  };

  const catCfg = {
    chamada: { label:'Chamada', color:'#1d4ed8', bg:'#eff6ff', border:'#bfdbfe' },
    sistema: { label:'Sistema', color:'#92400e', bg:'#fffbeb', border:'#fde68a' },
    dados:   { label:'Dados',   color:'#166534', bg:'#f0fdf4', border:'#bbf7d0' },
    outro:   { label:'Outro',   color:'#64748b', bg:'#f1f5f9', border:'#e2e8f0' },
  };

  return (
    <div>
      <div style={{ fontSize:10.5, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', letterSpacing:'0.06em', textTransform:'uppercase', marginBottom:10, fontWeight:600 }}>Nova Nota</div>
      <div style={{ display:'flex', gap:4, marginBottom:8 }}>
        {Object.entries(catCfg).map(([k, c]) => (
          <button key={k} onClick={() => setCat(k)} style={{ padding:'3px 10px', borderRadius:99, border:'1.5px solid', fontSize:11, fontWeight:cat===k?700:400, cursor:'pointer', background:cat===k?c.bg:'transparent', color:cat===k?c.color:'var(--dgd-fg-3)', borderColor:cat===k?c.border:'var(--dgd-border-1)' }}>{c.label}</button>
        ))}
      </div>
      <textarea value={texto} onChange={e => setTexto(e.target.value)} placeholder="Descreve o problema: o que aconteceu, passos para reproduzir, erro que apareceu..." rows={3}
        style={{ width:'100%', boxSizing:'border-box', padding:'8px 10px', fontSize:12.5, border:'1px solid var(--dgd-border-1)', borderRadius:6, resize:'vertical', fontFamily:'var(--dgd-font-body,sans-serif)', color:'var(--dgd-fg-1)', background:'var(--dgd-bg-surface,#fff)', outline:'none' }} />
      <div style={{ display:'flex', justifyContent:'flex-end', marginTop:6 }}>
        <button onClick={handleSave} disabled={saving || !texto.trim()} style={{ padding:'5px 16px', borderRadius:6, border:'none', background:'#112954', color:'#fff', fontSize:12, fontWeight:600, cursor: saving?'not-allowed':'pointer', opacity: !texto.trim()?0.5:1 }}>
          {saving ? 'A enviar...' : 'Enviar Nota'}
        </button>
      </div>

      {loading && <div style={{ padding:20, textAlign:'center', color:'var(--dgd-fg-3)', fontSize:12 }}>A carregar...</div>}
      {chamadaBlocks.length > 0 && (
        <div style={{ marginTop:16 }}>
          <div style={{ fontSize:10.5, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', letterSpacing:'0.06em', textTransform:'uppercase', marginBottom:8, fontWeight:600 }}>Resumos de Chamadas AI</div>
          {chamadaBlocks.map((blk, i) => {
            const header = blk.match(/\[CHAMADA AI[^\]]*\]/)?.[0] || '';
            const body = blk.replace(header, '').trim();
            return (
              <div key={i} style={{ padding:'10px 12px', border:'1px solid var(--dgd-border-1)', borderRadius:8, marginBottom:6, background:'var(--dgd-bg,#f8fafc)' }}>
                <div style={{ display:'flex', alignItems:'center', gap:6, marginBottom:6 }}>
                  <span style={{ fontSize:10, padding:'1px 7px', borderRadius:99, background:'#eff6ff', color:'#1d4ed8', border:'1px solid #bfdbfe', fontWeight:600 }}>Chamada AI</span>
                  <span style={{ fontSize:10.5, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)' }}>{header.replace(/\[CHAMADA AI ·? ?/,'').replace('\]','')}</span>
                  <button onClick={() => verTranscricao(header)} style={{ marginLeft:'auto', fontSize:10.5, padding:'2px 8px', borderRadius:5, border:'1px solid #bfdbfe', background:'#eff6ff', color:'#1d4ed8', cursor:'pointer' }}>Ver transcrição</button>
                </div>
                <div style={{ fontSize:12, color:'var(--dgd-fg-2)', lineHeight:1.6, whiteSpace:'pre-wrap' }}>{body}</div>
              </div>
            );
          })}
        </div>
      )}
      {!loading && notes.length > 0 && (
        <div style={{ marginTop:16 }}>
          <div style={{ fontSize:10.5, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', letterSpacing:'0.06em', textTransform:'uppercase', marginBottom:8, fontWeight:600 }}>Notas Anteriores</div>
          {notes.map(n => {
            const cc = catCfg[n.categoria] || catCfg.outro;
            return (
              <div key={n.id} style={{ padding:'10px 12px', border:'1px solid var(--dgd-border-1)', borderRadius:8, marginBottom:6, background: n.resolvido ? '#f0fdf4' : 'transparent' }}>
                <div style={{ display:'flex', alignItems:'center', gap:6, marginBottom:4, flexWrap:'wrap' }}>
                  <span style={{ fontSize:10, padding:'1px 7px', borderRadius:99, background:cc.bg, color:cc.color, border:'1px solid '+cc.border, fontWeight:600 }}>{cc.label}</span>
                  <span style={{ fontSize:10.5, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)' }}>{new Date(n.created_at).toLocaleString('pt-PT', { day:'2-digit', month:'2-digit', hour:'2-digit', minute:'2-digit' })}</span>
                  {n.contacto_nome && <span style={{ fontSize:10.5, fontWeight:600, color:'var(--dgd-fg-2)' }}>{n.contacto_nome}</span>}
                  {(n.sdr_nome || n.sdr_email) && <span style={{ fontSize:10.5, color:'var(--dgd-fg-3)' }}>· {n.sdr_nome || n.sdr_email}</span>}
                  {n.resolvido && <span style={{ fontSize:10, color:'#166534', fontWeight:600 }}>RESOLVIDO</span>}
                </div>
                <div style={{ fontSize:12.5, color:'var(--dgd-fg-1)', lineHeight:1.5, whiteSpace:'pre-wrap' }}>{n.nota}</div>
              </div>
            );
          })}
        </div>
      )}
      {!loading && notes.length === 0 && (
        <div style={{ padding:20, textAlign:'center', color:'var(--dgd-fg-3)', fontSize:12, marginTop:12 }}>Sem notas para esta empresa.</div>
      )}

      {transcricaoModal && (
        <div style={{ position:'fixed', inset:0, zIndex:9999, background:'rgba(0,0,0,0.5)', display:'flex', alignItems:'center', justifyContent:'center' }} onClick={() => setTranscricaoModal(null)}>
          <div style={{ background:'#fff', borderRadius:12, padding:24, width:'min(700px,95vw)', maxHeight:'80vh', overflowY:'auto', boxShadow:'0 8px 32px rgba(0,0,0,0.18)' }} onClick={e => e.stopPropagation()}>
            <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:16 }}>
              <span style={{ fontWeight:700, fontSize:13 }}>Transcrição · {transcricaoModal.header.replace(/\[CHAMADA AI ·? ?/,'').replace(']','')}</span>
              <button onClick={() => setTranscricaoModal(null)} style={{ border:'none', background:'none', cursor:'pointer', fontSize:20, color:'var(--dgd-fg-3)', lineHeight:1 }}>×</button>
            </div>
            {transcricaoLoading ? (
              <div style={{ textAlign:'center', color:'var(--dgd-fg-3)', fontSize:12, padding:20 }}>A carregar...</div>
            ) : transcricaoModal.text ? (
              <pre style={{ fontFamily:'var(--dgd-font-mono,monospace)', fontSize:11.5, lineHeight:1.7, whiteSpace:'pre-wrap', color:'var(--dgd-fg-1)', margin:0 }}>{transcricaoModal.text}</pre>
            ) : (
              <div style={{ textAlign:'center', color:'var(--dgd-fg-3)', fontSize:12, padding:20 }}>Transcrição não disponível para esta chamada.</div>
            )}
          </div>
        </div>
      )}
    </div>
  );
};

const SdrBriefingBlocks = ({ campanhaId, fallbackMd }) => {
  const [data,    setData]    = React.useState(null);
  const [loading, setLoading] = React.useState(true);
  const [error,   setError]   = React.useState(null);

  React.useEffect(function() {
    if (!campanhaId) { setLoading(false); return; }
    fetch('/api/comercial/sdr/campanha-briefing/' + campanhaId, { credentials:'include' })
      .then(function(r) { return r.ok ? r.json() : Promise.reject(r.status); })
      .then(function(d) { setData(d); })
      .catch(function() { setError(true); })
      .finally(function() { setLoading(false); });
  }, [campanhaId]);

  if (loading) return <div style={{ padding:'24px 0', textAlign:'center', color:'var(--dgd-fg-3)', fontSize:12 }}>A carregar briefing...</div>;
  if (error || (!data && fallbackMd)) return <SdrFichaMdRenderer md={fallbackMd} />;
  if (!data) return <div style={{ padding:'24px 0', textAlign:'center', color:'var(--dgd-fg-3)', fontSize:12 }}>Ficha de campanha não disponível.</div>;

  const bCard = (title, children) => (
    <div style={{ background:'var(--dgd-bg-card,white)', border:'1px solid var(--dgd-border-1)', borderRadius:8, overflow:'hidden', marginBottom:10 }}>
      <div style={{ padding:'6px 14px', borderBottom:'1px solid var(--dgd-border-1)', background:'var(--dgd-bg,#f8fafc)' }}>
        <div style={{ fontSize:10.5, fontWeight:700, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', letterSpacing:'0.07em', textTransform:'uppercase' }}>{title}</div>
      </div>
      <div style={{ padding:'10px 14px' }}>{children}</div>
    </div>
  );

  const field = (label, value) => {
    if (!value || (Array.isArray(value) && !value.length)) return null;
    const isArr = Array.isArray(value);
    const toStr = function(v) {
      if (typeof v === 'string') return v;
      if (v && typeof v === 'object') return Object.values(v).filter(Boolean).join(' — ');
      return String(v || '');
    };
    return (
      <div style={{ marginBottom:10 }}>
        <div style={{ fontSize:10, fontWeight:700, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', letterSpacing:'0.06em', textTransform:'uppercase', marginBottom:4 }}>{label}</div>
        {isArr ? (
          <div style={{ display:'flex', flexDirection:'column', gap:3 }}>
            {value.filter(Boolean).map(function(v,i) {
              return <div key={i} style={{ display:'flex', gap:6, fontSize:12.5, color:'var(--dgd-fg-1)' }}><span style={{ color:'var(--dgd-fg-3)', flexShrink:0 }}>·</span><span>{toStr(v)}</span></div>;
            })}
          </div>
        ) : (
          <div style={{ fontSize:12.5, color:'var(--dgd-fg-1)', lineHeight:1.6, whiteSpace:'pre-wrap' }}>{toStr(value)}</div>
        )}
      </div>
    );
  };

  const fmt = function(d) { return d ? new Date(d).toLocaleDateString('pt-PT', { day:'2-digit', month:'short', year:'numeric' }) : null; };

  return (
    <div style={{ maxHeight:440, overflowY:'auto' }}>
      {/* Header meta */}
      <div style={{ display:'flex', flexWrap:'wrap', gap:6, marginBottom:10, padding:'8px 12px', background:'var(--dgd-bg,#f8fafc)', border:'1px solid var(--dgd-border-1)', borderRadius:8, alignItems:'center' }}>
        {data.marca_name && <span style={{ fontSize:11, padding:'2px 9px', borderRadius:99, background:'#eff6ff', color:'#1d4ed8', border:'1px solid #bfdbfe', fontWeight:600 }}>{data.marca_name}</span>}
        {data.commercial_name && <span style={{ fontSize:11, padding:'2px 9px', borderRadius:99, background:'#f0fdf4', color:'#166534', border:'1px solid #bbf7d0', fontWeight:500 }}>{data.commercial_name}</span>}
        {(data.timeline_start || data.timeline_end) && <span style={{ fontSize:11, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)' }}>{[fmt(data.timeline_start), fmt(data.timeline_end)].filter(Boolean).join(' → ')}</span>}
      </div>

      {/* Bloco Produto */}
      {bCard('Produto', <>
        {field('Elevator Pitch', data.elevator_pitch)}
        {field('Oferta Activa', data.commercial_offer)}
        {field('USPs', data.usps)}
        {field('Aplicações', data.applications)}
        {field('Certificações', data.certifications)}
      </>)}

      {/* Bloco Cliente-alvo */}
      {bCard('Cliente-alvo', <>
        {field('Decisor', data.decision_maker)}
        {field('Utilizador Final', data.end_user)}
        {field('Dores / Pain Points', data.pain_points)}
        {field('Motivadores', data.motivators)}
        {field('Objecções Comuns', data.objections)}
        {field('Trigger de Compra', data.purchase_trigger)}
      </>)}

      {/* Bloco Campanha */}
      {bCard('Campanha', <>
        {field('Mensagem-Chave', data.key_message)}
        {field('Objectivo', data.objective)}
        {field('Percepção Desejada', data.desired_perception)}
        {field('Tom', data.tone)}
        {field('KPIs', data.kpis)}
        {data.typeform_url && <div style={{ marginBottom:10 }}><div style={{ fontSize:10, fontWeight:700, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', letterSpacing:'0.06em', textTransform:'uppercase', marginBottom:4 }}>Typeform</div><div style={{ fontSize:12.5, color:'#1d4ed8' }}>{data.typeform_url}</div></div>}
      </>)}

      {/* Bloco Mercado */}
      {bCard('Mercado', <>
        {field('Concorrentes', data.competitors)}
        {field('Argumentos Diferenciadores', data.differentiation_args)}
        {field('Tendências de Mercado', data.market_trends)}
        {field('Narrativa de Posicionamento', data.positioning_narrative)}
      </>)}

      {/* Bloco Restrições (só se tiver conteúdo) */}
      {(data.prohibited_claims || data.off_brand_messages || (data.competitors_not_name?.length) || data.other_restrictions) && bCard('Restrições', <>
        {field('Claims Proibidos', data.prohibited_claims)}
        {field('Mensagens Off-brand', data.off_brand_messages)}
        {field('Concorrentes a Não Nomear', data.competitors_not_name)}
        {field('Outras Restrições', data.other_restrictions)}
      </>)}
    </div>
  );
};

// ─── Renderer de ficha MD por blocos ──────────────────────────────────────────
const SdrFichaMdRenderer = ({ md }) => {
  if (!md) return <div style={{ padding:'24px 0', textAlign:'center', color:'var(--dgd-fg-3)', fontSize:12 }}>Ficha de campanha não disponível.</div>;
  function renderInline(text) {
    const parts = text.split(/\*\*([^*]+)\*\*/g);
    return parts.map(function(p, i) {
      return i % 2 === 1 ? React.createElement('strong', { key:i, style:{ fontWeight:700 } }, p) : p;
    });
  }

  // Parse header meta lines (before first heading)
  function parseMeta(lines) {
    const meta = {};
    lines.forEach(function(l) {
      const mMarca = l.match(/^Marca:\s*(.+?)\s*·\s*Produto:\s*(.+?)\s*·\s*Mercados:\s*(.+?)\s*·\s*Vigência:\s*(.+)$/);
      if (mMarca) { meta.marca=mMarca[1]; meta.produto=mMarca[2]; meta.mercados=mMarca[3]; meta.vigencia=mMarca[4]; return; }
      const mVer = l.match(/^Versão da ficha:\s*(.+)/);
      if (mVer) { meta.versao = mVer[1]; return; }
    });
    return meta;
  }

  const lines = md.split('\n');
  // Split into sections by any heading
  const sections = [];
  let cur = { title: null, level: 0, lines: [] };
  lines.forEach(function(line) {
    const hm = line.match(/^(#{1,4})\s+(.*)/);
    if (hm) {
      if (cur.lines.length || cur.title !== null) sections.push(cur);
      cur = { title: hm[2].trim(), level: hm[1].length, lines: [] };
    } else {
      cur.lines.push(line);
    }
  });
  if (cur.lines.length || cur.title !== null) sections.push(cur);

  return (
    <div style={{ display:'flex', flexDirection:'column', gap:10 }}>
      {sections.map(function(sec, si) {
        const nonEmpty = sec.lines.filter(function(l) { return l.trim(); });
        if (sec.title === null) {
          // Header meta block
          const meta = parseMeta(nonEmpty);
          if (!Object.keys(meta).length) return null;
          return (
            <div key={si} style={{ display:'flex', flexWrap:'wrap', gap:6, padding:'10px 14px', background:'var(--dgd-bg,#f8fafc)', border:'1px solid var(--dgd-border-1)', borderRadius:8 }}>
              {meta.marca    && <span style={{ fontSize:11, padding:'2px 9px', borderRadius:99, background:'#eff6ff', color:'#1d4ed8', border:'1px solid #bfdbfe', fontWeight:600 }}>{meta.marca}</span>}
              {meta.produto  && <span style={{ fontSize:11, padding:'2px 9px', borderRadius:99, background:'#f0fdf4', color:'#166534', border:'1px solid #bbf7d0', fontWeight:500 }}>{meta.produto}</span>}
              {meta.mercados && <span style={{ fontSize:11, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)' }}>Mercados: {meta.mercados}</span>}
              {meta.vigencia && <span style={{ fontSize:11, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)' }}>Vigência: {meta.vigencia}</span>}
              {meta.versao   && <span style={{ fontSize:10.5, color:'var(--dgd-fg-3)', marginLeft:'auto' }}>{meta.versao}</span>}
            </div>
          );
        }
        if (!nonEmpty.length) return null;
        return (
          <div key={si} style={{ background:'var(--dgd-bg-card,white)', border:'1px solid var(--dgd-border-1)', borderRadius:8, overflow:'hidden' }}>
            <div style={{ padding:'6px 14px', borderBottom:'1px solid var(--dgd-border-1)', background:'var(--dgd-bg,#f8fafc)' }}>
              <div style={{ fontSize:10.5, fontWeight:700, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', letterSpacing:'0.07em', textTransform:'uppercase' }}>{sec.title}</div>
            </div>
            <div style={{ padding:'10px 14px', display:'flex', flexDirection:'column', gap:4 }}>
              {nonEmpty.map(function(line, li) {
                if (/^>\s/.test(line)) return (
                  <div key={li} style={{ borderLeft:'3px solid #93c5fd', paddingLeft:10, color:'#1d4ed8', fontSize:12.5, fontStyle:'italic', lineHeight:1.6 }}>{renderInline(line.replace(/^>\s/,''))}</div>
                );
                if (/^[\-·•]\s/.test(line)) return (
                  <div key={li} style={{ paddingLeft:12, fontSize:12.5, color:'var(--dgd-fg-1)', display:'flex', gap:6, lineHeight:1.55 }}>
                    <span style={{ color:'var(--dgd-fg-3)', flexShrink:0, marginTop:1 }}>·</span>
                    <span>{renderInline(line.replace(/^[\-·•]\s/,''))}</span>
                  </div>
                );
                return <div key={li} style={{ fontSize:12.5, color:'var(--dgd-fg-1)', lineHeight:1.6 }}>{renderInline(line)}</div>;
              })}
            </div>
          </div>
        );
      })}
    </div>
  );
};

// ─── Opp Detail Modal (Oportunidades Criadas) ─────────────────────────────────
const SdrOppDetailModal = ({ lead, onClose, user, getOppEstado, handleToggleOppEstado, handleRestaurar }) => {
  const [tab,       setTab]       = React.useState('info');
  const [newNota,   setNewNota]   = React.useState('');
  const [notesList, setNotesList] = React.useState([]);
  const [notaSave,  setNotaSave]  = React.useState('idle');
  const [fmOppId,    setFmOppId]    = React.useState(lead.fm_opp_id || '');
  const [fmSave,     setFmSave]     = React.useState('idle');
  const [fmLookup,   setFmLookup]   = React.useState('idle'); // idle|loading|done|error
  const [fmOps,      setFmOps]      = React.useState([]);
  const [fmManual,   setFmManual]   = React.useState(false);
  const [recState,  setRecState]  = React.useState('idle');
  const [recErr,    setRecErr]    = React.useState('');
  const [aiConversa, setAiConversa] = React.useState(null); // null=não carregado, []=carregado
  const mediaRef  = React.useRef(null);
  const chunksRef = React.useRef([]);

  // carrega conversa heydigi se origem=sdr-ai
  React.useEffect(() => {
    if (lead.origem !== 'sdr-ai' || !lead.telefone) return;
    fetch(`/api/comercial/sdr/ai-conversa?telefone=${encodeURIComponent(lead.telefone)}`, { credentials:'include' })
      .then(r => r.json()).catch(() => [])
      .then(d => { if (Array.isArray(d)) setAiConversa(d); });
  }, [lead.id]);

  // carrega notas ao abrir
  React.useEffect(() => {
    fetch(`/api/comercial/sdr/lead-notes/${lead.id}`, { credentials:'include' })
      .then(r => r.json()).catch(() => [])
      .then(d => { if (Array.isArray(d)) setNotesList(d); });
  }, [lead.id]);

  const handleSaveNota = () => {
    if (!newNota.trim()) return;
    setNotaSave('saving');
    fetch('/api/comercial/sdr/lead-notes', {
      method:'POST', credentials:'include',
      headers:{ 'Content-Type':'application/json' },
      body: JSON.stringify({ lead_id: lead.id, nota: newNota.trim() }),
    }).then(r => r.json()).then(n => {
      setNotesList(p => [n, ...p]);
      setNewNota('');
      setNotaSave('saved');
      setTimeout(() => setNotaSave('idle'), 2000);
    }).catch(() => setNotaSave('error'));
  };

  const handleSaveFm = () => {
    setFmSave('saving');
    fetch('/api/comercial/sdr/lead-fm-link', {
      method:'POST', credentials:'include',
      headers:{ 'Content-Type':'application/json' },
      body: JSON.stringify({ lead_id: lead.id, fm_opp_id: fmOppId.trim() || null }),
    }).then(r => r.json()).then(() => {
      setFmSave('saved');
      setTimeout(() => setFmSave('idle'), 2000);
    }).catch(() => setFmSave('error'));
  };

  const handleFmLookup = async () => {
    setFmLookup('loading');
    setFmOps([]);
    const tenant = lead.tenant || 'PT';
    let url = `/api/comercial/sdr/fm-opp-lookup?empresa=${encodeURIComponent(lead.empresa)}&tenant=${tenant}`;
    if (lead.nif) url += `&nif=${encodeURIComponent(lead.nif)}`;
    const data = await fetch(url, { credentials:'include' }).then(r => r.json()).catch(() => null);
    if (!data) { setFmLookup('error'); return; }
    setFmOps(data);
    setFmLookup('done');
  };

  const handleSelectFmOp = (op) => {
    setFmOppId(op.id_oportunidade);
    setFmSave('saving');
    fetch('/api/comercial/sdr/lead-fm-link', {
      method:'POST', credentials:'include',
      headers:{ 'Content-Type':'application/json' },
      body: JSON.stringify({ lead_id: lead.id, fm_opp_id: op.id_oportunidade }),
    }).then(r => r.json()).then(() => {
      setFmSave('saved');
      setTimeout(() => setFmSave('idle'), 2000);
    }).catch(() => setFmSave('error'));
  };

  const startRec = async () => {
    setRecErr('');
    try {
      const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
      const mr = new MediaRecorder(stream);
      chunksRef.current = [];
      mr.ondataavailable = e => { if (e.data.size > 0) chunksRef.current.push(e.data); };
      mr.onstop = async () => {
        setRecState('transcribing');
        stream.getTracks().forEach(t => t.stop());
        const blob = new Blob(chunksRef.current, { type:'audio/webm' });
        const fd = new FormData(); fd.append('audio', blob, 'nota.webm');
        try {
          const r = await fetch('/api/comercial/crm/transcribe', { method:'POST', credentials:'include', body:fd });
          const d = await r.json();
          if (d.nota_limpa) setNewNota(d.nota_limpa);
          else if (d.text) setNewNota(p => p ? `${p}\n${d.text}` : d.text);
        } catch { setRecErr('Erro na transcrição'); }
        setRecState('idle');
      };
      mr.start();
      mediaRef.current = mr;
      setRecState('recording');
    } catch { setRecErr('Sem acesso ao microfone'); }
  };
  const stopRec = () => { if (mediaRef.current?.state === 'recording') mediaRef.current.stop(); };

  const bant = lead.bant || {};
  const bantItems = [
    { k:'Budget',    v: bant.budget },
    { k:'Authority', v: bant.authority },
    { k:'Need',      v: bant.need },
    { k:'Timeline',  v: bant.timeline },
  ];
  const acao   = lead.acao;
  const isDemo = acao === 'agendar_demo';
  const oppEst = getOppEstado(lead);
  const fmStatus = fmOppId.trim() ? 'sincronizado' : (lead.fm_status || 'pendente');

  const TABS = [['info','Info'],['conversa','Conversa WA'],['notas','Notas SDR'],['fm','FM Sync']];
  const tabBtn = (t) => ({
    padding:'10px 16px', border:'none', borderBottom: tab===t ? '2px solid #112954' : '2px solid transparent',
    background:'transparent', fontSize:12.5, fontWeight: tab===t ? 700 : 400,
    color: tab===t ? '#112954' : 'var(--dgd-fg-2)', cursor:'pointer', whiteSpace:'nowrap',
  });

  return ReactDOM.createPortal(
    <div onClick={onClose}
      style={{ position:'fixed', inset:0, background:'rgba(0,0,0,.45)', zIndex:9000, display:'flex', alignItems:'center', justifyContent:'center', padding:16 }}>
      <div onClick={e => e.stopPropagation()}
        style={{ background:'white', borderRadius:12, width:'100%', maxWidth:580, maxHeight:'88vh', display:'flex', flexDirection:'column', boxShadow:'0 20px 60px rgba(0,0,0,.25)', overflow:'hidden' }}>

        {/* Header */}
        <div style={{ padding:'16px 20px 0', borderBottom:'1px solid var(--dgd-border-1)', flexShrink:0 }}>
          <div style={{ display:'flex', alignItems:'flex-start', justifyContent:'space-between', marginBottom:12 }}>
            <div>
              <div style={{ fontWeight:700, fontSize:16, color:'var(--dgd-fg-1)' }}>{lead.nome}</div>
              <div style={{ fontSize:12, color:'var(--dgd-fg-3)', marginTop:2 }}>{lead.empresa} · {lead.telefone || '—'}</div>
            </div>
            <div style={{ display:'flex', alignItems:'center', gap:8, flexShrink:0 }}>
              <span style={{ fontSize:10.5, padding:'3px 10px', borderRadius:99, fontWeight:600,
                background: isDemo ? '#f0fdf4' : '#eff6ff',
                color:      isDemo ? '#166534' : '#1d4ed8',
                border:     `1px solid ${isDemo ? '#bbf7d0' : '#bfdbfe'}` }}>
                {isDemo ? 'Qualificado para Demo' : 'Passado ao Comercial'}
              </span>
              {fmStatus === 'sincronizado' && (
                <span style={{ fontSize:10, padding:'2px 8px', borderRadius:99, fontWeight:600, background:'#f0fdf4', color:'#166534', border:'1px solid #bbf7d0' }}>FM ✓</span>
              )}
            </div>
          </div>
          {/* Tabs */}
          <div style={{ display:'flex', gap:0 }}>
            {TABS.map(([t,l]) => <button key={t} style={tabBtn(t)} onClick={() => setTab(t)}>{l}</button>)}
          </div>
        </div>

        {/* Body */}
        <div style={{ flex:1, overflowY:'auto', padding:20 }}>

          {/* ── Tab: Info ── */}
          {tab === 'info' && (
            <div style={{ display:'flex', flexDirection:'column', gap:16 }}>
              {/* BANT */}
              <div>
                <div style={{ fontSize:10, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', letterSpacing:'0.08em', marginBottom:8, fontWeight:600 }}>BANT</div>
                <div style={{ display:'flex', gap:6, flexWrap:'wrap' }}>
                  {bantItems.map(b => (
                    <span key={b.k} style={{ fontSize:11, padding:'3px 11px', borderRadius:99, fontWeight:600,
                      background: b.v===true ? '#f0fdf4' : b.v===false ? '#fef2f2' : '#f1f5f9',
                      color:      b.v===true ? '#166534' : b.v===false ? '#991b1b' : '#64748b',
                      border:     `1px solid ${b.v===true ? '#bbf7d0' : b.v===false ? '#fecaca' : '#e2e8f0'}` }}>
                      {b.k}: {b.v===true ? '✓' : b.v===false ? '✗' : '—'}
                    </span>
                  ))}
                </div>
              </div>
              {/* Info grid */}
              <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:'10px 20px' }}>
                {[
                  { l:'NIF', v: lead.nif || '—' },
                  { l:'Data Demo', v: lead.data_demo || '—' },
                  { l:'Segmento', v: lead.segmento || '—' },
                  { l:'Origem', v: lead.origem || '—' },
                  { l:'Campanha', v: lead.campanha || '—' },
                  { l:'Atribuído', v: lead.atribuido || '—' },
                  { l:'Passada em', v: lead.ultima_act || '—' },
                  { l:'Telefone', v: lead.telefone || '—' },
                ].map(row => (
                  <div key={row.l}>
                    <div style={{ fontSize:10, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', letterSpacing:'0.06em', marginBottom:3, fontWeight:600, textTransform:'uppercase' }}>{row.l}</div>
                    <div style={{ fontSize:13, color:'var(--dgd-fg-1)', fontWeight:500 }}>{row.v}</div>
                  </div>
                ))}
              </div>
              {/* Estado + Restaurar */}
              <div style={{ display:'flex', alignItems:'center', gap:12, paddingTop:12, borderTop:'1px solid var(--dgd-border-1)' }}>
                <span style={{ fontSize:11, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', fontWeight:600 }}>ESTADO OPP</span>
                {(() => {
                  const aberto = oppEst === 'aberto';
                  return (
                    <button onClick={() => handleToggleOppEstado(lead.id)}
                      style={{ padding:'3px 12px', borderRadius:99, fontWeight:600, fontSize:11, cursor:'pointer', border:`1px solid ${aberto?'#bbf7d0':'#e2e8f0'}`, background:aberto?'#f0fdf4':'#f8fafc', color:aberto?'#166534':'#64748b' }}>
                      {aberto ? 'Aberto' : 'Por Abrir'}
                    </button>
                  );
                })()}
              </div>
            </div>
          )}

          {/* ── Tab: Conversa WA ── */}
          {tab === 'conversa' && (
            <div>
              {(() => {
                const msgs = aiConversa !== null ? aiConversa : (lead.conversa || []);
                if (aiConversa === null && lead.origem === 'sdr-ai') return (
                  <div style={{ textAlign:'center', color:'var(--dgd-fg-3)', fontSize:13, padding:'32px 0' }}>A carregar...</div>
                );
                if (msgs.length === 0) return (
                  <div style={{ textAlign:'center', color:'var(--dgd-fg-3)', fontSize:13, padding:'32px 0' }}>Sem conversa registada.</div>
                );
                return (
                <div style={{ display:'flex', flexDirection:'column', gap:8 }}>
                  {msgs.map((msg, i) => (
                    <div key={i} style={{ display:'flex', flexDirection:'column', alignItems: msg.de==='ai' ? 'flex-start' : 'flex-end' }}>
                      <div style={{ maxWidth:'80%', 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.5, 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)', padding:'0 4px' }}>
                        {msg.de==='ai' ? 'digi.ai' : lead.nome} · {msg.ts}
                      </div>
                    </div>
                  ))}
                </div>
                );
              })()}
            </div>
          )}

          {/* ── Tab: Notas SDR ── */}
          {tab === 'notas' && (
            <div>
              <div style={{ marginBottom:16, padding:'12px 14px', background:'var(--dgd-bg,#f8fafc)', border:'1px solid var(--dgd-border-1)', borderRadius:8 }}>
                <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:8 }}>
                  <div style={{ fontSize:10.5, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', letterSpacing:'0.06em', textTransform:'uppercase', fontWeight:600 }}>Nova Nota</div>
                  <div style={{ display:'flex', alignItems:'center', gap:6 }}>
                    {recState === 'transcribing' && <span style={{ fontSize:11, color:'var(--dgd-fg-3)' }}>A transcrever...</span>}
                    {recErr && <span style={{ fontSize:11, color:'#dc2626' }}>{recErr}</span>}
                    <button onClick={recState==='recording' ? stopRec : startRec} disabled={recState==='transcribing'}
                      style={{ display:'flex', alignItems:'center', gap:5, padding:'4px 10px', borderRadius:6, border:'1px solid', fontSize:11, fontWeight:600, cursor:recState==='transcribing'?'not-allowed':'pointer', background:recState==='recording'?'#fee2e2':'transparent', borderColor:recState==='recording'?'#fca5a5':'var(--dgd-border-1)', color:recState==='recording'?'#dc2626':'var(--dgd-fg-2)' }}>
                      {recState==='recording'
                        ? <><span style={{ width:7,height:7,borderRadius:'50%',background:'#dc2626',animation:'pulse 1s infinite',flexShrink:0 }} />Parar</>
                        : <><svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/><line x1="12" y1="19" x2="12" y2="23"/><line x1="8" y1="23" x2="16" y2="23"/></svg>Gravar áudio</>}
                    </button>
                  </div>
                </div>
                <textarea value={newNota} onChange={e => setNewNota(e.target.value)} disabled={recState!=='idle'}
                  placeholder="O que aconteceu? Próximos passos, objeções, combinado..."
                  rows={4}
                  style={{ width:'100%', boxSizing:'border-box', padding:'8px 10px', fontSize:12.5, border:'1px solid var(--dgd-border-1)', borderRadius:6, resize:'vertical', fontFamily:'var(--dgd-font-body,sans-serif)', color:'var(--dgd-fg-1)', background:recState!=='idle'?'var(--dgd-bg,#f8fafc)':'white', outline:'none', marginBottom:8 }} />
                <div style={{ display:'flex', justifyContent:'flex-end' }}>
                  <button onClick={handleSaveNota} disabled={!newNota.trim() || notaSave==='saving'}
                    style={{ padding:'7px 16px', borderRadius:6, border:'none', fontSize:12.5, fontWeight:600, cursor:(!newNota.trim()||notaSave==='saving')?'not-allowed':'pointer', background:notaSave==='saved'?'#16a34a':(!newNota.trim()?'var(--dgd-border-1)':'#112954'), color:(!newNota.trim()&&notaSave!=='saved')?'var(--dgd-fg-3)':'#fff' }}>
                    {notaSave==='saved'?'✓ Guardado':notaSave==='saving'?'A guardar...':'Guardar nota'}
                  </button>
                </div>
              </div>
              {notesList.length === 0 ? (
                <div style={{ textAlign:'center', color:'var(--dgd-fg-3)', fontSize:12.5, padding:'24px 0' }}>Ainda sem notas guardadas para este lead.</div>
              ) : (
                <div>
                  <div style={{ fontSize:10.5, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', letterSpacing:'0.06em', textTransform:'uppercase', fontWeight:600, marginBottom:10 }}>Histórico de Notas ({notesList.length})</div>
                  {notesList.map(n => (
                    <div key={n.id} style={{ marginBottom:8, padding:'10px 14px', background:'white', border:'1px solid var(--dgd-border-1)', borderRadius:6 }}>
                      <div style={{ fontSize:10.5, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', marginBottom:5, display:'flex', alignItems:'center', gap:8 }}>
                        <span>{new Date(n.created_at).toLocaleDateString('pt-PT',{day:'2-digit',month:'2-digit',year:'numeric'})} {new Date(n.created_at).toLocaleTimeString('pt-PT',{hour:'2-digit',minute:'2-digit'})}</span>
                        <span style={{ color:'var(--dgd-border-1)' }}>·</span>
                        <span>{n.sdr_nome || n.sdr_email}</span>
                      </div>
                      <div style={{ fontSize:12.5, color:'var(--dgd-fg-1)', lineHeight:1.6, whiteSpace:'pre-wrap' }}>{n.nota}</div>
                    </div>
                  ))}
                </div>
              )}
            </div>
          )}

          {/* ── Tab: FM Sync ── */}
          {tab === 'fm' && (
            <div style={{ display:'flex', flexDirection:'column', gap:16 }}>
              {/* Status badge */}
              <div style={{ display:'flex', alignItems:'center', gap:10 }}>
                <span style={{ fontSize:10, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', fontWeight:600, letterSpacing:'0.08em' }}>ESTADO FM</span>
                <span style={{ fontSize:11, padding:'2px 10px', borderRadius:99, fontWeight:600,
                  background: fmStatus==='sincronizado' ? '#f0fdf4' : '#fffbeb',
                  color:      fmStatus==='sincronizado' ? '#166534' : '#92400e',
                  border:     `1px solid ${fmStatus==='sincronizado' ? '#bbf7d0' : '#fde68a'}` }}>
                  {fmStatus==='sincronizado' ? '✓ Sincronizado' : 'Pendente FM'}
                </span>
              </div>
              {/* Dados para FM */}
              <div style={{ padding:'12px 14px', background:'var(--dgd-bg,#f8fafc)', border:'1px solid var(--dgd-border-1)', borderRadius:8 }}>
                <div style={{ fontSize:10, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', fontWeight:600, letterSpacing:'0.08em', marginBottom:10, textTransform:'uppercase' }}>Dados para o Gestor</div>
                {[
                  ['Contacto', lead.nome],
                  ['Empresa', lead.empresa],
                  ['NIF', lead.nif || '— (preencher no Gestor)'],
                  ['Telefone', lead.telefone || '—'],
                  ['Segmento', lead.segmento || '—'],
                  ['Campanha', lead.campanha || '—'],
                  ['Tipo', isDemo ? 'Qualificado para Demo' : 'Passado ao Comercial'],
                ].map(([k,v]) => (
                  <div key={k} style={{ display:'flex', gap:12, marginBottom:6, fontSize:12.5 }}>
                    <span style={{ color:'var(--dgd-fg-3)', minWidth:90, flexShrink:0, fontFamily:'var(--dgd-font-mono,monospace)', fontSize:10, fontWeight:600, textTransform:'uppercase', letterSpacing:'0.04em', paddingTop:2 }}>{k}</span>
                    <span style={{ color:'var(--dgd-fg-1)' }}>{v}</span>
                  </div>
                ))}
              </div>
              {/* Lookup no Gestor */}
              <div>
                <div style={{ fontSize:10, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', fontWeight:600, letterSpacing:'0.08em', marginBottom:8, textTransform:'uppercase' }}>Oportunidades Recentes no Gestor (7 dias)</div>
                {fmLookup === 'idle' && (
                  <button onClick={handleFmLookup}
                    style={{ padding:'8px 16px', borderRadius:6, border:'none', fontSize:12.5, fontWeight:600, cursor:'pointer', background:'#112954', color:'white' }}>
                    Procurar no Gestor
                  </button>
                )}
                {fmLookup === 'loading' && (
                  <div style={{ fontSize:12, color:'var(--dgd-fg-3)', padding:'8px 0' }}>A consultar o Gestor...</div>
                )}
                {fmLookup === 'error' && (
                  <div style={{ fontSize:12, color:'#991b1b', padding:'8px 0' }}>Erro ao contactar o Gestor. Tenta novamente ou usa o ID manual.</div>
                )}
                {fmLookup === 'done' && fmOps.length === 0 && (
                  <div style={{ fontSize:12, color:'var(--dgd-fg-3)', padding:'8px 0' }}>
                    Nenhuma OP encontrada para <strong>{lead.empresa}</strong> nos últimos 7 dias.
                    <button onClick={() => setFmManual(true)} style={{ marginLeft:8, fontSize:12, color:'#1d4ed8', background:'none', border:'none', cursor:'pointer', textDecoration:'underline' }}>Inserir ID manualmente</button>
                  </div>
                )}
                {fmLookup === 'done' && fmOps.length > 0 && (
                  <div style={{ border:'1px solid var(--dgd-border-1)', borderRadius:8, overflow:'hidden' }}>
                    {fmOps.map((op, i) => (
                      <div key={op.id_oportunidade} onClick={() => handleSelectFmOp(op)}
                        style={{ display:'flex', alignItems:'center', gap:12, padding:'10px 14px', cursor:'pointer', borderBottom: i < fmOps.length-1 ? '1px solid var(--dgd-border-1)' : 'none',
                          background: fmOppId === op.id_oportunidade ? 'color-mix(in oklch,#112954 6%,transparent)' : 'white' }}>
                        <div style={{ flex:1 }}>
                          <div style={{ fontSize:12.5, fontWeight:600, color:'var(--dgd-fg-1)' }}>{op.produto_name || '—'}</div>
                          <div style={{ fontSize:11, color:'var(--dgd-fg-3)', marginTop:2, fontFamily:'var(--dgd-font-mono,monospace)' }}>
                            {op.stage_name} · {op.produto_valor_k || '—'} · {op.start_date}
                          </div>
                        </div>
                        {fmOppId === op.id_oportunidade
                          ? <span style={{ fontSize:11, color:'#166534', fontWeight:700 }}>{fmSave==='saved'?'✓ Guardado':'✓ Seleccionado'}</span>
                          : <span style={{ fontSize:11, color:'#1d4ed8' }}>Seleccionar</span>
                        }
                      </div>
                    ))}
                    <div style={{ padding:'8px 14px', borderTop:'1px solid var(--dgd-border-1)', background:'var(--dgd-bg,#f8fafc)' }}>
                      <button onClick={() => setFmManual(v => !v)} style={{ fontSize:11, color:'var(--dgd-fg-3)', background:'none', border:'none', cursor:'pointer', textDecoration:'underline' }}>
                        Não é nenhuma destas? Inserir ID manualmente
                      </button>
                    </div>
                  </div>
                )}
              </div>
              {/* Manual fallback */}
              {(fmManual || (fmLookup === 'idle' && fmOppId)) && (
                <div>
                  <div style={{ fontSize:10, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', fontWeight:600, letterSpacing:'0.08em', marginBottom:6, textTransform:'uppercase' }}>ID Oportunidade (manual)</div>
                  <div style={{ display:'flex', gap:8 }}>
                    <input type="text" value={fmOppId} onChange={e => setFmOppId(e.target.value)}
                      placeholder="Cola o ID da oportunidade FM aqui"
                      style={{ flex:1, padding:'8px 12px', fontSize:12.5, border:'1px solid var(--dgd-border-1)', borderRadius:6, fontFamily:'var(--dgd-font-mono,monospace)', outline:'none', color:'var(--dgd-fg-1)' }} />
                    <button onClick={handleSaveFm} disabled={fmSave==='saving'}
                      style={{ padding:'8px 14px', borderRadius:6, border:'none', fontSize:12.5, fontWeight:600, cursor:fmSave==='saving'?'not-allowed':'pointer', background:fmSave==='saved'?'#16a34a':'#112954', color:'white', whiteSpace:'nowrap' }}>
                      {fmSave==='saved'?'✓ Guardado':fmSave==='saving'?'...':'Guardar'}
                    </button>
                  </div>
                </div>
              )}
            </div>
          )}
        </div>

        {/* Footer */}
        <div style={{ padding:'10px 20px', borderTop:'1px solid var(--dgd-border-1)', flexShrink:0, display:'flex', justifyContent:'space-between', alignItems:'center' }}>
          <button onClick={() => { if (window.confirm(`Restaurar ${lead.nome} para Daily Qualification?`)) handleRestaurar(lead.id); }}
            style={{ padding:'7px 14px', borderRadius:6, border:'1px solid #fde68a', background:'#fffbeb', color:'#92400e', fontSize:12, cursor:'pointer', fontWeight:500 }}>
            Restaurar para Qualification
          </button>
          <button onClick={onClose}
            style={{ padding:'7px 16px', borderRadius:6, border:'1px solid var(--dgd-border-1)', background:'white', color:'var(--dgd-fg-2)', fontSize:12, cursor:'pointer' }}>
            Fechar
          </button>
        </div>
      </div>
    </div>,
    document.body
  );
};

const SdrLeadAiModal = ({ lead, onClose, user, onSaved, onArquivar }) => {
  const [newNota, setNewNota]     = React.useState('');
  const [notesList, setNotesList] = React.useState([]);
  const [notaSave, setNotaSave]   = React.useState('idle'); // idle | saving | saved | error
  const [nifCliente, setNif]      = React.useState('');
  const [dataDemo, setDataDemo]   = React.useState('');
  const [distritol, setDistritol] = React.useState('');
  const [cpPostall, setCpl]       = React.useState('');
  const [localidadel, setLocall]  = React.useState('');
  const [concelhol, setConcelhl]  = React.useState('');
  const [bantSdr, setBantSdr]     = React.useState({
    budget:    lead.bant.budget    === true ? true : null,
    authority: lead.bant.authority === true ? true : null,
    need:      lead.bant.need      === true ? true : null,
    timeline:  lead.bant.timeline  === true ? true : null,
  });
  const [saveState, setSave]      = React.useState('idle');
  const [saveErr, setSaveErr]     = React.useState('');
  const [tab, setTab]             = React.useState('info');
  const [recState, setRec]        = React.useState('idle');
  const [recErr, setRecErr]       = React.useState('');
  const [aiConversa, setAiConversa] = React.useState(null);
  const [transcricaoNota, setTranscricaoNota] = React.useState(null); // { text, ts } | null
  const [transcricaoNotaLoading, setTranscricaoNotaLoading] = React.useState(false);
  const mediaRef  = React.useRef(null);
  const chunksRef = React.useRef([]);

  const verTranscricaoNota = async (notaText) => {
    const m = notaText.match(/\[CHAMADA AI[^\]]*(\d{2})\/(\d{2}),?\s+(\d{2}):(\d{2})/);
    setTranscricaoNotaLoading(true);
    setTranscricaoNota({ text: null, ts: m ? `${m[1]}/${m[2]}, ${m[3]}:${m[4]}` : '' });
    try {
      const r = await fetch(`/api/comercial/sdr/chamada/historico?prospect_id=${encodeURIComponent(lead.id)}`, { credentials: 'include' });
      const lista = await r.json();
      let melhor = null;
      if (m && Array.isArray(lista)) {
        const ano = new Date().getFullYear();
        const alvo = new Date(ano, parseInt(m[2]) - 1, parseInt(m[1]), parseInt(m[3]), parseInt(m[4])).getTime();
        let menorDiff = Infinity;
        for (const c of lista) {
          const diff = Math.abs(new Date(c.created_at).getTime() - alvo);
          if (diff < menorDiff) { menorDiff = diff; melhor = c; }
        }
      } else if (Array.isArray(lista) && lista.length > 0) { melhor = lista[0]; }
      setTranscricaoNota({ text: melhor?.transcricao || '', ts: m ? `${m[1]}/${m[2]}, ${m[3]}:${m[4]}` : '' });
    } catch (_) {
      setTranscricaoNota({ text: '', ts: '' });
    } finally { setTranscricaoNotaLoading(false); }
  };

  React.useEffect(() => {
    if (lead.origem !== 'sdr-ai' || !lead.telefone) return;
    fetch(`/api/comercial/sdr/ai-conversa?telefone=${encodeURIComponent(lead.telefone)}`, { credentials:'include' })
      .then(r => r.json()).catch(() => [])
      .then(d => { if (Array.isArray(d)) setAiConversa(d); });
  }, [lead.id]);

  // Grupo efectivo calculado em tempo real a partir do bantSdr
  const allSdrTrue  = bantSdr.budget === true && bantSdr.authority === true && bantSdr.need === true && bantSdr.timeline === true;
  const bantGe2     = Object.values(bantSdr).filter(v => v === true).length >= 2;
  const anyBantTrue = Object.values(bantSdr).some(v => v === true);
  const efectiveTipo = allSdrTrue ? 'bant_completo' : anyBantTrue ? 'em_qualificacao' : lead.tipo;
  const g = SDR_GRUPO_CFG[efectiveTipo] || SDR_GRUPO_CFG.parada;

  // Carregar dados guardados
  React.useEffect(() => {
    Promise.all([
      fetch(`/api/comercial/sdr/lead-action/${lead.id}`, { credentials:'include' }).then(r => r.json()).catch(() => null),
      fetch(`/api/comercial/sdr/lead-notes/${lead.id}`, { credentials:'include' }).then(r => r.json()).catch(() => []),
    ]).then(([action, notes]) => {
      if (action && !action.error) {
        if (action.notas_sdr) setNewNota(action.notas_sdr);
        if (action.nif_cliente) setNif(action.nif_cliente);
        if (action.data_demo) setDataDemo(action.data_demo);
        if (action.distrito) setDistritol(action.distrito);
        if (action.codigo_postal) setCpl(action.codigo_postal);
        if (action.localidade) setLocall(action.localidade);
        if (action.concelho) setConcelhl(action.concelho);
        setBantSdr({
          budget:    action.bant_budget_sdr    ?? (lead.bant.budget    === true ? true : null),
          authority: action.bant_authority_sdr ?? (lead.bant.authority === true ? true : null),
          need:      action.bant_need_sdr      ?? (lead.bant.need      === true ? true : null),
          timeline:  action.bant_timeline_sdr  ?? (lead.bant.timeline  === true ? true : null),
        });
      }
      if (Array.isArray(notes)) setNotesList(notes);
    });
  }, [lead.id]);

  const startRec = async () => {
    setRecErr('');
    try {
      const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
      chunksRef.current = [];
      const mr = new MediaRecorder(stream);
      mr.ondataavailable = e => { if (e.data.size > 0) chunksRef.current.push(e.data); };
      mr.onstop = async () => {
        stream.getTracks().forEach(t => t.stop());
        setRec('transcribing');
        const fd = new FormData();
        fd.append('audio', new Blob(chunksRef.current, { type:'audio/webm' }), 'lead-nota.webm');
        fd.append('existing_text', newNota);
        fd.append('user_name', user?.name || '');
        fd.append('nome_entidade', lead.empresa);
        try {
          const r = await fetch('/api/comercial/crm/transcribe-nota', { method:'POST', credentials:'include', body:fd });
          const d = await r.json();
          if (!r.ok) throw new Error(d.error || 'Erro na transcrição');
          if (d.nota_limpa) setNewNota(d.nota_limpa);
          else if (d.text) setNewNota(p => p ? `${p}\n${d.text}` : d.text);
        } catch (e) { setRecErr(e.message); }
        setRec('idle');
      };
      mr.start(); mediaRef.current = mr; setRec('recording');
    } catch (e) {
      setRecErr(e.name === 'NotAllowedError' ? 'Permissão de microfone negada.' : e.message);
      setRec('idle');
    }
  };
  const stopRec = () => { if (mediaRef.current?.state === 'recording') mediaRef.current.stop(); };

  const handleSave = async (acaoOverride) => {
    if (bantGe2 && !nifCliente.trim() && (acaoOverride === 'agendar_demo' || acaoOverride === 'passar_oportunidade' || allSdrTrue)) {
      setSaveErr('NIF do cliente obrigatório para passar ou agendar');
      return;
    }
    setSave('saving'); setSaveErr('');
    try {
      const r = await fetch('/api/comercial/sdr/lead-action', {
        method:'POST', credentials:'include',
        headers:{ 'Content-Type':'application/json' },
        body: JSON.stringify({
          lead_id:lead.id, empresa_nome:lead.empresa, tipo_grupo:efectiveTipo, acao: acaoOverride || null, notas_sdr: newNota || null,
          bant_budget_sdr: bantSdr.budget, bant_authority_sdr: bantSdr.authority,
          bant_need_sdr: bantSdr.need, bant_timeline_sdr: bantSdr.timeline,
          nif_cliente: nifCliente.trim() || null,
          data_demo: dataDemo || null,
          distrito: distritol.trim() || null,
          codigo_postal: cpPostall.trim() || null,
          localidade: localidadel.trim() || null,
          concelho: concelhol.trim() || null,
        }),
      });
      const d = await r.json();
      if (!r.ok) throw new Error(d.error);
      setSave('saved');
      if (onSaved) onSaved(lead.id, bantSdr, efectiveTipo, acaoOverride || null);
      setTimeout(() => setSave('idle'), 2500);
    } catch (e) { setSaveErr(e.message); setSave('error'); setTimeout(() => setSave('idle'), 3000); }
  };

  const handleSaveNota = async () => {
    if (!newNota.trim()) return;
    setNotaSave('saving');
    try {
      const r = await fetch('/api/comercial/sdr/lead-notes', {
        method:'POST', credentials:'include',
        headers:{ 'Content-Type':'application/json' },
        body: JSON.stringify({ lead_id:lead.id, empresa_nome:lead.empresa, nota:newNota.trim() }),
      });
      const d = await r.json();
      if (!r.ok) throw new Error(d.error);
      setNotesList(prev => [d, ...prev]);
      setNewNota('');
      setNotaSave('saved'); setTimeout(() => setNotaSave('idle'), 2000);
    } catch (e) { setNotaSave('error'); setTimeout(() => setNotaSave('idle'), 3000); }
  };

  const bantFields = [['Budget','budget'],['Authority','authority'],['Need','need'],['Timeline','timeline']];
  const overlay = { position:'fixed', inset:0, zIndex:2000, background:'rgba(0,0,0,0.45)', display:'flex', alignItems:'center', justifyContent:'center', padding:24 };
  const card    = { width:'100%', maxWidth:720, maxHeight:'90vh', overflowY:'auto', background:'var(--dgd-bg-surface,#fff)', border:'1px solid var(--dgd-border-1)', borderRadius:12, boxShadow:'0 12px 48px rgba(0,0,0,0.22)' };

  return (
    <div style={overlay} onClick={e => { if (e.target === e.currentTarget) onClose(); }}>
      <div style={card}>
        {/* Header */}
        <div style={{ padding:'16px 20px', borderBottom:'1px solid var(--dgd-border-1)', display:'flex', alignItems:'flex-start', gap:12 }}>
          <div style={{ flex:1 }}>
            <div style={{ display:'flex', alignItems:'center', gap:8, marginBottom:4 }}>
              <span style={{ fontSize:10, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', letterSpacing:'0.08em' }}>DIGI AI · LEAD</span>
              <span style={{ padding:'2px 8px', borderRadius:99, fontSize:10.5, fontWeight:700, color:g.color, background:g.bg, border:`1px solid ${g.border}` }}>{g.label}</span>
              <span style={{ padding:'2px 8px', borderRadius:99, fontSize:10.5, fontWeight:600, background: lead.origem==='Inbound'?'#eff6ff':'#faf5ff', color: lead.origem==='Inbound'?'#1d4ed8':'#7c3aed', border:`1px solid ${lead.origem==='Inbound'?'#bfdbfe':'#ddd6fe'}` }}>{lead.origem}</span>
            </div>
            <div style={{ fontSize:16, fontWeight:700, color:'var(--dgd-fg-1)' }}>{lead.nome}</div>
            <div style={{ fontSize:12.5, color:'var(--dgd-fg-3)', marginTop:2 }}>{lead.empresa} · {lead.segmento}</div>
          </div>
          <button onClick={onClose} style={{ background:'transparent', border:'none', cursor:'pointer', color:'var(--dgd-fg-3)', padding:6, flexShrink:0 }}>
            <svg width="16" height="16" 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>

        {/* Tabs */}
        <div style={{ display:'flex', borderBottom:'1px solid var(--dgd-border-1)', background:'var(--dgd-bg,#f8fafc)' }}>
          {[['info','Info AI'],['conversa','Conversa WA'],['guiao','Guião BANT'],['notas','Notas SDR'],[lead.campanha?'briefing':null,lead.campanha?'Briefing':null]].filter(([t])=>t).map(([t,l]) => (
            <button key={t} onClick={() => setTab(t)} style={{ padding:'10px 16px', border:'none', borderBottom:tab===t?'2px solid #112954':'2px solid transparent', background:'transparent', fontSize:12.5, fontWeight:tab===t?700:400, color:tab===t?'#112954':'var(--dgd-fg-2)', cursor:'pointer', whiteSpace:'nowrap' }}>{l}</button>
          ))}
        </div>

        {/* Body */}
        <div style={{ padding:20 }}>
          {/* ── Tab: Info AI ── */}
          {tab === 'info' && (
            <div>
              {/* Dados do lead */}
              <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:20, marginBottom:20 }}>
                <div>
                  <div style={{ fontSize:10.5, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', letterSpacing:'0.06em', textTransform:'uppercase', marginBottom:8, fontWeight:600 }}>Dados do Lead</div>
                  {[['Nome',lead.nome],['Empresa',lead.empresa],['Telefone',lead.telefone||'—'],['Segmento',lead.segmento||'—'],['Campanha',lead.campanha||'—'],['Canal',lead.canal||lead.origem||'—'],['País',lead.pais||'—'],['Cargo',lead.cargo||'—'],['Score',lead.score!=null?`${lead.score}/100`:'—'],['Recomendação',lead.recomendacao||'—'],['Equipamento',lead.equipamento||'—'],['Objecção',lead.objecao||'—'],['Atribuído',lead.atribuido],['Última activ.',lead.ultima_act]].filter(([k,v])=>v&&v!=='—'||['Nome','Empresa','Campanha','Atribuído','Última activ.'].includes(k)).map(([k,v]) => (
                    <div key={k} style={{ display:'flex', gap:10, marginBottom:5, fontSize:12.5 }}>
                      <span style={{ color:'var(--dgd-fg-3)', minWidth:100, flexShrink:0, fontFamily:'var(--dgd-font-mono,monospace)', fontSize:10, fontWeight:600, textTransform:'uppercase', letterSpacing:'0.04em', paddingTop:2 }}>{k}</span>
                      <span style={{ color:'var(--dgd-fg-1)' }}>{v}</span>
                    </div>
                  ))}
                </div>

                {/* BANT AI + BANT SDR */}
                <div>
                  <div style={{ fontSize:10.5, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', letterSpacing:'0.06em', textTransform:'uppercase', marginBottom:8, fontWeight:600 }}>BANT</div>
                  <div style={{ display:'grid', gridTemplateColumns:'auto 1fr 1fr', gap:'4px 10px', alignItems:'center', marginBottom:6 }}>
                    <div /><div style={{ fontSize:10, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', fontWeight:600 }}>AI</div><div style={{ fontSize:10, color:'#112954', fontFamily:'var(--dgd-font-mono,monospace)', fontWeight:600 }}>SDR</div>
                    {bantFields.map(([label, key]) => {
                      const ai = lead.bant[key];
                      const sdr = bantSdr[key];
                      const aiCfg = ai===true?{c:'#166534',bg:'#f0fdf4',b:'#bbf7d0',t:'S'}:ai===false?{c:'#991b1b',bg:'#fef2f2',b:'#fecaca',t:'N'}:{c:'#94a3b8',bg:'#f1f5f9',b:'#e2e8f0',t:'?'};
                      return (
                        <React.Fragment key={key}>
                          <span style={{ fontSize:11, fontWeight:600, color:'var(--dgd-fg-2)', fontFamily:'var(--dgd-font-mono,monospace)', paddingRight:4 }}>{label}</span>
                          <span style={{ display:'inline-flex', alignItems:'center', justifyContent:'center', width:22, height:22, borderRadius:4, fontSize:10, fontWeight:700, color:aiCfg.c, background:aiCfg.bg, border:`1px solid ${aiCfg.b}` }}>{aiCfg.t}</span>
                          <div style={{ display:'flex', gap:4 }}>
                            {[true,false,null].map(v => {
                              const a = bantSdr[key]===v;
                              const c = v===true?{l:'S',c:'#166534',bg:'#f0fdf4',b:'#bbf7d0'}:v===false?{l:'N',c:'#991b1b',bg:'#fef2f2',b:'#fecaca'}:{l:'?',c:'#64748b',bg:'#f1f5f9',b:'#e2e8f0'};
                              return <button key={String(v)} onClick={() => setBantSdr(p => ({...p,[key]:v}))} style={{ width:22, height:22, display:'inline-flex', alignItems:'center', justifyContent:'center', borderRadius:4, border:`1.5px solid ${a?c.b:'var(--dgd-border-1)'}`, background:a?c.bg:'transparent', color:a?c.c:'var(--dgd-fg-3)', fontSize:10, fontWeight:a?700:400, cursor:'pointer' }}>{c.l}</button>;
                            })}
                          </div>
                        </React.Fragment>
                      );
                    })}
                  </div>
                  {/* NIF — abaixo do BANT, obrigatório quando ≥2 BANT confirmados */}
                  <div style={{ display:'flex', alignItems:'center', gap:8, marginTop:8, padding:'7px 10px', borderRadius:6, background: bantGe2 && !nifCliente.trim() ? '#fef2f2' : 'var(--dgd-bg,#f8fafc)', border:`1px solid ${bantGe2 && !nifCliente.trim() ? '#fecaca' : 'var(--dgd-border-1)'}` }}>
                    <span style={{ fontSize:10.5, fontWeight:600, color: bantGe2 && !nifCliente.trim() ? '#991b1b' : 'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', letterSpacing:'0.05em', whiteSpace:'nowrap' }}>NIF</span>
                    <input
                      type="text"
                      value={nifCliente}
                      onChange={e => setNif(e.target.value)}
                      placeholder={bantGe2 ? 'Obrigatório' : 'NIF do cliente'}
                      maxLength={20}
                      style={{ flex:1, border:'none', background:'transparent', fontSize:12.5, outline:'none', color:'var(--dgd-fg-1)', fontFamily:'var(--dgd-font-mono,monospace)', '::placeholder': { color: bantGe2 ? '#991b1b' : undefined } }}
                    />
                    {bantGe2 && !nifCliente.trim() && <span style={{ fontSize:10, color:'#991b1b', fontWeight:600, whiteSpace:'nowrap' }}>obrigatório</span>}
                  </div>
                  {/* Localização */}
                  <div style={{ marginTop:10, padding:'10px 12px', background:'var(--dgd-bg,#f8fafc)', border:'1px solid var(--dgd-border-1)', borderRadius:8 }}>
                    <div style={{ fontSize:10, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', fontWeight:600, letterSpacing:'0.06em', textTransform:'uppercase', marginBottom:8 }}>Localização</div>
                    <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:6 }}>
                      {[
                        ['Cód. Postal', cpPostall, setCpl,      '0000-000'],
                        ['Localidade',  localidadel, setLocall, 'Localidade'],
                        ['Distrito',    distritol, setDistritol,'Distrito'],
                        ['Concelho',    concelhol, setConcelhl, 'Concelho'],
                      ].map(([label, val, setter, ph]) => (
                        <div key={label} style={{ display:'flex', flexDirection:'column', gap:3 }}>
                          <span style={{ fontSize:10, fontWeight:600, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', letterSpacing:'0.05em' }}>{label}</span>
                          <input type="text" value={val} onChange={ev => setter(ev.target.value)} placeholder={ph} maxLength={80}
                            style={{ padding:'5px 8px', border:'1px solid var(--dgd-border-1)', borderRadius:5, fontSize:12.5, outline:'none', color:'var(--dgd-fg-1)', background:'var(--dgd-bg-surface,#fff)', width:'100%', boxSizing:'border-box' }} />
                        </div>
                      ))}
                    </div>
                  </div>
                </div>
              </div>

              {/* Notas AI */}
              {lead.notas && (
                <div style={{ padding:'10px 14px', background:'#fffbeb', border:'1px solid #fde68a', borderRadius:6, marginBottom:16 }}>
                  <div style={{ fontSize:10, fontFamily:'var(--dgd-font-mono,monospace)', color:'#92400e', fontWeight:600, letterSpacing:'0.06em', marginBottom:4 }}>RESUMO DO AI</div>
                  <div style={{ fontSize:13, color:'var(--dgd-fg-1)', lineHeight:1.6 }}>{lead.notas}</div>
                </div>
              )}

              {/* Chamada Twilio */}
              <SdrCallWidget
                prospect={{ ...lead, contactos: lead.telefone ? [{ telemovel: lead.telefone, nome_completo: lead.nome }] : [] }}
                campanhaNome={lead.campanha || ''}
                user={user}
                onResult={(d) => {
                  if (d.bant) setBantSdr(p => ({
                    budget:    d.bant.budget    !== undefined ? d.bant.budget    : p.budget,
                    authority: d.bant.authority !== undefined ? d.bant.authority : p.authority,
                    need:      d.bant.need      !== undefined ? d.bant.need      : p.need,
                    timeline:  d.bant.timeline  !== undefined ? d.bant.timeline  : p.timeline,
                  }));
                  if (d.qualificacao?.nif) setNif(d.qualificacao.nif);
                  const avaliacao = formatarAvaliacaoChamada(d);
                  if (avaliacao) setNewNota(p => p ? `${p}\n\n${avaliacao}` : avaliacao);
                }}
              />

              {/* ── Nota rápida ── */}
              <div style={{ borderTop:'1px solid var(--dgd-border-1)', paddingTop:14 }}>
                <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:6 }}>
                  <div style={{ fontSize:10.5, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', letterSpacing:'0.06em', textTransform:'uppercase', fontWeight:600 }}>
                    Nota Rápida
                    {notesList.length > 0 && <span style={{ color:'#1d4ed8', marginLeft:6, fontWeight:700 }}>{notesList.length} guardada{notesList.length !== 1 ? 's' : ''}</span>}
                  </div>
                  <div style={{ display:'flex', alignItems:'center', gap:6 }}>
                    {recState === 'transcribing' && <span style={{ fontSize:11, color:'var(--dgd-fg-3)' }}>A transcrever...</span>}
                    {recErr && <span style={{ fontSize:11, color:'#dc2626' }}>{recErr}</span>}
                    <button
                      onClick={recState === 'recording' ? stopRec : startRec}
                      disabled={recState === 'transcribing'}
                      style={{ display:'flex', alignItems:'center', gap:5, padding:'3px 9px', borderRadius:6, border:'1px solid', fontSize:11, fontWeight:600, cursor:recState==='transcribing'?'not-allowed':'pointer', background:recState==='recording'?'#fee2e2':'transparent', borderColor:recState==='recording'?'#fca5a5':'var(--dgd-border-1)', color:recState==='recording'?'#dc2626':'var(--dgd-fg-2)' }}
                    >
                      {recState === 'recording'
                        ? <><span style={{ width:7,height:7,borderRadius:'50%',background:'#dc2626',animation:'pulse 1s infinite',flexShrink:0 }} />Parar</>
                        : <><svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/><line x1="12" y1="19" x2="12" y2="23"/><line x1="8" y1="23" x2="16" y2="23"/></svg>Gravar</>
                      }
                    </button>
                  </div>
                </div>
                <div style={{ display:'flex', gap:8, alignItems:'flex-start' }}>
                  <textarea
                    value={newNota}
                    onChange={e => setNewNota(e.target.value)}
                    disabled={recState !== 'idle'}
                    placeholder="Nota sobre este lead..."
                    rows={2}
                    style={{ flex:1, boxSizing:'border-box', padding:'7px 10px', fontSize:12.5, border:'1px solid var(--dgd-border-1)', borderRadius:6, resize:'none', fontFamily:'var(--dgd-font-body,sans-serif)', color:'var(--dgd-fg-1)', background:recState!=='idle'?'var(--dgd-bg,#f8fafc)':'var(--dgd-bg-surface,#fff)', outline:'none', opacity:recState==='recording'?0.6:1 }}
                  />
                  <button
                    onClick={handleSaveNota}
                    disabled={!newNota.trim() || notaSave === 'saving'}
                    style={{ padding:'7px 12px', borderRadius:6, border:'none', fontSize:12, fontWeight:600, cursor:(!newNota.trim()||notaSave==='saving')?'not-allowed':'pointer', background:notaSave==='saved'?'#16a34a':(!newNota.trim()?'var(--dgd-border-1)':'#112954'), color:(!newNota.trim()&&notaSave!=='saved')?'var(--dgd-fg-3)':'#fff', whiteSpace:'nowrap', minWidth:72, flexShrink:0 }}
                  >{notaSave==='saved'?'✓ Guardado':notaSave==='saving'?'...':'Guardar'}</button>
                </div>
              </div>
            </div>
          )}

          {/* ── Tab: Conversa WA ── */}
          {tab === 'conversa' && (
            <div>
              {(() => {
                const msgs = aiConversa !== null ? aiConversa : (lead.conversa || []);
                if (aiConversa === null && lead.origem === 'sdr-ai') return (
                  <div style={{ textAlign:'center', color:'var(--dgd-fg-3)', fontSize:13, padding:'32px 0' }}>A carregar...</div>
                );
                if (msgs.length === 0) return (
                  <div style={{ textAlign:'center', color:'var(--dgd-fg-3)', fontSize:13, padding:'32px 0' }}>Sem conversa registada.</div>
                );
                return (
                  <div style={{ display:'flex', flexDirection:'column', gap:8, maxHeight:380, overflowY:'auto', padding:4 }}>
                    {msgs.map((msg, i) => (
                      <div key={i} style={{ display:'flex', flexDirection:'column', alignItems: msg.de==='ai' ? 'flex-start' : 'flex-end' }}>
                        <div style={{ maxWidth:'80%', 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.5, 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)', padding:'0 4px' }}>
                          {msg.de==='ai' ? 'digi.ai' : lead.nome} · {msg.ts}
                        </div>
                      </div>
                    ))}
                  </div>
                );
              })()}
            </div>
          )}

          {/* ── Tab: Guião BANT ── */}
          {tab === 'guiao' && (
            <div>
              <div style={{ fontSize:10.5, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', letterSpacing:'0.06em', textTransform:'uppercase', fontWeight:600, marginBottom:12 }}>Guião BANT — {lead.nome}</div>
              <div style={{ display:'flex', flexDirection:'column', gap:8 }}>
                {gerarGuiaoAiLead(lead).map(function(step, i) {
                  return (
                    <div key={i} style={{ padding:'10px 14px', borderRadius:8, border:'1px solid ' + (step.alerta ? '#fde68a' : 'var(--dgd-border-1)'), background: step.alerta ? '#fffbeb' : 'var(--dgd-bg-surface,#fff)' }}>
                      <div style={{ fontSize:10.5, fontWeight:700, fontFamily:'var(--dgd-font-mono,monospace)', color: step.alerta ? '#92400e' : '#112954', letterSpacing:'0.05em', marginBottom:6 }}>{step.label}</div>
                      <div style={{ fontSize:12.5, color:'var(--dgd-fg-1)', lineHeight:1.6, whiteSpace:'pre-wrap' }}>{step.texto}</div>
                      {step.nota && <div style={{ marginTop:5, fontSize:11, color: step.alerta ? '#92400e' : 'var(--dgd-fg-3)', fontStyle:'italic' }}>{step.nota}</div>}
                    </div>
                  );
                })}
              </div>
            </div>
          )}

          {/* ── Tab: Briefing Campanha ── */}
          {tab === 'briefing' && lead.campanha && (
            <div>
              <div style={{ marginBottom:14 }}>
                <div style={{ fontSize:10.5, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', letterSpacing:'0.06em', marginBottom:4 }}>CAMPANHA DE ORIGEM</div>
                <div style={{ fontSize:16, fontWeight:700, color:'var(--dgd-fg-1)' }}>{lead.campanha}</div>
              </div>
              <SdrBriefingBlocks campanhaId={lead.sdr_campanha_id} fallbackMd={lead.sdr_ficha_md} />
            </div>
          )}

          {/* ── Tab: Notas SDR ── */}
          {tab === 'notas' && (
            <div>
              {/* Nova nota */}
              <div style={{ marginBottom:16, padding:'12px 14px', background:'var(--dgd-bg,#f8fafc)', border:'1px solid var(--dgd-border-1)', borderRadius:8 }}>
                <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:8 }}>
                  <div style={{ fontSize:10.5, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', letterSpacing:'0.06em', textTransform:'uppercase', fontWeight:600 }}>Nova Nota</div>
                  <div style={{ display:'flex', alignItems:'center', gap:6 }}>
                    {recState === 'transcribing' && <span style={{ fontSize:11, color:'var(--dgd-fg-3)' }}>A transcrever...</span>}
                    {recErr && <span style={{ fontSize:11, color:'#dc2626' }}>{recErr}</span>}
                    <button
                      onClick={recState === 'recording' ? stopRec : startRec}
                      disabled={recState === 'transcribing'}
                      style={{ display:'flex', alignItems:'center', gap:5, padding:'4px 10px', borderRadius:6, border:'1px solid', fontSize:11, fontWeight:600, cursor:recState==='transcribing'?'not-allowed':'pointer', background:recState==='recording'?'#fee2e2':'transparent', borderColor:recState==='recording'?'#fca5a5':'var(--dgd-border-1)', color:recState==='recording'?'#dc2626':'var(--dgd-fg-2)' }}
                    >
                      {recState === 'recording'
                        ? <><span style={{ width:7, height:7, borderRadius:'50%', background:'#dc2626', animation:'pulse 1s infinite', flexShrink:0 }} />Parar</>
                        : <><svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/><line x1="12" y1="19" x2="12" y2="23"/><line x1="8" y1="23" x2="16" y2="23"/></svg>Gravar áudio</>
                      }
                    </button>
                  </div>
                </div>
                <textarea
                  value={newNota}
                  onChange={e => setNewNota(e.target.value)}
                  disabled={recState !== 'idle'}
                  placeholder="O que aconteceu? Próximos passos, objeções, combinado..."
                  rows={4}
                  style={{ width:'100%', boxSizing:'border-box', padding:'8px 10px', fontSize:12.5, border:'1px solid var(--dgd-border-1)', borderRadius:6, resize:'vertical', fontFamily:'var(--dgd-font-body,sans-serif)', color:'var(--dgd-fg-1)', background:recState!=='idle'?'var(--dgd-bg,#f8fafc)':'var(--dgd-bg-surface,#fff)', outline:'none', opacity:recState==='recording'?0.6:1, marginBottom:8 }}
                />
                <div style={{ display:'flex', justifyContent:'flex-end' }}>
                  <button
                    onClick={handleSaveNota}
                    disabled={!newNota.trim() || notaSave === 'saving'}
                    style={{ padding:'7px 16px', borderRadius:6, border:'none', fontSize:12.5, fontWeight:600, cursor:(!newNota.trim()||notaSave==='saving')?'not-allowed':'pointer', background:notaSave==='saved'?'#16a34a':(!newNota.trim()?'var(--dgd-border-1)':'#112954'), color:(!newNota.trim()&&notaSave!=='saved')?'var(--dgd-fg-3)':'#fff' }}
                  >{notaSave==='saved'?'✓ Guardado':notaSave==='saving'?'A guardar...':'Guardar nota'}</button>
                </div>
              </div>

              {transcricaoNota && (
                <div style={{ position:'fixed', inset:0, zIndex:9999, background:'rgba(0,0,0,0.5)', display:'flex', alignItems:'center', justifyContent:'center' }} onClick={() => setTranscricaoNota(null)}>
                  <div style={{ background:'#fff', borderRadius:12, padding:24, width:'min(700px,95vw)', maxHeight:'80vh', overflowY:'auto', boxShadow:'0 8px 32px rgba(0,0,0,0.18)' }} onClick={e => e.stopPropagation()}>
                    <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:16 }}>
                      <span style={{ fontWeight:700, fontSize:13 }}>Transcrição · {transcricaoNota.ts}</span>
                      <button onClick={() => setTranscricaoNota(null)} style={{ border:'none', background:'none', cursor:'pointer', fontSize:20, color:'var(--dgd-fg-3)', lineHeight:1 }}>×</button>
                    </div>
                    {transcricaoNotaLoading ? (
                      <div style={{ textAlign:'center', color:'var(--dgd-fg-3)', fontSize:12, padding:20 }}>A carregar...</div>
                    ) : transcricaoNota.text ? (
                      <pre style={{ fontFamily:'var(--dgd-font-mono,monospace)', fontSize:11.5, lineHeight:1.7, whiteSpace:'pre-wrap', color:'var(--dgd-fg-1)', margin:0 }}>{transcricaoNota.text}</pre>
                    ) : (
                      <div style={{ textAlign:'center', color:'var(--dgd-fg-3)', fontSize:12, padding:20 }}>Transcrição não disponível para esta chamada.</div>
                    )}
                  </div>
                </div>
              )}

              {/* Lista de notas */}
              {notesList.length === 0 ? (
                <div style={{ textAlign:'center', color:'var(--dgd-fg-3)', fontSize:12.5, padding:'24px 0' }}>Ainda sem notas guardadas para este lead.</div>
              ) : (
                <div>
                  <div style={{ fontSize:10.5, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', letterSpacing:'0.06em', textTransform:'uppercase', fontWeight:600, marginBottom:10 }}>
                    Histórico de Notas ({notesList.length})
                  </div>
                  {notesList.map(n => (
                    <div key={n.id} style={{ marginBottom:8, padding:'10px 14px', background:'var(--dgd-bg-surface,#fff)', border:'1px solid var(--dgd-border-1)', borderRadius:6 }}>
                      <div style={{ fontSize:10.5, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', marginBottom:5, display:'flex', alignItems:'center', gap:8 }}>
                        <span>{new Date(n.created_at).toLocaleDateString('pt-PT',{day:'2-digit',month:'2-digit',year:'numeric'})} {new Date(n.created_at).toLocaleTimeString('pt-PT',{hour:'2-digit',minute:'2-digit'})}</span>
                        <span style={{ color:'var(--dgd-border-1)' }}>·</span>
                        <span>{n.sdr_nome || n.sdr_email}</span>
                        {n.nota?.startsWith('[CHAMADA AI') && (
                          <button onClick={() => verTranscricaoNota(n.nota)} style={{ marginLeft:'auto', fontSize:10.5, padding:'2px 8px', borderRadius:5, border:'1px solid #bfdbfe', background:'#eff6ff', color:'#1d4ed8', cursor:'pointer' }}>Ver transcrição</button>
                        )}
                      </div>
                      <div style={{ fontSize:12.5, color:'var(--dgd-fg-1)', lineHeight:1.6, whiteSpace:'pre-wrap' }}>{n.nota}</div>
                    </div>
                  ))}
                </div>
              )}
            </div>
          )}
        </div>

        {/* Footer */}
        <div style={{ padding:'12px 20px', borderTop:'1px solid var(--dgd-border-1)', display:'flex', alignItems:'center', justifyContent:'space-between', background:'var(--dgd-bg,#f8fafc)', gap:8, flexWrap:'wrap' }}>
          <div style={{ display:'flex', gap:6 }}>
            {bantFields.map(([label, key]) => {
              const v = bantSdr[key] !== null ? bantSdr[key] : lead.bant[key];
              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 key={key} style={{ display:'inline-flex', alignItems:'center', justifyContent:'center', width:22, height:22, borderRadius:4, fontSize:10, fontWeight:700, fontFamily:'var(--dgd-font-mono,monospace)', color, background:bg, border:`1px solid ${border}` }}>{label[0]}</span>;
            })}
          </div>
          <div style={{ display:'flex', gap:8, alignItems:'center', flexWrap:'wrap' }}>
            {saveState === 'error' && <span style={{ fontSize:11.5, color:'#991b1b' }}>{saveErr || 'Erro ao guardar'}</span>}
            <button onClick={onClose} style={{ padding:'7px 14px', borderRadius:6, border:'1px solid var(--dgd-border-1)', background:'transparent', fontSize:13, cursor:'pointer', color:'var(--dgd-fg-2)' }}>Fechar</button>
            {onArquivar && (
              <button onClick={() => { if (window.confirm(`Arquivar ${lead.nome}?`)) onArquivar(lead.id); }}
                style={{ padding:'7px 12px', borderRadius:6, border:'1px solid #d6d3d1', background:'#fafaf9', color:'#78716c', fontSize:12, cursor:'pointer' }}
              >Arquivar</button>
            )}
            <button
              onClick={() => handleSave(null)}
              disabled={saveState === 'saving'}
              style={{ padding:'7px 14px', borderRadius:6, border:'none', background:'var(--dgd-fg-3,#64748b)', color:'#fff', fontSize:13, fontWeight:600, cursor:saveState==='saving'?'not-allowed':'pointer', minWidth:90 }}
            >
              {saveState === 'saving' ? 'A guardar...' : saveState === 'saved' ? '✓ Guardado' : 'Guardar'}
            </button>
            {bantGe2 ? (
              <>
                <input
                  type="date" value={dataDemo} onChange={e => setDataDemo(e.target.value)}
                  style={{ padding:'6px 10px', borderRadius:6, border:'1px solid var(--dgd-border-1)', fontSize:12.5, color:'var(--dgd-fg-1)', background:'var(--dgd-bg-card,white)', cursor:'pointer' }}
                />
                <button
                  onClick={() => handleSave('agendar_demo')}
                  disabled={saveState === 'saving' || !dataDemo}
                  style={{ padding:'7px 14px', borderRadius:6, border:'none', background:dataDemo?'#166534':'#94a3b8', color:'#fff', fontSize:13, fontWeight:700, cursor:(saveState==='saving'||!dataDemo)?'not-allowed':'pointer', whiteSpace:'nowrap' }}
                >Agendar Demo</button>
                <button
                  onClick={() => handleSave('passar_oportunidade')}
                  disabled={saveState === 'saving'}
                  style={{ padding:'7px 14px', borderRadius:6, border:'1px solid #166534', background:'transparent', color:'#166534', fontSize:13, fontWeight:600, cursor:saveState==='saving'?'not-allowed':'pointer', whiteSpace:'nowrap' }}
                >Passar a Oportunidade</button>
              </>
            ) : (
              <button
                onClick={() => handleSave(g.acao)}
                disabled={saveState === 'saving'}
                style={{ padding:'7px 16px', borderRadius:6, border:'none', background:g.color, color:'#fff', fontSize:13, fontWeight:700, cursor:saveState==='saving'?'not-allowed':'pointer', whiteSpace:'nowrap' }}
              >{g.acao}</button>
            )}
          </div>
        </div>
      </div>
    </div>
  );
};

// ─── Daily Qualification (SDR Humano) ─────────────────────────────────────────
const SdrDailyProspect = ({ user, sdrEmail, sdrEmailsStr, ano: anoProp, tenant, onLeadUpdated }) => {
  const [leads,     setLeads]     = React.useState([]);
  const [loading,   setLoading]   = React.useState(true);
  const [statusMap, setStatusMap] = React.useState({});
  const [leadModal, setLeadModal] = React.useState(null);

  // Carrega leads reais da BD e inicializa statusMap com actions já guardadas
  React.useEffect(() => {
    let cancelled = false;
    setLoading(true);
    const mes = new Date().getMonth() + 1;
    const ano = anoProp || new Date().getFullYear();
    let leadsUrl = `/api/comercial/sdr/leads?mes=${mes}&ano=${ano}`;
    if (sdrEmail) leadsUrl += `&sdr_email=${encodeURIComponent(sdrEmail)}`;
    else if (sdrEmailsStr) leadsUrl += `&sdr_emails=${encodeURIComponent(sdrEmailsStr)}`;
    fetch(leadsUrl, { credentials:'include' })
      .then(r => r.json()).catch(() => [])
      .then(rows => {
        if (cancelled) return;
        if (!Array.isArray(rows)) { setLoading(false); return; }
        const fmtDT = (ts) => ts ? new Date(ts).toLocaleDateString('pt-PT',{day:'2-digit',month:'2-digit'}) + ' ' + new Date(ts).toLocaleTimeString('pt-PT',{hour:'2-digit',minute:'2-digit'}) : null;
        const mapped = rows.map(r => ({
          id:           r.id,
          tipo:         r.action_tipo || r.tipo_inicial || 'sem_contacto',
          tipo_inicial: r.tipo_inicial || 'sem_contacto',
          acao:         r.acao || null,
          opp_estado:   r.opp_estado || 'por_abrir',
          nif:          r.nif_cliente || '',
          data_demo:    r.data_demo || null,
          fm_opp_id:    r.fm_opp_id || null,
          fm_status:    r.fm_status || 'pendente',
          nome:         r.nome,
          empresa:      r.empresa,
          telefone:     r.telefone || '',
          segmento:     r.segmento || '',
          origem:       r.origem || 'Inbound',
          campanha:     r.campanha || r.campanha_ai || null,
          canal:        r.canal_ai || null,
          pais:         r.pais_ai || null,
          score:        r.score_ai || null,
          recomendacao: r.recomendacao_ai || null,
          equipamento:  r.equipamento_ai || null,
          objecao:      r.objecao_ai || null,
          sdr_ficha_md:    r.sdr_ficha_md || null,
          sdr_campanha_id: r.sdr_campanha_id || null,
          atribuido:    fmtDT(r.atribuido_at) || '--',
          ultima_act:   fmtDT(r.ultima_act_at),
          bant:         r.bant_inicial || {},
          notas:        r.notas_inicial || '',
          conversa:     [],
          historico:    [],
        }));
        setLeads(mapped);
        // Inicializa statusMap com as actions já guardadas (vêm no JOIN)
        const map = {};
        rows.forEach(r => {
          if (!r.action_tipo) return;
          map[r.id] = {
            tipo: r.action_tipo,
            acao: r.acao || null,
            opp_estado: r.opp_estado || 'por_abrir',
            bant: { budget: r.bant_budget_sdr, authority: r.bant_authority_sdr,
                    need: r.bant_need_sdr,    timeline: r.bant_timeline_sdr },
          };
        });
        if (Object.keys(map).length) setStatusMap(map);
        setLoading(false);
      });
    return () => { cancelled = true; };
  }, [sdrEmail, sdrEmailsStr, anoProp]);

  const [subTab,   setSubTab]   = React.useState('qualification');
  const [oppModal, setOppModal] = React.useState(null);

  // Helpers de filtragem por sub-tab
  const getTipoEf = (l) => {
    const base = statusMap[l.id]?.tipo ?? l.tipo;
    if (base === 'excluido' || base === 'arquivada') return base;
    const bant = statusMap[l.id]?.bant ?? l.bant ?? {};
    const allTrue = bant.budget===true && bant.authority===true && bant.need===true && bant.timeline===true;
    const anyTrue = Object.values(bant).some(v => v === true);
    return allTrue ? 'bant_completo' : anyTrue ? 'em_qualificacao' : base;
  };
  const getAcaoEf = (l) => statusMap[l.id]?.acao ?? l.acao;
  const INACTIVAS = ['arquivada','excluido'];
  const OPP_ACOES = ['passar_oportunidade','agendar_demo'];
  const isOpp      = (l) => OPP_ACOES.includes(getAcaoEf(l)) && !INACTIVAS.includes(getTipoEf(l));
  const isInactiva = (l) => INACTIVAS.includes(getTipoEf(l));
  const isActive   = (l) => !isOpp(l) && !isInactiva(l);

  const activeLeads   = leads.filter(isActive);
  const oppLeads      = leads.filter(isOpp);
  const inativasLeads = leads.filter(isInactiva);

  // Chamado pelo modal após save bem-sucedido
  const onLeadSaved = (leadId, bantSdr, savedTipo, savedAcao) => {
    setStatusMap(prev => ({ ...prev, [leadId]: { tipo: savedTipo, bant: bantSdr, acao: savedAcao ?? prev[leadId]?.acao ?? null } }));
    setLeads(prev => prev.map(l => l.id === leadId
      ? { ...l, tipo: savedTipo, bant: { ...l.bant, ...bantSdr }, acao: savedAcao ?? l.acao }
      : l
    ));
    setLeadModal(prev => prev?.id === leadId ? { ...prev, tipo: savedTipo, bant: { ...prev.bant, ...bantSdr }, acao: savedAcao ?? prev.acao } : prev);
    if (onLeadUpdated) onLeadUpdated();
  };

  const postLeadAction = (leadId, empresa, tipo_grupo, acao, bant) => {
    fetch('/api/comercial/sdr/lead-action', {
      method:'POST', credentials:'include',
      headers:{ 'Content-Type':'application/json' },
      body: JSON.stringify({
        lead_id: leadId, empresa_nome: empresa, tipo_grupo, acao: acao || null,
        bant_budget_sdr: bant?.budget ?? null, bant_authority_sdr: bant?.authority ?? null,
        bant_need_sdr: bant?.need ?? null, bant_timeline_sdr: bant?.timeline ?? null,
      }),
    }).then(() => { if (onLeadUpdated) onLeadUpdated(); }).catch(() => {});
  };

  const handleExcluir = (leadId) => {
    const lead = leads.find(l => l.id === leadId);
    if (!lead) return;
    const bant = statusMap[leadId]?.bant || {};
    setStatusMap(prev => ({ ...prev, [leadId]: { ...(prev[leadId]||{}), tipo:'excluido', acao: null } }));
    setLeads(prev => prev.map(l => l.id === leadId ? { ...l, tipo:'excluido', acao: null } : l));
    postLeadAction(leadId, lead.empresa, 'excluido', null, bant);
  };

  const handleArquivar = (leadId) => {
    const lead = leads.find(l => l.id === leadId);
    if (!lead) return;
    const bant = statusMap[leadId]?.bant || {};
    setStatusMap(prev => ({ ...prev, [leadId]: { ...(prev[leadId]||{}), tipo:'arquivada', acao: null } }));
    setLeads(prev => prev.map(l => l.id === leadId ? { ...l, tipo:'arquivada', acao: null } : l));
    setLeadModal(null);
    postLeadAction(leadId, lead.empresa, 'arquivada', null, bant);
  };

  const getOppEstado = (l) => statusMap[l.id]?.opp_estado ?? l.opp_estado ?? 'por_abrir';

  const handleToggleOppEstado = (leadId) => {
    const lead = leads.find(l => l.id === leadId);
    if (!lead) return;
    const current = getOppEstado(lead);
    const next = current === 'por_abrir' ? 'aberto' : 'por_abrir';
    setStatusMap(prev => ({ ...prev, [leadId]: { ...(prev[leadId]||{}), opp_estado: next } }));
    setLeads(prev => prev.map(l => l.id === leadId ? { ...l, opp_estado: next } : l));
    const bant = statusMap[leadId]?.bant || {};
    fetch('/api/comercial/sdr/lead-action', {
      method:'POST', credentials:'include',
      headers:{ 'Content-Type':'application/json' },
      body: JSON.stringify({
        lead_id: leadId, empresa_nome: lead.empresa,
        tipo_grupo: getTipoEf(lead), acao: getAcaoEf(lead), opp_estado: next,
        bant_budget_sdr: bant.budget ?? null, bant_authority_sdr: bant.authority ?? null,
        bant_need_sdr: bant.need ?? null, bant_timeline_sdr: bant.timeline ?? null,
      }),
    }).catch(() => {});
  };

  const handleRestaurar = (leadId) => {
    const lead = leads.find(l => l.id === leadId);
    if (!lead) return;
    const tipoAtual = getTipoEf(lead);
    const bant = statusMap[leadId]?.bant || {};
    setStatusMap(prev => ({ ...prev, [leadId]: { ...(prev[leadId]||{}), acao: null } }));
    setLeads(prev => prev.map(l => l.id === leadId ? { ...l, acao: null } : l));
    setOppModal(null);
    postLeadAction(leadId, lead.empresa, tipoAtual, null, bant);
  };

  const handleReativar = (leadId) => {
    const lead = leads.find(l => l.id === leadId);
    if (!lead) return;
    const tipoOriginal = lead.tipo_inicial || 'sem_contacto';
    const bant = statusMap[leadId]?.bant || {};
    setStatusMap(prev => ({ ...prev, [leadId]: { ...(prev[leadId]||{}), tipo: tipoOriginal, acao: null } }));
    setLeads(prev => prev.map(l => l.id === leadId ? { ...l, tipo: tipoOriginal, acao: null } : l));
    postLeadAction(leadId, lead.empresa, tipoOriginal, null, bant);
  };

  // status badge config (mesmo SDR_GRUPO_CFG mas para coluna)
  const statusCfg = SDR_GRUPO_CFG;

  const thS = { padding:'7px 12px', textAlign:'left', fontSize:10, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', letterSpacing:'0.07em', textTransform:'uppercase', fontWeight:600, borderBottom:'1px solid var(--dgd-border-1)', background:'var(--dgd-bg,#f8fafc)', whiteSpace:'nowrap' };

  if (loading) return (
    <div style={{ marginTop:20, padding:'32px 0', textAlign:'center', color:'var(--dgd-fg-3)', fontSize:12, fontFamily:'var(--dgd-font-mono,monospace)' }}>
      A carregar leads...
    </div>
  );

  return (
    <>
    <div style={{ marginTop:20 }}>
      <div style={{ marginBottom:12 }}>
        <div style={{ fontSize:10, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', letterSpacing:'0.08em', marginBottom:3 }}>SDR HUMANO · {new Date().toLocaleDateString('pt-PT',{day:'2-digit',month:'2-digit',year:'numeric'})}</div>
        <div style={{ fontSize:15, fontWeight:600, color:'var(--dgd-fg-1)' }}>Daily Qualification</div>
      </div>

      <div style={{ background:'var(--dgd-bg-card,white)', border:'1px solid var(--dgd-border-1)', borderRadius:8, overflow:'hidden' }}>
        {/* Header bloco */}
        <div style={{ padding:'10px 14px', borderBottom:'1px solid var(--dgd-border-1)', display:'flex', alignItems:'center', gap:10, background:'var(--dgd-bg,#f8fafc)', flexWrap:'wrap' }}>
          <span style={{ fontSize:13, fontWeight:700, color:'var(--dgd-fg-1)' }}>Leads SDR Atribuídas</span>
          <span style={{ display:'inline-flex', alignItems:'center', justifyContent:'center', minWidth:22, height:22, borderRadius:99, background:'var(--dgd-bg-surface,#fff)', border:'1.5px solid var(--dgd-border-1)', fontSize:12, fontWeight:700, color:'var(--dgd-fg-2)', padding:'0 7px' }}>{leads.length}</span>
          {subTab === 'qualification' && (
            <div style={{ marginLeft:'auto', display:'flex', gap:6, flexWrap:'wrap' }}>
              {Object.entries(statusCfg).filter(([k]) => !INACTIVAS.includes(k)).map(([k,v]) => {
                const n = activeLeads.filter(l => getTipoEf(l) === k).length;
                if (!n) return null;
                return <span key={k} style={{ fontSize:10.5, padding:'2px 8px', borderRadius:99, fontWeight:600, color:v.color, background:v.bg, border:`1px solid ${v.border}`, whiteSpace:'nowrap' }}>{v.label} {n}</span>;
              })}
            </div>
          )}
        </div>

        {/* Sub-tabs */}
        {(() => {
          const tabStyle = (active) => ({
            padding:'7px 14px', fontSize:11.5, fontWeight:600, cursor:'pointer', border:'none', background:'transparent',
            borderBottom: active ? '2px solid var(--dgd-fg-1)' : '2px solid transparent',
            color: active ? 'var(--dgd-fg-1)' : 'var(--dgd-fg-3)',
          });
          return (
            <div style={{ display:'flex', borderBottom:'1px solid var(--dgd-border-1)', padding:'0 6px', background:'var(--dgd-bg-card,white)' }}>
              <button style={tabStyle(subTab==='qualification')} onClick={() => setSubTab('qualification')}>
                Daily Qualification <span style={{ marginLeft:4, fontSize:10.5, fontWeight:700, color:'inherit', opacity:.7 }}>{activeLeads.length}</span>
              </button>
              <button style={tabStyle(subTab==='oportunidades')} onClick={() => setSubTab('oportunidades')}>
                Oportunidades Criadas <span style={{ marginLeft:4, fontSize:10.5, fontWeight:700, color:'inherit', opacity:.7 }}>{oppLeads.length}</span>
              </button>
              <button style={tabStyle(subTab==='inactivas')} onClick={() => setSubTab('inactivas')}>
                Inactivas <span style={{ marginLeft:4, fontSize:10.5, fontWeight:700, color:'inherit', opacity:.7 }}>{inativasLeads.length}</span>
              </button>
            </div>
          );
        })()}

        {/* Tab: Daily Qualification */}
        {subTab === 'qualification' && (
          <div style={{ overflowX:'auto' }}>
            <table style={{ width:'100%', borderCollapse:'collapse', fontSize:12.5 }}>
              <thead>
                <tr>
                  <th style={thS}>Lead</th>
                  <th style={thS}>Origem</th>
                  <th style={thS}>BANT</th>
                  <th style={thS}>Status</th>
                  <th style={thS}>Atribuído</th>
                  <th style={thS}>Última act.</th>
                  <th style={{ ...thS, textAlign:'right' }}></th>
                </tr>
              </thead>
              <tbody>
                {[...activeLeads].sort((a, b) => {
                  const order = { bant_completo:0, em_qualificacao:1, sem_contacto:2, sem_resposta:3, parada:4 };
                  return (order[getTipoEf(a)] ?? 9) - (order[getTipoEf(b)] ?? 9);
                }).map(l => {
                  const ov    = statusMap[l.id];
                  const tipoEf = getTipoEf(l);
                  const sc    = statusCfg[tipoEf] || statusCfg.parada;
                  const ob    = ov?.bant || {};
                  const bantEf = { budget: ob.budget ?? l.bant?.budget, authority: ob.authority ?? l.bant?.authority, need: ob.need ?? l.bant?.need, timeline: ob.timeline ?? l.bant?.timeline };
                  return (
                    <tr key={l.id} onClick={() => setLeadModal(l)}
                      style={{ borderBottom:'1px solid var(--dgd-border-1)', cursor:'pointer' }}
                      onMouseEnter={e => e.currentTarget.style.background='var(--dgd-bg,#f8fafc)'}
                      onMouseLeave={e => e.currentTarget.style.background='transparent'}
                    >
                      <td style={{ padding:'9px 12px' }}>
                        <div style={{ fontWeight:600, color:'var(--dgd-fg-1)' }}>{l.nome}</div>
                        <div style={{ fontSize:11.5, color:'var(--dgd-fg-3)', marginTop:1 }}>{l.empresa}</div>
                      </td>
                      <td style={{ padding:'9px 12px', whiteSpace:'nowrap' }}>
                        <span style={{ fontSize:10.5, padding:'2px 7px', borderRadius:99, fontWeight:600, background:l.origem==='Inbound'?'#eff6ff':'#faf5ff', color:l.origem==='Inbound'?'#1d4ed8':'#7c3aed', border:`1px solid ${l.origem==='Inbound'?'#bfdbfe':'#ddd6fe'}` }}>{l.origem}</span>
                        {l.campanha && <div style={{ fontSize:10, color:'var(--dgd-fg-3)', marginTop:2, maxWidth:120, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{l.campanha}</div>}
                      </td>
                      <td style={{ padding:'9px 12px' }}><SdrBantDots bant={bantEf} /></td>
                      <td style={{ padding:'9px 12px', whiteSpace:'nowrap' }}>
                        <span style={{ fontSize:11, padding:'2px 9px', borderRadius:99, fontWeight:600, color:sc.color, background:sc.bg, border:`1px solid ${sc.border}` }}>{sc.label}</span>
                      </td>
                      <td style={{ padding:'9px 12px', color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', fontSize:11, whiteSpace:'nowrap' }}>{l.atribuido}</td>
                      <td style={{ padding:'9px 12px', color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', fontSize:11, whiteSpace:'nowrap' }}>{l.ultima_act}</td>
                      <td style={{ padding:'9px 12px', textAlign:'right', whiteSpace:'nowrap' }}>
                        <div style={{ display:'inline-flex', gap:6, alignItems:'center' }}>
                          <button onClick={e => { e.stopPropagation(); setLeadModal(l); }}
                            style={{ padding:'4px 12px', borderRadius:6, border:`1px solid ${sc.border}`, background:sc.bg, color:sc.color, fontSize:11.5, fontWeight:600, cursor:'pointer', whiteSpace:'nowrap' }}
                          >{sc.acao}</button>
                          <button onClick={e => { e.stopPropagation(); if (window.confirm(`Excluir ${l.nome}?`)) handleExcluir(l.id); }}
                            style={{ padding:'4px 8px', borderRadius:6, border:'1px solid #fecaca', background:'#fef2f2', color:'#991b1b', fontSize:10.5, fontWeight:500, cursor:'pointer' }}
                          >Excluir</button>
                        </div>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        )}

        {/* Tab: Oportunidades Criadas */}
        {subTab === 'oportunidades' && (
          <div style={{ overflowX:'auto' }}>
            {oppLeads.length === 0 ? (
              <div style={{ padding:'32px 0', textAlign:'center', color:'var(--dgd-fg-3)', fontSize:12, fontFamily:'var(--dgd-font-mono,monospace)' }}>Sem oportunidades criadas este mês</div>
            ) : (
              <table style={{ width:'100%', borderCollapse:'collapse', fontSize:12.5 }}>
                <thead>
                  <tr>
                    <th style={thS}>Lead</th>
                    <th style={thS}>Tipo</th>
                    <th style={thS}>Estado</th>
                    <th style={thS}>NIF</th>
                    <th style={thS}>Data Demo</th>
                    <th style={thS}>Passada em</th>
                    <th style={thS}></th>
                  </tr>
                </thead>
                <tbody>
                  {oppLeads.map(l => {
                    const acao = getAcaoEf(l);
                    const isDemo = acao === 'agendar_demo';
                    return (
                      <tr key={l.id} onClick={() => setOppModal(l)} style={{ borderBottom:'1px solid var(--dgd-border-1)', cursor:'pointer' }}
                        onMouseEnter={e => e.currentTarget.style.background='var(--dgd-bg-hover,#f1f5f9)'}
                        onMouseLeave={e => e.currentTarget.style.background=''}>
                        <td style={{ padding:'9px 12px' }}>
                          <div style={{ fontWeight:600, color:'var(--dgd-fg-1)' }}>{l.nome}</div>
                          <div style={{ fontSize:11.5, color:'var(--dgd-fg-3)', marginTop:1 }}>{l.empresa}</div>
                        </td>
                        <td style={{ padding:'9px 12px', whiteSpace:'nowrap' }}>
                          <span style={{ fontSize:10.5, padding:'2px 9px', borderRadius:99, fontWeight:600,
                            background: isDemo ? '#f0fdf4' : '#eff6ff',
                            color:      isDemo ? '#166534' : '#1d4ed8',
                            border:     `1px solid ${isDemo ? '#bbf7d0' : '#bfdbfe'}` }}>
                            {isDemo ? 'Qualificado para Demo' : 'Passado ao Comercial'}
                          </span>
                        </td>
                        <td style={{ padding:'9px 12px' }}>
                          {(() => {
                            const est = getOppEstado(l);
                            const aberto = est === 'aberto';
                            return (
                              <button onClick={e => { e.stopPropagation(); handleToggleOppEstado(l.id); }}
                                title="Clica para alternar"
                                style={{ padding:'2px 9px', borderRadius:99, fontWeight:600, fontSize:10.5, cursor:'pointer', border:`1px solid ${aberto ? '#bbf7d0' : '#e2e8f0'}`, background: aberto ? '#f0fdf4' : '#f8fafc', color: aberto ? '#166534' : '#64748b' }}
                              >{aberto ? 'Aberto' : 'Por Abrir'}</button>
                            );
                          })()}
                        </td>
                        <td style={{ padding:'9px 12px', fontFamily:'var(--dgd-font-mono,monospace)', fontSize:11, color:'var(--dgd-fg-2)' }}>{l.nif || '—'}</td>
                        <td style={{ padding:'9px 12px', fontFamily:'var(--dgd-font-mono,monospace)', fontSize:11, color:'var(--dgd-fg-2)' }}>{l.data_demo || '—'}</td>
                        <td style={{ padding:'9px 12px', fontFamily:'var(--dgd-font-mono,monospace)', fontSize:11, color:'var(--dgd-fg-3)' }}>{l.ultima_act || '—'}</td>
                        <td style={{ padding:'9px 12px' }} onClick={e => e.stopPropagation()}>
                          <button onClick={() => { if (window.confirm(`Restaurar ${l.nome || l.empresa} para Daily Qualification?`)) handleRestaurar(l.id); }}
                            style={{ padding:'3px 10px', borderRadius:6, border:'1px solid #fde68a', background:'#fffbeb', color:'#92400e', fontSize:11, cursor:'pointer', fontWeight:500, whiteSpace:'nowrap' }}>
                            Restaurar
                          </button>
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            )}
          </div>
        )}

        {/* Modal: Oportunidade (detalhe) */}
        {oppModal && (
          <SdrOppDetailModal
            lead={{ ...oppModal, opp_estado: getOppEstado(oppModal), bant: statusMap[oppModal.id]?.bant ?? oppModal.bant ?? {}, acao: getAcaoEf(oppModal) }}
            user={user}
            onClose={() => setOppModal(null)}
            getOppEstado={getOppEstado}
            handleToggleOppEstado={handleToggleOppEstado}
            handleRestaurar={handleRestaurar}
          />
        )}

        {/* Tab: Inactivas */}
        {subTab === 'inactivas' && (
          <div style={{ overflowX:'auto' }}>
            {inativasLeads.length === 0 ? (
              <div style={{ padding:'32px 0', textAlign:'center', color:'var(--dgd-fg-3)', fontSize:12, fontFamily:'var(--dgd-font-mono,monospace)' }}>Sem leads inactivas</div>
            ) : (
              <table style={{ width:'100%', borderCollapse:'collapse', fontSize:12.5 }}>
                <thead>
                  <tr>
                    <th style={thS}>Lead</th>
                    <th style={thS}>Motivo</th>
                    <th style={thS}>Última act.</th>
                    <th style={{ ...thS, textAlign:'right' }}></th>
                  </tr>
                </thead>
                <tbody>
                  {inativasLeads.map(l => {
                    const tipo = getTipoEf(l);
                    const sc   = statusCfg[tipo] || statusCfg.parada;
                    return (
                      <tr key={l.id} style={{ borderBottom:'1px solid var(--dgd-border-1)', opacity:.7 }}>
                        <td style={{ padding:'9px 12px' }}>
                          <div style={{ fontWeight:600, color:'var(--dgd-fg-1)' }}>{l.nome}</div>
                          <div style={{ fontSize:11.5, color:'var(--dgd-fg-3)', marginTop:1 }}>{l.empresa}</div>
                        </td>
                        <td style={{ padding:'9px 12px' }}>
                          <span style={{ fontSize:11, padding:'2px 9px', borderRadius:99, fontWeight:600, color:sc.color, background:sc.bg, border:`1px solid ${sc.border}` }}>{sc.label}</span>
                        </td>
                        <td style={{ padding:'9px 12px', fontFamily:'var(--dgd-font-mono,monospace)', fontSize:11, color:'var(--dgd-fg-3)' }}>{l.ultima_act || '—'}</td>
                        <td style={{ padding:'9px 12px', textAlign:'right' }}>
                          <button onClick={() => handleReativar(l.id)}
                            style={{ padding:'4px 12px', borderRadius:6, border:'1px solid var(--dgd-border-1)', background:'var(--dgd-bg-card,white)', color:'var(--dgd-fg-2)', fontSize:11, cursor:'pointer' }}
                          >Reativar</button>
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            )}
          </div>
        )}
      </div>
    </div>
    {leadModal && (
      <SdrLeadAiModal lead={leadModal} user={user} onClose={() => setLeadModal(null)} onSaved={onLeadSaved} onArquivar={handleArquivar} />
    )}
    </>
  );
};

// ─── Guião BANT contextualizado para leads AI ────────────────────────────────
function gerarGuiaoAiLead(lead) {
  const primeiroNome = (lead.nome || '').split(' ')[0] || 'responsável';
  const empresa = lead.empresa || 'a empresa';
  const produto = lead.campanha || lead.segmento || 'a nossa solução';
  const cargo = lead.cargo || null;
  const equipAtual = lead.equipamento || null;
  const objecao = lead.objecao || null;
  const bant = lead.bant || {};
  const temBudget = bant.budget === true;
  const temAuthority = bant.authority === true;
  const temNeed = bant.need === true;
  const temTimeline = bant.timeline === true;

  const textoAuthority = temAuthority
    ? 'AI identificou decisor' + (cargo ? ' ("' + cargo + '")' : '') + '. Confirmar: "É você quem valida este tipo de aquisição, ou envolve mais alguém — sócio, financeiro?"'
    : '"Quem toma a decisão de compra' + (cargo ? ' — é você como ' + cargo : '') + ', ou há outros intervenientes? Pode incluir essa pessoa numa próxima conversa?"';

  const textoNeed = temNeed
    ? 'Necessidade confirmada. Aprofundar: "' + (equipAtual ? 'Têm actualmente ' + equipAtual + ' — quais os principais problemas: custo, velocidade, qualidade?' : 'Qual o maior problema com a solução actual?') + ' O volume mensal é suficiente para justificar ' + produto + '?"'
    : '"' + (equipAtual ? 'Têm actualmente ' + equipAtual + '. Qual o principal problema — custo operacional, capacidade, qualidade?' : 'Que solução usam actualmente e qual o maior problema?') + ' ' + produto + ' resolve directamente esse ponto."';

  const notaAuthority = temAuthority ? 'Decisor identificado' + (cargo ? ': ' + cargo : '') : 'Decisor a confirmar';

  const steps = [
    {
      label: 'Abertura',
      texto: '"Olá ' + primeiroNome + ', bom dia! Sou [nome], da Digidelta. Entrou em contacto connosco sobre ' + produto + ' — estou a ligar para perceber melhor o que procura e ver se faz sentido avançarmos. Tem 3 minutos?"',
      nota: lead.recomendacao ? 'AI: ' + lead.recomendacao : null,
    },
    {
      label: 'B — Budget',
      texto: temBudget
        ? 'AI já confirmou budget disponível. Aprofundar: "Têm o valor aprovado ou depende ainda de decisão interna? Estamos a falar de leasing/financiamento ou aquisição directa?"'
        : '"Têm orçamento previsto para este tipo de solução — ' + produto + '? Estamos a falar de um investimento na ordem de [X]€ — é algo que conseguem considerar a curto prazo?"',
      nota: temBudget ? 'Budget confirmado pela Digi AI' : 'Budget não confirmado — validar',
    },
    {
      label: 'A — Authority',
      texto: textoAuthority,
      nota: notaAuthority,
    },
    {
      label: 'N — Need',
      texto: textoNeed,
      nota: temNeed ? 'Necessidade confirmada pela AI' : null,
    },
    {
      label: 'T — Timeline',
      texto: temTimeline
        ? '"A AI indicou que têm urgência. Quando seria o momento ideal para uma demo técnica — esta semana ou a próxima?"'
        : '"Se os números fizerem sentido, qual o horizonte — Q4, início de 2025? Têm algum prazo condicionante (obra, evento, contrato a renovar)?"',
      nota: temTimeline ? 'Timeline identificada pela AI' : 'Timeline a confirmar',
    },
    {
      label: 'Fecho',
      texto: '"Com base no que partilhou, faz sentido avançar para uma demo de 30-45 min com o nosso técnico — sem compromisso. Posso agendar para esta semana?"',
      nota: 'Registar data/hora e enviar confirmação por email',
    },
  ];

  if (objecao) {
    steps.splice(5, 0, {
      label: 'Objecção Esperada',
      texto: 'A Digi AI identificou esta objecção: "' + objecao + '"\n\nAbordagem: reconhecer, validar e redirigir — "Percebo. Muitos dos nossos clientes tinham a mesma preocupação antes de verem os números. Posso mostrar-lhe um caso semelhante à ' + empresa + '?"',
      nota: 'Preparar resposta antes de ligar',
      alerta: true,
    });
  }

  return steps;
}

// ─── Guião BANT (gerado client-side) ─────────────────────────────────────────
function gerarGuiaoBant(empresa, contacto, campanhaNome, briefing, userName) {
  const nome = contacto?.nome_completo?.split(' ')[0] || 'responsável';
  const seg = empresa?.segmento || empresa?.industria || 'artes gráficas';
  const cidade = empresa?.cidade || '';
  const empNome = empresa?.nome || 'empresa';

  // Dados do briefing (quando disponível)
  const b = briefing || {};
  const produto = b.commercial_name || b.product_name || empresa?.marca_alvo || campanhaNome || 'a nossa solução';
  const marca = b.marca_name || empresa?.marca_alvo || '';
  const pitch = b.elevator_pitch || '';
  const usps = Array.isArray(b.usps) ? b.usps.filter(Boolean) : [];
  const painPoints = Array.isArray(b.pain_points) ? b.pain_points.filter(Boolean) : [];
  const objections = Array.isArray(b.objections) ? b.objections.filter(Boolean) : [];
  const decisionMaker = b.decision_maker || '';
  const purchaseTrigger = b.purchase_trigger || '';
  const offer = b.commercial_offer || '';
  const diffArgs = Array.isArray(b.differentiation_args) ? b.differentiation_args.filter(Boolean) : [];
  const keyMsg = b.key_message || '';

  // Abertura
  const sdrNome = userName || 'a equipa Digidelta';
  let aberturaText = `Olá ${nome}, bom dia! Chamo-me ${sdrNome}, da Digidelta${cidade ? ` — falamos sobre a ${empNome} em ${cidade}` : ''}.`;
  if (pitch) {
    aberturaText += `\n\n${pitch}`;
  } else {
    aberturaText += `\n\nEstamos a contactar empresas na área de ${seg} sobre ${produto}. Tem 3 minutos?`;
  }
  if (keyMsg) aberturaText += `\n\nMensagem-chave: ${keyMsg}`;

  // Budget
  let budgetText = `"Têm orçamento previsto para este tipo de investimento — ${produto}?"`;
  budgetText += `\n\n→ Se sim: "Qual o intervalo aproximado que estão a considerar?"`;
  budgetText += `\n→ Se não: "O que impede neste momento — prioridade ou ciclo de investimento?"`;
  if (offer) budgetText += `\n\nOferta comercial: ${offer}`;
  if (purchaseTrigger) budgetText += `\nTrigger de compra: ${purchaseTrigger}`;

  // Authority
  let authText = `"Quem toma a decisão de compra na ${empNome}? É você ou envolve mais alguém — financeiro, sócio-gerente?"`;
  if (decisionMaker) authText += `\n\nPerfil decisor típico: ${decisionMaker}`;
  authText += `\n\n→ Identificar decisor se não for o contacto actual.`;
  authText += `\n→ "Posso agendar uma conversa que inclua esse decisor?"`;

  // Need
  let needText = '';
  if (painPoints.length) {
    needText += `Dores típicas do segmento:\n${painPoints.map(p => `• ${p}`).join('\n')}\n\n`;
    needText += `Perguntar: "Identificam-se com alguma destas situações?"`;
  } else {
    needText += `"Quais os maiores desafios que têm hoje na área de ${seg}?"`;
  }
  if (usps.length) {
    needText += `\n\nComo respondemos (USPs):\n${usps.map(u => `✓ ${u}`).join('\n')}`;
  }
  if (diffArgs.length) {
    needText += `\n\nDiferenciação:\n${diffArgs.map(d => `→ ${d}`).join('\n')}`;
  }

  // Timeline
  let timeText = `"Se os números fizerem sentido, qual seria o horizonte para avançar?"`;
  timeText += `\n\n→ Se urgência: marcar demo presencial.`;
  timeText += `\n→ Se longo prazo: nurturing email + follow-up em 30 dias.`;

  // Fecho
  let fechoText = `"O próximo passo seria uma demonstração com o nosso especialista — posso marcar para a próxima semana?"`;
  fechoText += `\n\n→ Registar data/hora no CRM e enviar confirmação por email.`;

  // Objeções (bloco extra se disponível)
  const sections = [
    { label:'Abertura', text: aberturaText },
    { label:'B — Budget', text: budgetText },
    { label:'A — Authority', text: authText },
    { label:'N — Need', text: needText },
    { label:'T — Timeline', text: timeText },
  ];
  if (objections.length) {
    sections.push({ label:'Objeções Comuns', text: objections.map(o => `• ${o}`).join('\n') });
  }
  sections.push({ label:'Fecho', text: fechoText });
  return sections;
}

// ─── Formata avaliação completa de chamada para guardar como nota ─────────────
function formatarAvaliacaoChamada(d) {
  const linhas = [];
  const ts = new Date().toLocaleString('pt-PT', { day:'2-digit', month:'2-digit', hour:'2-digit', minute:'2-digit' });
  linhas.push(`[CHAMADA AI · ${ts}]`);
  if (d.resumo || d.notas) linhas.push(d.resumo || d.notas);
  if (d.scoring && typeof d.scoring === 'object') {
    const NOMES = { abertura:'Abertura', campanha:'Campanha', foco:'Foco', escuta:'Escuta', fecho:'Fecho' };
    const scores = Object.entries(NOMES)
      .filter(([k]) => d.scoring[k] !== undefined)
      .map(([k, label]) => `${label}: ${d.scoring[k] === true ? '✓' : d.scoring[k] === false ? '✗' : '?'}`)
      .join(' | ');
    if (scores) linhas.push(`Scoring: ${scores}`);
  }
  if (Array.isArray(d.sugestoes) && d.sugestoes.length) {
    linhas.push('Sugestões:\n' + d.sugestoes.map(s => `• ${s}`).join('\n'));
  }
  return linhas.join('\n\n');
}

// ─── SdrCallWidget — Twilio Voice inline no BANT modal ────────────────────────
// Estados: idle → a-ligar → em-chamada → a-fechar → resultado
const SdrCallWidget = ({ prospect, campanhaNome, onResult, user }) => {
  const [estado, setEstado]         = React.useState('idle');       // idle|verificar|a-ligar|em-chamada|a-fechar|resultado|erro
  const [telDestino, setTelDestino] = React.useState('');
  const [callerLabel, setCaller]    = React.useState('');
  const [callDevice, setDevice]     = React.useState(null);
  const [callConn, setConn]         = React.useState(null);
  const [transcript, setTranscript] = React.useState([]);           // [{lado, text}]
  const [campos, setCampos]         = React.useState(null);         // extracção ao vivo
  const [resultado, setResultado]   = React.useState(null);         // fecho
  const [erroMsg, setErro]          = React.useState('');
  const [durSeg, setDur]            = React.useState(0);
  const [callSid, setCallSid]       = React.useState(null);
  const [transcricaoFinal, setTranscricaoFinal] = React.useState('');
  const [showTranscricao, setShowTranscricao]   = React.useState(false);
  const durTimer = React.useRef(null);
  const durStart = React.useRef(null);
  const extrairTimer = React.useRef(null);
  const streamRefs = React.useRef({ sdr: null, lead: null });
  const transcriptRef = React.useRef([]);  // ref para evitar stale closure no disconnect

  // Número do contacto principal
  const contactoPrincipal = prospect?.contactos?.[0];
  const telContacto = contactoPrincipal?.telemovel || '';

  React.useEffect(() => {
    if (telContacto) setTelDestino(telContacto);
  }, [telContacto]);

  // Cleanup ao desmontar
  React.useEffect(() => {
    return () => {
      clearInterval(durTimer.current);
      clearInterval(extrairTimer.current);
      if (callConn) try { callConn.disconnect(); } catch (_) {}
      if (callDevice) try { callDevice.destroy(); } catch (_) {}
      Object.values(streamRefs.current).forEach(s => { if (s) try { s.stop(); } catch (_) {} });
    };
  }, []);

  function addLinha(lado, text) {
    if (!text?.trim()) return;
    const linha = { lado, text: text.trim() };
    transcriptRef.current = [...transcriptRef.current, linha];
    setTranscript(p => [...p, linha]);
  }

  function transcritoConcatenado() {
    return transcriptRef.current.map(l => `${l.lado === 'lead' ? 'Lead' : 'SDR'}: ${l.text}`).join('\n');
  }

  // Enviar chunk WAV para /trecho
  async function enviarTrecho(buffer, lado) {
    const RMS_MIN = 0.012;
    // Calcular RMS simples
    const view = new DataView(buffer);
    let sum = 0;
    const count = Math.floor((buffer.byteLength - 44) / 2);
    for (let i = 44; i < buffer.byteLength - 1; i += 2) {
      const s = view.getInt16(i, true) / 32768;
      sum += s * s;
    }
    const rms = count > 0 ? Math.sqrt(sum / count) : 0;
    if (rms < RMS_MIN) return;
    const fd = new FormData();
    fd.append('audio', new Blob([buffer], { type: 'audio/wav' }), 'trecho.wav');
    fd.append('lado', lado);
    fetch('/api/comercial/sdr/chamada/trecho', { method: 'POST', credentials: 'include', body: fd })
      .then(r => r.json())
      .then(d => { if (d.text) addLinha(d.lado, d.text); })
      .catch(() => {});
  }

  // Gravar canal de áudio em chunks de 4s
  function iniciarStream(track, lado) {
    try {
      const ctx = new AudioContext({ sampleRate: 16000 });
      if (ctx.state === 'suspended') ctx.resume();
      const src = ctx.createMediaStreamSource(new MediaStream([track]));
      const scriptNode = ctx.createScriptProcessor(4096, 1, 1);
      const chunks = [];
      let chunkSamples = 0;
      const CHUNK_SAMPLES = 16000 * 15; // 15 segundos

      scriptNode.onaudioprocess = e => {
        const data = e.inputBuffer.getChannelData(0);
        chunks.push(new Float32Array(data));
        chunkSamples += data.length;
        if (chunkSamples >= CHUNK_SAMPLES) {
          // Montar WAV
          const total = chunks.reduce((s, c) => s + c.length, 0);
          const buf = new ArrayBuffer(44 + total * 2);
          const dv  = new DataView(buf);
          const write = (o, s) => { for (let i = 0; i < s.length; i++) dv.setUint8(o + i, s.charCodeAt(i)); };
          write(0, 'RIFF'); dv.setUint32(4, 36 + total * 2, true);
          write(8, 'WAVE'); write(12, 'fmt ');
          dv.setUint32(16, 16, true); dv.setUint16(20, 1, true); dv.setUint16(22, 1, true);
          dv.setUint32(24, 16000, true); dv.setUint32(28, 32000, true);
          dv.setUint16(32, 2, true); dv.setUint16(34, 16, true);
          write(36, 'data'); dv.setUint32(40, total * 2, true);
          let offset = 44;
          for (const c of chunks) {
            for (const s of c) {
              const v = Math.max(-1, Math.min(1, s));
              dv.setInt16(offset, v < 0 ? v * 0x8000 : v * 0x7FFF, true);
              offset += 2;
            }
          }
          enviarTrecho(buf, lado);
          chunks.length = 0;
          chunkSamples  = 0;
        }
      };
      src.connect(scriptNode);
      scriptNode.connect(ctx.destination);
      const flush = async () => {
        if (chunkSamples < 4096) return;
        const total = chunks.reduce((s, c) => s + c.length, 0);
        const buf = new ArrayBuffer(44 + total * 2);
        const dv  = new DataView(buf);
        const write = (o, s) => { for (let i = 0; i < s.length; i++) dv.setUint8(o + i, s.charCodeAt(i)); };
        write(0, 'RIFF'); dv.setUint32(4, 36 + total * 2, true);
        write(8, 'WAVE'); write(12, 'fmt ');
        dv.setUint32(16, 16, true); dv.setUint16(20, 1, true); dv.setUint16(22, 1, true);
        dv.setUint32(24, 16000, true); dv.setUint32(28, 32000, true);
        dv.setUint16(32, 2, true); dv.setUint16(34, 16, true);
        write(36, 'data'); dv.setUint32(40, total * 2, true);
        let off = 44;
        for (const c of chunks) { for (const s of c) { const v = Math.max(-1, Math.min(1, s)); dv.setInt16(off, v < 0 ? v * 0x8000 : v * 0x7FFF, true); off += 2; } }
        chunks.length = 0; chunkSamples = 0;
        try {
          const fd = new FormData();
          fd.append('audio', new Blob([buf], { type: 'audio/wav' }), 'trecho.wav');
          fd.append('lado', lado);
          const r = await fetch('/api/comercial/sdr/chamada/trecho', { method: 'POST', credentials: 'include', body: fd });
          const d = await r.json();
          if (d.text) addLinha(d.lado, d.text);
        } catch (_) {}
      };
      streamRefs.current[lado] = { flush, stop: () => { try { scriptNode.disconnect(); src.disconnect(); ctx.close(); } catch (_) {} } };
    } catch (_) {}
  }

  // Extracção ao vivo (a cada 15s durante a chamada)
  function iniciarExtraccaoVivo() {
    clearInterval(extrairTimer.current);
    extrairTimer.current = setInterval(() => {
      const t = transcritoConcatenado();
      if (t.length < 30) return;
      fetch('/api/comercial/sdr/chamada/extrair', {
        method: 'POST', credentials: 'include',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          transcricao:   t,
          empresa:       prospect.empresa,
          contacto:      contactoPrincipal?.nome_completo || '',
          campanha_nome: campanhaNome,
          ficha_md:      prospect.ficha_md || '',
        }),
      }).then(r => r.json()).then(d => { if (!d.vazio) setCampos(d); }).catch(() => {});
    }, 15000);
  }

  async function ligar() {
    const tel = telDestino.trim().replace(/[\s\-().]/g, '');
    if (!tel) { setErro('Introduz o número de telefone do contacto.'); return; }
    setEstado('a-ligar'); setErro('');
    setTranscript([]); transcriptRef.current = [];
    setCampos(null); setResultado(null);
    try {
      const tokenRes = await fetch('/api/comercial/sdr/chamada/token', {
        method: 'POST', credentials: 'include',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          para:          tel,
          campanha_id:   prospect.campanha_id,
          campanha_nome: campanhaNome,
          prospect_id:   String(prospect.id || ''),
          empresa:       prospect.empresa,
          contacto:      contactoPrincipal?.nome_completo || '',
        }),
      });
      const tokenData = await tokenRes.json();
      if (!tokenRes.ok) throw new Error(tokenData.error || 'Erro ao obter token');
      setCaller(tokenData.caller || '');

      const Device = window.Twilio?.Device;
      if (!Device) throw new Error('SDK Twilio não carregado');
      const device = new Device(tokenData.token, { edge: 'roaming', logLevel: 1 });
      await device.register();
      setDevice(device);

      device.on('error', e => {
        setErro('Erro Twilio: ' + (e.message || String(e)));
        setEstado('erro');
        clearInterval(durTimer.current);
        clearInterval(extrairTimer.current);
      });

      const conn = await device.connect({ params: { chamadaId: tokenData.chamadaId } });
      setConn(conn);
      setEstado('em-chamada');
      durStart.current = Date.now();
      setDur(0);
      durTimer.current = setInterval(() => setDur(Math.floor((Date.now() - durStart.current) / 1000)), 1000);

      // Streams de áudio — canal local (SDR) e remoto (Lead)
      conn.on('volume', () => {}); // mantém o stream activo

      // Canal SDR (microfone local)
      try {
        const localStream = await navigator.mediaDevices.getUserMedia({ audio: true });
        const localTrack  = localStream.getAudioTracks()[0];
        if (localTrack) iniciarStream(localTrack, 'sdr');
      } catch (_) {}

      // Canal Lead — só capturar após accept (quando o destino atende)
      let remoteCapturado = false;
      let remoteRetryInterval = null;
      const tryRemote = () => {
        if (remoteCapturado) return;
        const remoteStream = conn.getRemoteStream && conn.getRemoteStream();
        if (remoteStream) {
          const remoteTrack = remoteStream.getAudioTracks()[0];
          if (remoteTrack) { iniciarStream(remoteTrack, 'lead'); remoteCapturado = true; clearInterval(remoteRetryInterval); }
        }
      };

      // Obter callSid e iniciar captura do lead apenas quando atende
      conn.on('accept', c => {
        const sid = c?.parameters?.CallSid || null;
        if (sid) setCallSid(sid);
        tryRemote();
        remoteRetryInterval = setInterval(() => { tryRemote(); }, 1000);
        setTimeout(() => clearInterval(remoteRetryInterval), 15000);
      });
      conn.on('ringing', () => {});

      iniciarExtraccaoVivo();

      conn.on('disconnect', async () => {
        clearInterval(durTimer.current);
        clearInterval(extrairTimer.current);
        clearInterval(remoteRetryInterval);
        await Promise.all(Object.values(streamRefs.current).map(s => s?.flush?.() || Promise.resolve()));
        Object.values(streamRefs.current).forEach(s => { if (s) try { s.stop(); } catch (_) {} });
        fecharChamada(transcritoConcatenado(), conn.parameters?.CallSid || callSid);
      });

    } catch (e) {
      setErro(e.message || 'Erro ao ligar');
      setEstado('erro');
    }
  }

  async function desligar() {
    clearInterval(durTimer.current);
    clearInterval(extrairTimer.current);
    if (callConn) try { callConn.disconnect(); } catch (_) {}
  }

  async function fecharChamada(transcricao, sid) {
    setEstado('a-fechar');
    try {
      const r = await fetch('/api/comercial/sdr/chamada/fechar', {
        method: 'POST', credentials: 'include',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          transcricao,
          callSid:       sid,
          empresa:       prospect.empresa,
          contacto:      contactoPrincipal?.nome_completo || '',
          campanha_id:   prospect.campanha_id,
          campanha_nome: campanhaNome,
          ficha_md:      prospect.ficha_md || '',
          prospect_id:   String(prospect.id || ''),
        }),
      });
      const d = await r.json();
      if (!r.ok) throw new Error(d.error);
      setResultado(d);
      setTranscricaoFinal(transcricao);
      setEstado('resultado');
      if (onResult) onResult(d);
    } catch (e) {
      setErro('Erro no fecho da chamada: ' + e.message);
      setEstado('erro');
    }
    // Relatório Twilio em background
    if (sid) {
      setTimeout(() => {
        fetch('/api/comercial/sdr/chamada/relato', {
          method: 'POST', credentials: 'include',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            callSid:       sid,
            transcricao,
            fecho:         resultado || {},
            empresa:       prospect.empresa,
            contacto:      contactoPrincipal?.nome_completo || '',
            campanha_id:   prospect.campanha_id,
            campanha_nome: campanhaNome,
            prospect_id:   String(prospect.id || ''),
          }),
        }).catch(() => {});
      }, 4000);
    }
  }

  function formatDur(s) {
    return `${Math.floor(s / 60)}:${String(s % 60).padStart(2, '0')}`;
  }

  const pill = (c, bg, b, txt) => ({ display:'inline-block', padding:'2px 8px', borderRadius:99, fontSize:10.5, fontWeight:600, color:c, background:bg, border:`1px solid ${b}`, marginRight:4 });

  // ── Render ─────────────────────────────────────────────────────────────────

  if (estado === 'idle') {
    return (
      <div style={{ marginTop:14, padding:'10px 12px', border:'1px solid var(--dgd-border-1)', borderRadius:8, background:'var(--dgd-bg,#f8fafc)' }}>
        <div style={{ display:'flex', alignItems:'center', gap:8, marginBottom:8 }}>
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="#112954" strokeWidth="2"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07A19.5 19.5 0 0 1 4.69 12a19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 3.6 1.27h3a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L7.91 8.61a16 16 0 0 0 5.48 5.48l.82-.82a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0 1 21 16.92z"/></svg>
          <span style={{ fontSize:11, fontWeight:700, color:'#112954', fontFamily:'var(--dgd-font-mono,monospace)', letterSpacing:'0.06em' }}>LIGAR</span>
        </div>
        <div style={{ display:'flex', gap:6 }}>
          <input
            type="tel"
            value={telDestino}
            onChange={e => setTelDestino(e.target.value)}
            placeholder="+351 9XX XXX XXX"
            style={{ flex:1, padding:'6px 10px', fontSize:12.5, border:'1px solid var(--dgd-border-1)', borderRadius:6, outline:'none', fontFamily:'var(--dgd-font-mono,monospace)', background:'var(--dgd-bg-surface,#fff)', color:'var(--dgd-fg-1)' }}
          />
          <button
            onClick={ligar}
            disabled={!telDestino.trim()}
            style={{ padding:'6px 16px', borderRadius:6, border:'none', background:'#112954', color:'#fff', fontSize:12.5, fontWeight:700, cursor: telDestino.trim() ? 'pointer' : 'not-allowed', opacity: telDestino.trim() ? 1 : 0.5 }}
          >Ligar</button>
        </div>
        {erroMsg && <div style={{ marginTop:6, fontSize:11.5, color:'#dc2626' }}>{erroMsg}</div>}
      </div>
    );
  }

  if (estado === 'a-ligar') {
    return (
      <div style={{ marginTop:14, padding:'12px', border:'1px solid #bfdbfe', borderRadius:8, background:'#eff6ff', display:'flex', alignItems:'center', gap:8 }}>
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#1d4ed8" strokeWidth="2"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
        <span style={{ fontSize:12.5, color:'#1d4ed8', fontWeight:600 }}>A ligar...</span>
      </div>
    );
  }

  if (estado === 'em-chamada') {
    const bantVivo = campos?.bant || {};
    return (
      <div style={{ marginTop:14, border:'2px solid #16a34a', borderRadius:8, overflow:'hidden' }}>
        {/* Header chamada */}
        <div style={{ background:'#16a34a', padding:'8px 14px', display:'flex', alignItems:'center', justifyContent:'space-between' }}>
          <div style={{ display:'flex', alignItems:'center', gap:8 }}>
            <span style={{ width:8, height:8, borderRadius:'50%', background:'#fff', animation:'pulse 1s infinite', display:'inline-block' }} />
            <span style={{ fontSize:12, fontWeight:700, color:'#fff' }}>EM CHAMADA · {formatDur(durSeg)}</span>
            {callerLabel && <span style={{ fontSize:10.5, color:'rgba(255,255,255,0.8)' }}>de {callerLabel}</span>}
          </div>
          <button
            onClick={desligar}
            style={{ padding:'4px 12px', borderRadius:99, border:'2px solid rgba(255,255,255,0.6)', background:'rgba(255,0,0,0.25)', color:'#fff', fontSize:12, fontWeight:700, cursor:'pointer' }}
          >Desligar</button>
        </div>
        {/* Transcrição ao vivo */}
        <div style={{ maxHeight:180, overflowY:'auto', padding:'10px 14px', background:'#f0fdf4', borderBottom:'1px solid #bbf7d0' }}>
          {transcript.length === 0
            ? <div style={{ color:'#166534', fontSize:12, opacity:0.6 }}>Aguardar áudio...</div>
            : transcript.map((l, i) => (
              <div key={i} style={{ marginBottom:3 }}>
                <span style={{ fontSize:10.5, fontWeight:700, fontFamily:'var(--dgd-font-mono,monospace)', color: l.lado === 'sdr' ? '#112954' : '#166534', marginRight:6 }}>{l.lado === 'sdr' ? 'SDR' : 'LEAD'}:</span>
                <span style={{ fontSize:12.5, color:'var(--dgd-fg-1)' }}>{l.text}</span>
              </div>
            ))
          }
        </div>
        {/* BANT ao vivo */}
        {campos && (
          <div style={{ padding:'8px 14px', background:'var(--dgd-bg,#f8fafc)', display:'flex', gap:6, alignItems:'center', flexWrap:'wrap' }}>
            <span style={{ fontSize:10.5, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', fontWeight:600, marginRight:4 }}>BANT VIVO</span>
            {[['B', bantVivo.budget], ['A', bantVivo.authority], ['N', bantVivo.need], ['T', bantVivo.timeline]].map(([k, v]) => {
              const c  = v === true ? '#166534' : v === false ? '#991b1b' : '#94a3b8';
              const bg = v === true ? '#f0fdf4' : v === false ? '#fef2f2' : '#f1f5f9';
              return <span key={k} style={{ width:20, height:20, borderRadius:3, fontSize:9.5, fontWeight:700, fontFamily:'var(--dgd-font-mono,monospace)', display:'inline-flex', alignItems:'center', justifyContent:'center', background:bg, color:c, border:`1px solid ${c}33` }}>{k}</span>;
            })}
            {campos.qualificacao?.nif && <span style={{ ...pill('#92400e','#fffbeb','#fde68a', ''), marginLeft:8 }}>NIF: {campos.qualificacao.nif}</span>}
          </div>
        )}
      </div>
    );
  }

  if (estado === 'a-fechar') {
    return (
      <div style={{ marginTop:14, padding:'12px', border:'1px solid #e2e8f0', borderRadius:8, background:'#f8fafc', display:'flex', alignItems:'center', gap:8 }}>
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#94a3b8" strokeWidth="2"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
        <span style={{ fontSize:12.5, color:'var(--dgd-fg-3)' }}>A analisar a chamada com Claude...</span>
      </div>
    );
  }

  if (estado === 'resultado' && resultado) {
    const b = resultado.bant || {};
    const av = resultado.avaliacao || {};
    const nif = resultado.qualificacao?.nif || null;
    return (
      <div style={{ marginTop:14, border:'1px solid #bbf7d0', borderRadius:8, overflow:'hidden' }}>
        {showTranscricao && (
          <div onClick={() => setShowTranscricao(false)} style={{ position:'fixed', inset:0, background:'rgba(0,0,0,0.45)', zIndex:9999, display:'flex', alignItems:'center', justifyContent:'center' }}>
            <div onClick={e => e.stopPropagation()} style={{ background:'white', borderRadius:10, width:'min(680px,95vw)', maxHeight:'80vh', display:'flex', flexDirection:'column', boxShadow:'0 8px 32px rgba(0,0,0,0.18)' }}>
              <div style={{ padding:'12px 16px', borderBottom:'1px solid var(--dgd-border-1)', display:'flex', alignItems:'center', justifyContent:'space-between' }}>
                <span style={{ fontSize:13, fontWeight:700, color:'var(--dgd-fg-1)', fontFamily:'var(--dgd-font-mono,monospace)' }}>TRANSCRIÇÃO</span>
                <button onClick={() => setShowTranscricao(false)} style={{ background:'transparent', border:'none', cursor:'pointer', fontSize:18, color:'var(--dgd-fg-3)', lineHeight:1 }}>×</button>
              </div>
              <div style={{ padding:'16px', overflowY:'auto', flex:1 }}>
                {transcricaoFinal ? transcricaoFinal.split('\n').filter(Boolean).map((linha, i) => {
                  const isSdr  = /^SDR\s*:/i.test(linha);
                  const isLead = /^Lead\s*:/i.test(linha);
                  return (
                    <div key={i} style={{ marginBottom:6, display:'flex', gap:8 }}>
                      <span style={{ fontSize:10.5, fontWeight:700, fontFamily:'var(--dgd-font-mono,monospace)', color: isSdr ? '#1d4ed8' : isLead ? '#166534' : 'var(--dgd-fg-3)', minWidth:36, flexShrink:0 }}>
                        {isSdr ? 'SDR' : isLead ? 'LEAD' : ''}
                      </span>
                      <span style={{ fontSize:12.5, color:'var(--dgd-fg-1)', lineHeight:1.5 }}>{linha.replace(/^(SDR|Lead)\s*:\s*/i, '')}</span>
                    </div>
                  );
                }) : <div style={{ fontSize:12.5, color:'var(--dgd-fg-3)', fontStyle:'italic' }}>Sem transcrição disponível.</div>}
              </div>
            </div>
          </div>
        )}
        <div style={{ background:'#f0fdf4', padding:'8px 14px', borderBottom:'1px solid #bbf7d0', display:'flex', alignItems:'center', justifyContent:'space-between' }}>
          <span style={{ fontSize:11.5, fontWeight:700, color:'#166534', fontFamily:'var(--dgd-font-mono,monospace)' }}>CHAMADA CONCLUÍDA · RESULTADOS</span>
          <div style={{ display:'flex', gap:10, alignItems:'center' }}>
            {transcricaoFinal && <button onClick={() => setShowTranscricao(true)} style={{ fontSize:10.5, color:'#166534', background:'transparent', border:'1px solid #bbf7d0', borderRadius:5, padding:'2px 8px', cursor:'pointer', fontWeight:600 }}>Ver transcrição</button>}
            <button onClick={() => setEstado('idle')} style={{ fontSize:10.5, color:'#166534', background:'transparent', border:'none', cursor:'pointer', textDecoration:'underline' }}>Nova chamada</button>
          </div>
        </div>
        <div style={{ padding:'12px 14px' }}>
          {resultado.resumo && <div style={{ fontSize:12.5, color:'var(--dgd-fg-1)', marginBottom:10, lineHeight:1.5 }}>{resultado.resumo}</div>}
          {/* BANT sugerido */}
          <div style={{ marginBottom:8 }}>
            <div style={{ fontSize:10.5, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', fontWeight:600, marginBottom:4 }}>BANT SUGERIDO</div>
            <div style={{ display:'flex', gap:4 }}>
              {[['B','budget'],['A','authority'],['N','need'],['T','timeline']].map(([k, key]) => {
                const v = b[key]; const c = v === true ? '#166534' : v === false ? '#991b1b' : '#94a3b8'; const bg = v === true ? '#f0fdf4' : v === false ? '#fef2f2' : '#f1f5f9';
                return <span key={k} style={{ width:22, height:22, borderRadius:4, fontSize:10, fontWeight:700, fontFamily:'var(--dgd-font-mono,monospace)', display:'inline-flex', alignItems:'center', justifyContent:'center', background:bg, color:c, border:`1px solid ${c}44` }}>{k}</span>;
              })}
              {nif && <span style={{ ...pill('#92400e','#fffbeb','#fde68a'), marginLeft:8 }}>NIF: {nif}</span>}
            </div>
          </div>
          {/* Scoring */}
          {Object.keys(av).length > 0 && (
            <div style={{ marginBottom:8 }}>
              <div style={{ fontSize:10.5, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', fontWeight:600, marginBottom:4 }}>SCORING</div>
              <div style={{ display:'flex', gap:6, flexWrap:'wrap' }}>
                {[['Abertura','abertura'],['Campanha','campanha'],['Foco','foco'],['Escuta','escuta'],['Fecho','fecho']].map(([l, k]) => {
                  const v = av[k]; const c = v === true ? '#166534' : v === false ? '#dc2626' : '#94a3b8'; const bg = v === true ? '#f0fdf4' : v === false ? '#fef2f2' : '#f1f5f9';
                  return <span key={k} style={{ padding:'2px 8px', borderRadius:99, fontSize:10.5, fontWeight:600, color:c, background:bg, border:`1px solid ${c}44` }}>{l}</span>;
                })}
              </div>
            </div>
          )}
          {/* Dicas */}
          {resultado.sugestoes?.length > 0 && (
            <div style={{ marginBottom:8 }}>
              <div style={{ fontSize:10.5, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', fontWeight:600, marginBottom:4 }}>DICAS</div>
              {resultado.sugestoes.map((s, i) => <div key={i} style={{ fontSize:12, color:'var(--dgd-fg-2)', marginBottom:2 }}>· {s}</div>)}
            </div>
          )}
          {/* Notas */}
          {resultado.notas && <div style={{ fontSize:12, color:'var(--dgd-fg-2)', padding:'8px', background:'var(--dgd-bg,#f8fafc)', borderRadius:6, fontStyle:'italic' }}>{resultado.notas}</div>}
        </div>
      </div>
    );
  }

  if (estado === 'erro') {
    return (
      <div style={{ marginTop:14, padding:'10px 12px', border:'1px solid #fca5a5', borderRadius:8, background:'#fee2e2', display:'flex', alignItems:'center', justifyContent:'space-between', gap:8 }}>
        <span style={{ fontSize:12.5, color:'#dc2626' }}>{erroMsg || 'Erro na chamada'}</span>
        <button onClick={() => { setEstado('idle'); setErro(''); }} style={{ fontSize:11.5, color:'#dc2626', background:'transparent', border:'none', cursor:'pointer', textDecoration:'underline', whiteSpace:'nowrap' }}>Tentar novamente</button>
      </div>
    );
  }

  return null;
};

// ─── Modal BANT ───────────────────────────────────────────────────────────────
const SdrBantModal = ({ prospect, campanhaNome, onClose, onSaved, user }) => {
  const [data, setData]       = React.useState(null);
  const [briefing, setBriefing] = React.useState(null);
  const [loading, setLoading] = React.useState(true);
  const [err, setErr]         = React.useState('');
  const [bant, setBant]         = React.useState({ budget:null, authority:null, need:null, timeline:null });
  const [notas, setNotas]       = React.useState('');
  const [nifCliente, setNif]    = React.useState('');
  const [distrito, setDistrito] = React.useState('');
  const [cpPostal, setCp]       = React.useState('');
  const [localidade, setLocal]  = React.useState('');
  const [concelho, setConcelho] = React.useState('');
  const [saveState, setSave]  = React.useState('idle'); // idle | saving | saved | error
  const [showAguardar, setShowAguardar] = React.useState(false);
  const [nextDate, setNextDate] = React.useState('');
  const [passadoComercial, setPassadoComercial] = React.useState(false);
  const [tab, setTab]         = React.useState('empresa'); // empresa | guiao | campanha | notas | fm | chamadas
  const [chamadas, setChamadas]           = React.useState(null); // null=não carregado
  const [chamadasLoading, setChamadasLoading] = React.useState(false);
  const [chamadaTranscricao, setChamadaTranscricao] = React.useState(null); // {transcricao, contacto, created_at}
  const [recState, setRec]    = React.useState('idle'); // idle | recording | transcribing
  const [recErr, setRecErr]   = React.useState('');
  const mediaRef  = React.useRef(null);
  const chunksRef = React.useRef([]);
  // FM Sync state
  const [fmOppId,  setFmOppId]  = React.useState('');
  const [fmSave,   setFmSave]   = React.useState('idle');
  const [fmLookup, setFmLookup] = React.useState('idle'); // idle|loading|done|error
  const [fmOps,    setFmOps]    = React.useState([]);
  const [fmManual, setFmManual] = React.useState(false);
  const [oppDetailData, setOppDetailData] = React.useState(null);
  const nifClienteRef = React.useRef(nifCliente);
  React.useEffect(() => { nifClienteRef.current = nifCliente; }, [nifCliente]);

  // Auto-lookup quando abre tab FM com fmOppId já guardado
  React.useEffect(() => {
    if (tab !== 'fm' || fmLookup !== 'idle') return;
    const nif = nifClienteRef.current;
    const url = '/api/comercial/sdr/fm-opp-lookup?empresa=' + encodeURIComponent(prospect.empresa) + '&tenant=PT&days=365' + (nif ? '&nif=' + encodeURIComponent(nif) : '');
    setFmLookup('loading'); setFmOps([]);
    fetch(url, { credentials:'include' }).then(r => r.json()).then(d => {
      setFmOps(Array.isArray(d) ? d : []);
      setFmLookup('done');
    }).catch(() => setFmLookup('error'));
  }, [tab]);

  React.useEffect(() => {
    setLoading(true); setErr('');
    const fetches = [
      fetch(`/api/comercial/sdr/prospect/${prospect.id}`, { credentials:'include' }).then(r => r.json()),
      fetch(`/api/comercial/sdr/bant/${prospect.id}?empresa_nome=${encodeURIComponent(prospect.empresa)}&campanha=${encodeURIComponent(campanhaNome||'')}`, { credentials:'include' }).then(r => r.json()),
    ];
    if (prospect.campanha_id) {
      fetches.push(
        fetch(`/api/comercial/sdr/campanha-briefing/${prospect.campanha_id}`, { credentials:'include' })
          .then(r => r.ok ? r.json() : null).catch(() => null)
      );
    }
    Promise.all(fetches).then(([prospectData, saved, briefingData]) => {
      if (briefingData) setBriefing(briefingData);
      if (prospectData.error) throw new Error(prospectData.error);
      setData(prospectData);
      const emp = prospectData.empresa || {};
      if (saved) {
        setBant({ budget: saved.bant_budget, authority: saved.bant_authority, need: saved.bant_need, timeline: saved.bant_timeline });
        setNotas(saved.notas || '');
        if (saved.passado_comercial) setPassadoComercial(true);
        if (saved.fm_opp_id) setFmOppId(saved.fm_opp_id);
        if (saved.nif_cliente)    setNif(saved.nif_cliente);
        if (saved.distrito)       setDistrito(saved.distrito);
        else if (emp.distrito)    setDistrito(emp.distrito);
        if (saved.codigo_postal)  setCp(saved.codigo_postal);
        else if (emp.codigo_postal) setCp(emp.codigo_postal);
        if (saved.localidade)     setLocal(saved.localidade);
        else if (emp.cidade)      setLocal(emp.cidade);
        if (saved.concelho)       setConcelho(saved.concelho);
      } else {
        // pre-fill from prospect BD if no saved record
        if (emp.distrito)       setDistrito(emp.distrito);
        if (emp.codigo_postal)  setCp(emp.codigo_postal);
        if (emp.cidade)         setLocal(emp.cidade);
        if (emp.nif)            setNif(emp.nif);
      }
      setLoading(false);
    }).catch(e => { setErr(e.message); setLoading(false); });
  }, [prospect.id]);

  const allBantTrue = bant.budget === true && bant.authority === true && bant.need === true && bant.timeline === true;

  const handleSave = async () => {
    if (allBantTrue && !nifCliente.trim()) {
      setSave('error');
      setTimeout(() => setSave('idle'), 3000);
      return;
    }
    setSave('saving');
    try {
      const r = await fetch('/api/comercial/sdr/bant', {
        method:'POST', credentials:'include',
        headers:{ 'Content-Type':'application/json' },
        body: JSON.stringify({
          prospect_id: prospect.id,
          empresa_nome: prospect.empresa,
          campanha: campanhaNome,
          bant_budget: bant.budget, bant_authority: bant.authority,
          bant_need: bant.need, bant_timeline: bant.timeline,
          notas,
          nif_cliente:    nifCliente.trim() || null,
          distrito:       distrito.trim()   || null,
          codigo_postal:  cpPostal.trim()   || null,
          localidade:     localidade.trim() || null,
          concelho:       concelho.trim()   || null,
        }),
      });
      const d = await r.json();
      if (!r.ok) throw new Error(d.error);
      setSave('saved');
      if (onSaved) onSaved();
      setTimeout(() => setSave('idle'), 2500);
    } catch (e) {
      setSave('error');
      setTimeout(() => setSave('idle'), 3000);
    }
  };

  const startRec = async () => {
    setRecErr('');
    try {
      const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
      chunksRef.current = [];
      const mr = new MediaRecorder(stream);
      mr.ondataavailable = e => { if (e.data.size > 0) chunksRef.current.push(e.data); };
      mr.onstop = async () => {
        stream.getTracks().forEach(t => t.stop());
        setRec('transcribing');
        const blob = new Blob(chunksRef.current, { type: 'audio/webm' });
        const fd = new FormData();
        fd.append('audio', blob, 'bant-nota.webm');
        fd.append('existing_text', notas);
        fd.append('user_name', user?.name || '');
        fd.append('nome_entidade', prospect.empresa);
        try {
          const r = await fetch('/api/comercial/crm/transcribe-nota', { method:'POST', credentials:'include', body: fd });
          const d = await r.json();
          if (!r.ok) throw new Error(d.error || 'Erro na transcrição');
          if (d.nota_limpa) setNotas(d.nota_limpa);
          else if (d.text) setNotas(p => p ? `${p}\n${d.text}` : d.text);
        } catch (e) { setRecErr(e.message); }
        setRec('idle');
      };
      mr.start();
      mediaRef.current = mr;
      setRec('recording');
    } catch (e) {
      setRecErr(e.name === 'NotAllowedError' ? 'Permissão de microfone negada.' : e.message);
      setRec('idle');
    }
  };

  const stopRec = () => {
    if (mediaRef.current?.state === 'recording') mediaRef.current.stop();
  };

  const empresa  = data?.empresa;
  const contacto = data?.contactos?.[0];
  const guiao    = empresa ? gerarGuiaoBant(empresa, contacto, campanhaNome, briefing, user?.nome || user?.name) : [];

  const bantFields = [
    { key:'budget',    label:'Budget',    q:'Orçamento disponível?' },
    { key:'authority', label:'Authority', q:'É o decisor de compra?' },
    { key:'need',      label:'Need',      q:'Necessidade identificada?' },
    { key:'timeline',  label:'Timeline',  q:'Horizonte definido?' },
  ];

  const overlay = { position:'fixed', inset:0, zIndex:2000, background:'rgba(0,0,0,0.45)', display:'flex', alignItems:'center', justifyContent:'center', padding:24 };
  const card    = { width:'100%', maxWidth:860, maxHeight:'90vh', overflowY:'auto', background:'var(--dgd-bg-surface,#fff)', border:'1px solid var(--dgd-border-1,#e2e8f0)', borderRadius:12, boxShadow:'0 12px 48px rgba(0,0,0,0.22)' };
  const thS     = { padding:'7px 12px', textAlign:'left', fontSize:10.5, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', letterSpacing:'0.06em', textTransform:'uppercase', fontWeight:600, borderBottom:'1px solid var(--dgd-border-1)', background:'var(--dgd-bg,#f8fafc)' };

  return (
    <React.Fragment>
    <div style={overlay} onClick={e => { if (e.target === e.currentTarget) onClose(); }}>
      <div style={card}>
        {/* Header */}
        <div style={{ padding:'16px 20px', borderBottom:'1px solid var(--dgd-border-1)', display:'flex', alignItems:'center', gap:12 }}>
          <div style={{ flex:1 }}>
            <div style={{ fontSize:10, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', letterSpacing:'0.08em', marginBottom:3 }}>BD PROSPECÇÃO · BANT</div>
            <div style={{ fontSize:15, fontWeight:700, color:'var(--dgd-fg-1)' }}>{prospect.empresa}</div>
            {campanhaNome && <div style={{ fontSize:11.5, color:'var(--dgd-fg-3)', marginTop:2 }}>{campanhaNome}</div>}
          </div>
          <button onClick={onClose} style={{ background:'transparent', border:'none', cursor:'pointer', color:'var(--dgd-fg-3)', padding:6 }}>
            <svg width="16" height="16" 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>

        {/* Tabs */}
        <div style={{ display:'flex', gap:0, borderBottom:'1px solid var(--dgd-border-1)', background:'var(--dgd-bg,#f8fafc)' }}>
          {[['empresa','Empresa & Contacto'],['guiao','Guião BANT'],['campanha','Briefing Campanha'],['notas','Notas'],['fm','FM Sync'],['chamadas','Chamadas']].map(([t,l]) => (
            <button key={t} onClick={() => {
              setTab(t);
              if (t === 'chamadas' && chamadas === null && !chamadasLoading) {
                setChamadasLoading(true);
                fetch(`/api/comercial/sdr/chamada/historico?prospect_id=${encodeURIComponent(prospect.id)}`, { credentials:'include' })
                  .then(r => r.json()).then(d => { setChamadas(Array.isArray(d) ? d : []); setChamadasLoading(false); })
                  .catch(() => { setChamadas([]); setChamadasLoading(false); });
              }
            }} style={{ padding:'10px 18px', border:'none', borderBottom: tab===t ? '2px solid #112954' : '2px solid transparent', background:'transparent', fontSize:12.5, fontWeight:tab===t?700:400, color:tab===t?'#112954':'var(--dgd-fg-2)', cursor:'pointer', transition:'all 0.1s' }}>{l}</button>
          ))}
        </div>

        {/* Body */}
        <div style={{ padding:20 }}>
          {loading && <div style={{ textAlign:'center', padding:40, color:'var(--dgd-fg-3)', fontSize:13 }}>A carregar dados da BD prospecção...</div>}
          {err && <div style={{ padding:16, background:'#fee2e2', border:'1px solid #fca5a5', borderRadius:8, color:'#991b1b', fontSize:13 }}>{err}</div>}

          {!loading && !err && data && (
            <>
              {/* TAB: Empresa & Contacto */}
              {tab === 'empresa' && (
                <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:16 }}>
                  {(prospect.resposta_preview || prospect.estado === 'respondeu' || prospect.estado === 'empresa_com_lead' || prospect.estado === 'so_base') && (
                    <div style={{ gridColumn:'1 / -1', padding:'10px 12px', borderRadius:8, background: prospect.estado === 'empresa_com_lead' ? '#fff7ed' : '#f0fdf4', border: prospect.estado === 'empresa_com_lead' ? '1px solid #fdba74' : '1px solid #bbf7d0' }}>
                      <div style={{ fontSize:10.5, fontFamily:'var(--dgd-font-mono,monospace)', fontWeight:700, letterSpacing:'0.06em', textTransform:'uppercase', color:'#166534', marginBottom:6 }}>
                        {prospect.estado === 'empresa_com_lead' ? 'Parou porque a empresa gerou uma lead' : prospect.estado === 'so_base' ? 'Na lista, sem sequência de email' : 'Resposta'}
                        {prospect.resposta_em ? ` · ${new Date(prospect.resposta_em).toLocaleString('pt-PT', { day:'2-digit', month:'2-digit', year:'numeric', hour:'2-digit', minute:'2-digit' })}` : ''}
                      </div>
                      {prospect.resposta_assunto && <div style={{ fontSize:12.5, fontWeight:700, color:'#112954', marginBottom:4 }}>{prospect.resposta_assunto}</div>}
                      {prospect.resposta_preview && <div style={{ fontSize:12.5, lineHeight:1.45, color:'#334155', whiteSpace:'pre-wrap' }}>{prospect.resposta_preview}</div>}
                      {prospect.estado === 'so_base' && !prospect.resposta_preview && <div style={{ fontSize:12.5, color:'#334155' }}>Este contacto foi acrescentado à mão e não recebe os emails da sequência. A data de follow-up marca-se nesta ficha.</div>}
                      {prospect.estado === 'empresa_com_lead' && !prospect.resposta_preview && <div style={{ fontSize:12.5, color:'#334155' }}>Os emails pararam. O contacto continua nesta lista para follow-up.</div>}
                    </div>
                  )}
                  {/* Empresa + Localização editável */}
                  <div>
                    <div style={{ fontSize:10.5, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', letterSpacing:'0.06em', textTransform:'uppercase', marginBottom:10, fontWeight:600 }}>Empresa</div>
                    <table style={{ width:'100%', borderCollapse:'collapse', fontSize:12.5 }}>
                      <tbody>
                        {[
                          ['Nome', empresa.nome],
                          ['Segmento', empresa.segmento || empresa.industria || '—'],
                          ['CAE', empresa.cae_desc || '—'],
                          ['Funcionários', empresa.funcionarios ? `~${empresa.funcionarios}` : '—'],
                          ['Facturação', empresa.facturacao || '—'],
                          ['Marca Alvo', empresa.marca_alvo || '—'],
                          ['Website', empresa.website ? <a href={empresa.website} target="_blank" rel="noreferrer" style={{ color:'#112954' }}>{empresa.website.replace(/^https?:\/\//,'')}</a> : '—'],
                          ['Telefone', empresa.telefone || '—'],
                        ].map(([k, v]) => (
                          <tr key={k}>
                            <td style={{ ...thS, background:'transparent', border:'none', borderBottom:'1px solid var(--dgd-border-1)', paddingLeft:0, width:110 }}>{k}</td>
                            <td style={{ padding:'7px 0', borderBottom:'1px solid var(--dgd-border-1)', color:'var(--dgd-fg-1)' }}>{v}</td>
                          </tr>
                        ))}
                      </tbody>
                    </table>

                    {/* Localização — campos editáveis guardados no BANT report */}
                    <div style={{ marginTop:14, padding:'12px 14px', background:'var(--dgd-bg,#f8fafc)', border:'1px solid var(--dgd-border-1)', borderRadius:8 }}>
                      <div style={{ fontSize:10.5, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', letterSpacing:'0.06em', textTransform:'uppercase', marginBottom:10, fontWeight:600 }}>Localização</div>
                      <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:6 }}>
                        {[
                          ['Cód. Postal', cpPostal, setCp, '0000-000'],
                          ['Localidade',  localidade, setLocal, 'Localidade'],
                          ['Distrito',    distrito,   setDistrito, 'Distrito'],
                          ['Concelho',    concelho,   setConcelho, 'Concelho'],
                        ].map(([label, val, setter, ph]) => (
                          <div key={label} style={{ display:'flex', flexDirection:'column', gap:3 }}>
                            <span style={{ fontSize:10, fontWeight:600, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', letterSpacing:'0.05em' }}>{label}</span>
                            <input type="text" value={val} onChange={ev => setter(ev.target.value)} placeholder={ph} maxLength={80}
                              style={{ padding:'5px 8px', border:'1px solid var(--dgd-border-1)', borderRadius:5, fontSize:12.5, outline:'none', color:'var(--dgd-fg-1)', background:'var(--dgd-bg-surface,#fff)', width:'100%', boxSizing:'border-box' }} />
                          </div>
                        ))}
                      </div>
                    </div>

                    {empresa.sinais && Object.keys(empresa.sinais).length > 0 && (
                      <div style={{ marginTop:12, padding:'10px 12px', background:'#eff6ff', border:'1px solid #bfdbfe', borderRadius:6 }}>
                        <div style={{ fontSize:10.5, fontFamily:'var(--dgd-font-mono,monospace)', color:'#1d4ed8', fontWeight:600, marginBottom:4 }}>SINAIS DIGITAIS</div>
                        {empresa.sinais.gmb && <div style={{ fontSize:12 }}>⭐ Google: {empresa.sinais.gmb.rating} ({empresa.sinais.gmb.reviews} reviews)</div>}
                        {empresa.sinais.apollo?.segmento && <div style={{ fontSize:12 }}>Apollo: {empresa.sinais.apollo.segmento}</div>}
                        {empresa.sinais.crescimento && <div style={{ fontSize:12 }}>Crescimento: {empresa.sinais.crescimento}</div>}
                      </div>
                    )}
                  </div>

                  {/* Contacto inscrito */}
                  <div>
                    <div style={{ fontSize:10.5, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', letterSpacing:'0.06em', textTransform:'uppercase', marginBottom:10, fontWeight:600 }}>Contacto</div>
                    {(() => {
                      const enrolledEmail = (prospect.email || '').toLowerCase();
                      const match = data.contactos.find(c => c.email && c.email.toLowerCase() === enrolledEmail);
                      const nome = match?.nome_completo || prospect.contacto_nome || '—';
                      const cargo = match?.cargo || '';
                      const senioridade = match?.senioridade || '';
                      const papel = match?.papel || '';
                      const telemovel = match?.telemovel || '';
                      const linkedin = match?.linkedin_url || '';
                      return (
                        <div style={{ padding:'10px 12px', border:'1px solid var(--dgd-border-1)', borderRadius:8, background:'color-mix(in oklch,#112954 4%,transparent)' }}>
                          <div style={{ fontSize:9.5, fontFamily:'var(--dgd-font-mono,monospace)', color:'#112954', fontWeight:700, letterSpacing:'0.06em', marginBottom:4 }}>CONTACTO INSCRITO</div>
                          <div style={{ fontWeight:600, fontSize:13, color:'var(--dgd-fg-1)', marginBottom:2 }}>{nome}</div>
                          {(cargo || senioridade || papel) && (
                            <div style={{ fontSize:12, color:'var(--dgd-fg-2)', marginBottom:6 }}>{cargo}{senioridade ? ` · ${senioridade}` : ''}{papel ? ` · ${papel}` : ''}</div>
                          )}
                          {enrolledEmail && <div style={{ fontSize:12, color:'var(--dgd-fg-2)', marginBottom:2 }}>✉ {enrolledEmail}</div>}
                          {telemovel && <div style={{ fontSize:12, color:'var(--dgd-fg-2)', marginBottom:2 }}>☎ {telemovel}</div>}
                          {linkedin && <a href={linkedin} target="_blank" rel="noreferrer" style={{ fontSize:11.5, color:'#0a66c2' }}>LinkedIn</a>}
                        </div>
                      );
                    })()}

                    {/* BANT fill-in */}
                    <div style={{ marginTop:16 }}>
                      <div style={{ fontSize:10.5, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', letterSpacing:'0.06em', textTransform:'uppercase', marginBottom:8, fontWeight:600 }}>Qualificação BANT</div>
                      {bantFields.map(f => (
                        <div key={f.key} style={{ display:'flex', alignItems:'center', gap:10, marginBottom:6 }}>
                          <span style={{ width:68, fontSize:11, fontWeight:600, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-2)' }}>{f.label}</span>
                          {[true, false, null].map(v => {
                            const active = bant[f.key] === v;
                            const cfg = v===true ? { l:'Sim', c:'#166534', bg:'#f0fdf4', b:'#bbf7d0' } : v===false ? { l:'Não', c:'#991b1b', bg:'#fef2f2', b:'#fecaca' } : { l:'?', c:'#64748b', bg:'#f1f5f9', b:'#e2e8f0' };
                            return <button key={String(v)} onClick={() => setBant(p => ({ ...p, [f.key]:v }))} style={{ padding:'3px 10px', borderRadius:99, border:`1.5px solid ${active?cfg.b:'var(--dgd-border-1)'}`, background:active?cfg.bg:'transparent', color:active?cfg.c:'var(--dgd-fg-3)', fontSize:11, fontWeight:active?700:400, cursor:'pointer' }}>{cfg.l}</button>;
                          })}
                          <span style={{ fontSize:11, color:'var(--dgd-fg-3)', flex:1 }}>{f.q}</span>
                        </div>
                      ))}
                    {/* NIF + localização */}
                    <div style={{ marginTop:10 }}>
                      <div style={{ display:'flex', alignItems:'center', gap:8, marginTop:6, padding:'6px 10px', borderRadius:6, background: allBantTrue && !nifCliente.trim() ? '#fffbeb' : 'var(--dgd-bg,#f8fafc)', border:'1px solid ' + (allBantTrue && !nifCliente.trim() ? '#fde68a' : 'var(--dgd-border-1)') }}>
                        <span style={{ fontSize:10.5, fontWeight:600, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', letterSpacing:'0.05em', whiteSpace:'nowrap', minWidth:70 }}>NIF</span>
                        <input type="text" value={nifCliente} onChange={ev => setNif(ev.target.value)} placeholder={allBantTrue ? 'Obrigatório' : 'NIF do cliente'} maxLength={20} style={{ flex:1, border:'none', background:'transparent', fontSize:12.5, outline:'none', color:'var(--dgd-fg-1)', fontFamily:'var(--dgd-font-mono,monospace)' }} />
                        {allBantTrue && !nifCliente.trim() && <span style={{ fontSize:10, color:'#92400e', fontWeight:600, whiteSpace:'nowrap' }}>obrigatório</span>}
                      </div>
                    </div>
                    </div>

                    {/* Chamada Twilio */}
                    <SdrCallWidget
                      prospect={{ ...prospect, contactos: data?.contactos || [] }}
                      campanhaNome={campanhaNome}
                      user={user}
                      onResult={(d) => {
                        const newBant = {
                          budget:    d.bant?.budget    !== undefined ? d.bant.budget    : bant.budget,
                          authority: d.bant?.authority !== undefined ? d.bant.authority : bant.authority,
                          need:      d.bant?.need      !== undefined ? d.bant.need      : bant.need,
                          timeline:  d.bant?.timeline  !== undefined ? d.bant.timeline  : bant.timeline,
                        };
                        setBant(newBant);
                        const newNif = d.qualificacao?.nif || nifCliente;
                        if (d.qualificacao?.nif) setNif(d.qualificacao.nif);
                        const avaliacao = formatarAvaliacaoChamada(d);
                        const newNotas = avaliacao ? (notas ? `${notas}\n\n${avaliacao}` : avaliacao) : notas;
                        if (avaliacao) setNotas(newNotas);
                        // Auto-save após chamada
                        fetch('/api/comercial/sdr/bant', {
                          method:'POST', credentials:'include',
                          headers:{ 'Content-Type':'application/json' },
                          body: JSON.stringify({
                            prospect_id: prospect.id,
                            empresa_nome: prospect.empresa,
                            campanha: campanhaNome,
                            bant_budget: newBant.budget, bant_authority: newBant.authority,
                            bant_need: newBant.need, bant_timeline: newBant.timeline,
                            notas: newNotas,
                            nif_cliente:    newNif?.trim() || null,
                            distrito:       distrito.trim()   || null,
                            codigo_postal:  cpPostal.trim()   || null,
                            localidade:     localidade.trim() || null,
                            concelho:       concelho.trim()   || null,
                          }),
                        }).then(r => {
                          if (r.ok) { setSave('saved'); if (onSaved) onSaved(); setTimeout(() => setSave('idle'), 2500); }
                        }).catch(() => {});
                      }}
                    />

                    {/* Notas da chamada */}
                    <div style={{ marginTop:14 }}>
                      <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:6 }}>
                        <div style={{ fontSize:10.5, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', letterSpacing:'0.06em', textTransform:'uppercase', fontWeight:600 }}>Notas da Chamada</div>
                        <div style={{ display:'flex', alignItems:'center', gap:6 }}>
                          {recState === 'transcribing' && <span style={{ fontSize:11, color:'var(--dgd-fg-3)' }}>A transcrever...</span>}
                          {recErr && <span style={{ fontSize:11, color:'#dc2626' }}>{recErr}</span>}
                          <button
                            onClick={recState === 'recording' ? stopRec : startRec}
                            disabled={recState === 'transcribing'}
                            style={{ display:'flex', alignItems:'center', gap:5, padding:'4px 10px', borderRadius:6, border:'1px solid', fontSize:11, fontWeight:600, cursor: recState==='transcribing' ? 'not-allowed' : 'pointer', background: recState==='recording' ? '#fee2e2' : 'transparent', borderColor: recState==='recording' ? '#fca5a5' : 'var(--dgd-border-1)', color: recState==='recording' ? '#dc2626' : 'var(--dgd-fg-2)' }}
                          >
                            {recState === 'recording' ? (
                              <><span style={{ width:7, height:7, borderRadius:'50%', background:'#dc2626', animation:'pulse 1s infinite', flexShrink:0 }} />Parar</>
                            ) : (
                              <><svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/><line x1="12" y1="19" x2="12" y2="23"/><line x1="8" y1="23" x2="16" y2="23"/></svg>Gravar áudio</>
                            )}
                          </button>
                        </div>
                      </div>
                      <textarea
                        value={notas}
                        onChange={e => setNotas(e.target.value)}
                        disabled={recState === 'recording' || recState === 'transcribing'}
                        placeholder="Resumo da conversa, objeções, próximos passos... ou grava áudio para transcrição automática."
                        rows={4}
                        style={{ width:'100%', boxSizing:'border-box', padding:'8px 10px', fontSize:12.5, border:'1px solid var(--dgd-border-1)', borderRadius:6, resize:'vertical', fontFamily:'var(--dgd-font-body,sans-serif)', color:'var(--dgd-fg-1)', background: recState!=='idle' ? 'var(--dgd-bg,#f8fafc)' : 'var(--dgd-bg-surface,#fff)', outline:'none', opacity: recState==='recording' ? 0.6 : 1 }}
                      />
                    </div>
                  </div>
                </div>
              )}

              {/* TAB: Guião BANT */}
              {tab === 'guiao' && (
                <div>
                  <div style={{ fontSize:12, color:'var(--dgd-fg-3)', marginBottom:14, padding:'8px 12px', background:'#fffbeb', border:'1px solid #fde68a', borderRadius:6 }}>
                    Guião personalizado baseado nos dados da BD prospecção para <strong>{empresa.nome}</strong>.
                  </div>
                  {guiao.map((g, i) => (
                    <div key={i} style={{ marginBottom:12, border:'1px solid var(--dgd-border-1)', borderRadius:8, overflow:'hidden' }}>
                      <div style={{ padding:'8px 14px', background:'var(--dgd-bg,#f8fafc)', borderBottom:'1px solid var(--dgd-border-1)', fontSize:11.5, fontWeight:700, color:'#112954', fontFamily:'var(--dgd-font-mono,monospace)', letterSpacing:'0.04em' }}>{g.label}</div>
                      <div style={{ padding:'10px 14px', fontSize:13, color:'var(--dgd-fg-1)', lineHeight:1.6, whiteSpace:'pre-wrap' }}>{g.text}</div>
                    </div>
                  ))}
                </div>
              )}

              {/* TAB: Briefing Campanha */}
              {tab === 'campanha' && (
                <div>
                  <div style={{ marginBottom:14 }}>
                    <div style={{ fontSize:11, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', letterSpacing:'0.06em', marginBottom:4 }}>CAMPANHA ACTIVA</div>
                    <div style={{ fontSize:16, fontWeight:700, color:'var(--dgd-fg-1)' }}>{campanhaNome}</div>
                  </div>
                  <SdrBriefingBlocks campanhaId={prospect.campanha_id} fallbackMd={prospect.ficha_md} />
                </div>
              )}

              {/* TAB: Notas Troubleshooting */}
              {tab === 'notas' && (
                <SdrTroubleshootingTab prospectId={prospect.id} empresaNome={prospect.empresa} campanha={campanhaNome} contactoNome={prospect.contacto_nome} bantNotas={notas} user={user} />
              )}

              {/* TAB: Chamadas */}
              {tab === 'chamadas' && (
                <>
                  {chamadaTranscricao && (
                    <div onClick={() => setChamadaTranscricao(null)} style={{ position:'fixed', inset:0, background:'rgba(0,0,0,0.45)', zIndex:9999, display:'flex', alignItems:'center', justifyContent:'center' }}>
                      <div onClick={e => e.stopPropagation()} style={{ background:'white', borderRadius:10, width:'min(680px,95vw)', maxHeight:'80vh', display:'flex', flexDirection:'column', boxShadow:'0 8px 32px rgba(0,0,0,0.18)' }}>
                        <div style={{ padding:'12px 16px', borderBottom:'1px solid var(--dgd-border-1)', display:'flex', alignItems:'center', justifyContent:'space-between' }}>
                          <div>
                            <span style={{ fontSize:13, fontWeight:700, color:'var(--dgd-fg-1)', fontFamily:'var(--dgd-font-mono,monospace)' }}>TRANSCRIÇÃO</span>
                            <span style={{ fontSize:11, color:'var(--dgd-fg-3)', marginLeft:10 }}>{chamadaTranscricao.contacto} · {new Date(chamadaTranscricao.created_at).toLocaleString('pt-PT',{day:'2-digit',month:'2-digit',hour:'2-digit',minute:'2-digit'})}</span>
                          </div>
                          <button onClick={() => setChamadaTranscricao(null)} style={{ background:'transparent', border:'none', cursor:'pointer', fontSize:18, color:'var(--dgd-fg-3)', lineHeight:1 }}>×</button>
                        </div>
                        <div style={{ padding:'16px', overflowY:'auto', flex:1 }}>
                          {chamadaTranscricao.transcricao ? chamadaTranscricao.transcricao.split('\n').filter(Boolean).map((linha, i) => {
                            const isSdr  = /^SDR\s*:/i.test(linha);
                            const isLead = /^Lead\s*:/i.test(linha);
                            return (
                              <div key={i} style={{ marginBottom:6, display:'flex', gap:8 }}>
                                <span style={{ fontSize:10.5, fontWeight:700, fontFamily:'var(--dgd-font-mono,monospace)', color: isSdr ? '#1d4ed8' : isLead ? '#166534' : 'var(--dgd-fg-3)', minWidth:36, flexShrink:0 }}>
                                  {isSdr ? 'SDR' : isLead ? 'LEAD' : ''}
                                </span>
                                <span style={{ fontSize:12.5, color:'var(--dgd-fg-1)', lineHeight:1.5 }}>{linha.replace(/^(SDR|Lead)\s*:\s*/i, '')}</span>
                              </div>
                            );
                          }) : <div style={{ fontSize:12.5, color:'var(--dgd-fg-3)', fontStyle:'italic' }}>Sem transcrição disponível.</div>}
                        </div>
                      </div>
                    </div>
                  )}
                  {chamadasLoading && <div style={{ padding:'32px 0', textAlign:'center', fontSize:12, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)' }}>A carregar chamadas...</div>}
                  {!chamadasLoading && chamadas !== null && chamadas.length === 0 && (
                    <div style={{ padding:'32px 0', textAlign:'center', fontSize:12, color:'var(--dgd-fg-3)' }}>Sem chamadas registadas para esta lead.</div>
                  )}
                  {!chamadasLoading && chamadas?.length > 0 && chamadas.map((c, i) => {
                    const estadoCfg = {
                      conversa:     { label:'Conversa',     color:'#166534', bg:'#f0fdf4', border:'#bbf7d0' },
                      sem_resposta: { label:'Sem resposta', color:'#92400e', bg:'#fffbeb', border:'#fde68a' },
                      ocupado:      { label:'Ocupado',      color:'#991b1b', bg:'#fef2f2', border:'#fecaca' },
                      sem_relatorio:{ label:'Sem relatório',color:'#64748b', bg:'#f1f5f9', border:'#cbd5e1' },
                    };
                    const ec = estadoCfg[c.estado] || { label: c.estado || '—', color:'#64748b', bg:'#f1f5f9', border:'#cbd5e1' };
                    const dur = c.duracao_seg != null ? `${Math.floor(c.duracao_seg/60)}:${String(c.duracao_seg%60).padStart(2,'0')}` : null;
                    const bant = c.bant || {};
                    return (
                      <div key={c.id} style={{ padding:'12px 0', borderBottom: i < chamadas.length-1 ? '1px solid var(--dgd-border-1)' : 'none' }}>
                        <div style={{ display:'flex', alignItems:'center', gap:8, marginBottom:6 }}>
                          <span style={{ fontSize:10.5, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)' }}>
                            {new Date(c.created_at).toLocaleString('pt-PT',{day:'2-digit',month:'2-digit',hour:'2-digit',minute:'2-digit'})}
                          </span>
                          {dur && <span style={{ fontSize:10.5, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)' }}>{dur}</span>}
                          <span style={{ fontSize:10.5, padding:'1px 8px', borderRadius:99, fontWeight:600, color:ec.color, background:ec.bg, border:`1px solid ${ec.border}` }}>{ec.label}</span>
                          <div style={{ display:'flex', gap:3, marginLeft:4 }}>
                            {[['B','budget'],['A','authority'],['N','need'],['T','timeline']].map(([k,key]) => {
                              const v = bant[key]; const col = v===true?'#166534':v===false?'#991b1b':'#94a3b8'; const bg = v===true?'#f0fdf4':v===false?'#fef2f2':'#f1f5f9';
                              return <span key={k} style={{ width:18,height:18,borderRadius:3,fontSize:9,fontWeight:700,fontFamily:'var(--dgd-font-mono,monospace)',display:'inline-flex',alignItems:'center',justifyContent:'center',background:bg,color:col,border:`1px solid ${col}44` }}>{k}</span>;
                            })}
                          </div>
                          {c.transcricao && (
                            <button onClick={() => setChamadaTranscricao(c)} style={{ marginLeft:'auto', fontSize:10.5, padding:'2px 8px', borderRadius:5, border:'1px solid var(--dgd-border-1)', background:'white', color:'#1d4ed8', cursor:'pointer', fontWeight:600 }}>Ver transcrição</button>
                          )}
                        </div>
                        {c.resumo && <div style={{ fontSize:12, color:'var(--dgd-fg-2)', lineHeight:1.5, marginBottom:4 }}>{c.resumo}</div>}
                        {c.notas && <div style={{ fontSize:11.5, color:'var(--dgd-fg-3)', fontStyle:'italic' }}>{c.notas}</div>}
                      </div>
                    );
                  })}
                </>
              )}

              {/* TAB: FM Sync */}
              {tab === 'fm' && (() => {
                const fmStatus = fmOppId.trim() ? 'sincronizado' : 'pendente';
                const handleFmLookup = async () => {
                  setFmLookup('loading'); setFmOps([]);
                  const url = '/api/comercial/sdr/fm-opp-lookup?empresa=' + encodeURIComponent(prospect.empresa) + '&tenant=PT&days=365' + (nifCliente ? '&nif=' + encodeURIComponent(nifCliente) : '');
                  const d = await fetch(url, { credentials:'include' }).then(r => r.json()).catch(() => null);
                  if (!d) { setFmLookup('error'); return; }
                  setFmOps(d); setFmLookup('done');
                };
                const handleSaveFm = async (id) => {
                  const saveId = id !== undefined ? id : fmOppId.trim();
                  setFmSave('saving');
                  const resp = await fetch('/api/comercial/sdr/bant-fm-link', {
                    method:'POST', credentials:'include',
                    headers:{ 'Content-Type':'application/json' },
                    body: JSON.stringify({ prospect_id: prospect.id, empresa_nome: prospect.empresa, campanha: campanhaNome, fm_opp_id: saveId || null }),
                  }).then(r => r.json()).catch(() => null);
                  if (!resp?.ok) { setFmSave('error'); setTimeout(() => setFmSave('idle'), 3000); return; }
                  if (id !== undefined) setFmOppId(id);
                  setFmSave('saved'); setTimeout(() => setFmSave('idle'), 2000);
                };
                return (
                  <div style={{ display:'flex', flexDirection:'column', gap:16 }}>
                    {/* Status badge */}
                    <div style={{ display:'flex', alignItems:'center', gap:10 }}>
                      <span style={{ fontSize:10, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', fontWeight:600, letterSpacing:'0.08em' }}>ESTADO FM</span>
                      <span style={{ fontSize:11, padding:'2px 10px', borderRadius:99, fontWeight:600,
                        background: fmStatus==='sincronizado' ? '#f0fdf4' : '#fffbeb',
                        color:      fmStatus==='sincronizado' ? '#166534' : '#92400e',
                        border:     `1px solid ${fmStatus==='sincronizado' ? '#bbf7d0' : '#fde68a'}` }}>
                        {fmStatus==='sincronizado' ? '✓ Sincronizado' : 'Pendente FM'}
                      </span>
                    </div>
                    {/* Dados para o Gestor */}
                    <div style={{ padding:'12px 14px', background:'var(--dgd-bg,#f8fafc)', border:'1px solid var(--dgd-border-1)', borderRadius:8 }}>
                      <div style={{ fontSize:10, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', fontWeight:600, letterSpacing:'0.08em', marginBottom:10, textTransform:'uppercase' }}>Dados para o Gestor</div>
                      {[
                        ['Contacto', prospect.contacto_nome || '—'],
                        ['Empresa',  prospect.empresa],
                        ['NIF',      nifCliente || '— (preencher)'],
                        ['Email',    prospect.email || '—'],
                        ['Campanha', campanhaNome || '—'],
                        ['Tipo',     'Passado ao Comercial'],
                      ].map(function([k,v]) { return (
                        <div key={k} style={{ display:'flex', gap:12, marginBottom:6, fontSize:12.5 }}>
                          <span style={{ color:'var(--dgd-fg-3)', minWidth:90, flexShrink:0, fontFamily:'var(--dgd-font-mono,monospace)', fontSize:10, fontWeight:600, textTransform:'uppercase', letterSpacing:'0.04em', paddingTop:2 }}>{k}</span>
                          <span style={{ color:'var(--dgd-fg-1)' }}>{v}</span>
                        </div>
                      ); })}
                    </div>
                    {/* Lookup no Gestor */}
                    <div>
                      <div style={{ fontSize:10, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', fontWeight:600, letterSpacing:'0.08em', marginBottom:8, textTransform:'uppercase' }}>Oportunidades no Gestor (12 meses)</div>
                      {fmLookup === 'idle' && (
                        <button onClick={handleFmLookup}
                          style={{ padding:'8px 16px', borderRadius:6, border:'none', fontSize:12.5, fontWeight:600, cursor:'pointer', background:'#112954', color:'white' }}>
                          Procurar no Gestor
                        </button>
                      )}
                      {fmLookup === 'loading' && <div style={{ fontSize:12, color:'var(--dgd-fg-3)', padding:'8px 0' }}>A consultar o Gestor...</div>}
                      {fmLookup === 'error' && <div style={{ fontSize:12, color:'#991b1b', padding:'8px 0' }}>Erro ao contactar o Gestor. Tenta novamente ou usa o ID manual.</div>}
                      {fmLookup === 'done' && fmOps.length === 0 && (
                        <div style={{ fontSize:12, color:'var(--dgd-fg-3)', padding:'8px 0' }}>
                          Nenhuma OP encontrada para <strong>{prospect.empresa}</strong> nos últimos 12 meses.
                          <button onClick={() => setFmManual(true)} style={{ marginLeft:8, fontSize:12, color:'#1d4ed8', background:'none', border:'none', cursor:'pointer', textDecoration:'underline' }}>Inserir ID manualmente</button>
                        </div>
                      )}
                      {fmLookup === 'done' && fmOps.length > 0 && (
                        <div style={{ border:'1px solid var(--dgd-border-1)', borderRadius:8, overflow:'hidden' }}>
                          {fmOps.map(function(op, i) { return (
                            <div key={op.id_oportunidade} onClick={() => handleSaveFm(op.id_oportunidade)}
                              style={{ display:'flex', alignItems:'center', gap:12, padding:'10px 14px', cursor:'pointer', borderBottom: i < fmOps.length-1 ? '1px solid var(--dgd-border-1)' : 'none',
                                background: fmOppId === op.id_oportunidade ? 'color-mix(in oklch,#112954 6%,transparent)' : 'white' }}>
                              <div style={{ flex:1 }}>
                                <div style={{ fontSize:12.5, fontWeight:600, color:'var(--dgd-fg-1)' }}>{op.produto_name || '—'}</div>
                                <div style={{ fontSize:11, color:'var(--dgd-fg-3)', marginTop:2, fontFamily:'var(--dgd-font-mono,monospace)' }}>{op.stage_name} · {op.produto_valor_k || '—'} · {op.start_date}</div>
                              </div>
                              {fmOppId === op.id_oportunidade
                                ? <div style={{ display:'flex', alignItems:'center', gap:8 }}>
                                    <span style={{ fontSize:11, color:'#166534', fontWeight:700 }}>{fmSave==='saved' ? '✓ Guardado' : '✓ Seleccionado'}</span>
                                    <button onClick={e => { e.stopPropagation();
                                      fetch('/api/comercial/sdr/fm-op/' + encodeURIComponent(op.id_oportunidade), { credentials:'include' })
                                        .then(r => r.json()).then(d => setOppDetailData(d)).catch(() => {});
                                    }} style={{ fontSize:11, padding:'3px 10px', borderRadius:5, border:'1px solid #1d4ed8', background:'white', color:'#1d4ed8', cursor:'pointer', fontWeight:600, whiteSpace:'nowrap' }}>
                                      Ver oportunidade
                                    </button>
                                  </div>
                                : <span style={{ fontSize:11, color:'#1d4ed8' }}>Seleccionar</span>
                              }
                            </div>
                          ); })}
                          <div style={{ padding:'8px 14px', borderTop:'1px solid var(--dgd-border-1)', background:'var(--dgd-bg,#f8fafc)' }}>
                            <button onClick={() => setFmManual(v => !v)} style={{ fontSize:11, color:'var(--dgd-fg-3)', background:'none', border:'none', cursor:'pointer', textDecoration:'underline' }}>Não é nenhuma destas? Inserir ID manualmente</button>
                          </div>
                        </div>
                      )}
                    </div>
                    {/* Manual fallback */}
                    {(fmManual || (fmLookup === 'idle' && fmOppId)) && (
                      <div>
                        <div style={{ fontSize:10, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', fontWeight:600, letterSpacing:'0.08em', marginBottom:6, textTransform:'uppercase' }}>ID Oportunidade (manual)</div>
                        <div style={{ display:'flex', gap:8 }}>
                          <input type="text" value={fmOppId} onChange={e => setFmOppId(e.target.value)}
                            placeholder="Cola o ID da oportunidade FM aqui"
                            style={{ flex:1, padding:'8px 12px', fontSize:12.5, border:'1px solid var(--dgd-border-1)', borderRadius:6, fontFamily:'var(--dgd-font-mono,monospace)', outline:'none', color:'var(--dgd-fg-1)' }} />
                          <button onClick={() => handleSaveFm()} disabled={fmSave==='saving'}
                            style={{ padding:'8px 14px', borderRadius:6, border:'none', fontSize:12.5, fontWeight:600, cursor:fmSave==='saving'?'not-allowed':'pointer', background:fmSave==='saved'?'#16a34a':fmSave==='error'?'#dc2626':'#112954', color:'white', whiteSpace:'nowrap' }}>
                            {fmSave==='saved' ? '✓ Guardado' : fmSave==='saving' ? '...' : fmSave==='error' ? 'Erro — tenta de novo' : 'Guardar'}
                          </button>
                        </div>
                      </div>
                    )}
                  </div>
                );
              })()}
            </>
          )}
        </div>

        {/* Footer */}
        <div style={{ padding:'12px 20px', borderTop:'1px solid var(--dgd-border-1)', display:'flex', alignItems:'center', justifyContent:'space-between', background:'var(--dgd-bg,#f8fafc)' }}>
          <div style={{ display:'flex', gap:6 }}>
            {bantFields.map(f => {
              const v = bant[f.key];
              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 key={f.key} style={{ display:'inline-flex', alignItems:'center', justifyContent:'center', width:22, height:22, borderRadius:4, fontSize:10, fontWeight:700, fontFamily:'var(--dgd-font-mono,monospace)', color, background:bg, border:`1px solid ${border}` }}>{f.label[0]}</span>;
            })}
          </div>
          <div style={{ display:'flex', gap:8, alignItems:'center' }}>
            {saveState === 'error' && <span style={{ fontSize:11.5, color:'#991b1b' }}>{allBantTrue && !nifCliente.trim() ? 'NIF obrigatório para BANT Completo' : 'Erro ao guardar'}</span>}
            {/* A Aguardar — inline date picker */}
            {showAguardar ? (
              <div style={{ display:'flex', alignItems:'center', gap:4 }}>
                <input type="date" value={nextDate} onChange={e => setNextDate(e.target.value)} style={{ padding:'4px 8px', borderRadius:5, border:'1px solid #c4b5fd', fontSize:11.5, color:'#7c3aed', outline:'none' }} />
                <button onClick={async () => {
                  setSave('saving');
                  try {
                    const r = await fetch('/api/comercial/sdr/a-aguardar', {
                      method:'POST', credentials:'include',
                      headers:{ 'Content-Type':'application/json' },
                      body: JSON.stringify({ prospect_id: prospect.id, empresa_nome: prospect.empresa, campanha: campanhaNome, next_date: nextDate || null }),
                    });
                    if (r.ok) { setSave('saved'); if (onSaved) onSaved(); setTimeout(() => { setSave('idle'); onClose(); }, 1000); }
                    else throw new Error();
                  } catch (e) { setSave('error'); setTimeout(() => setSave('idle'), 3000); }
                }} disabled={!nextDate} style={{ padding:'4px 10px', borderRadius:5, border:'none', background: nextDate ? '#7c3aed' : '#e2e8f0', color:'#fff', fontSize:11, fontWeight:600, cursor: nextDate ? 'pointer' : 'not-allowed' }}>OK</button>
                <button onClick={() => setShowAguardar(false)} style={{ padding:'4px 8px', borderRadius:5, border:'1px solid var(--dgd-border-1)', background:'transparent', fontSize:11, cursor:'pointer', color:'var(--dgd-fg-3)' }}>X</button>
              </div>
            ) : (
              <button onClick={() => setShowAguardar(true)} style={{ padding:'7px 14px', borderRadius:6, border:'1px solid #c4b5fd', background:'#f5f3ff', fontSize:12, cursor:'pointer', color:'#7c3aed', fontWeight:500 }}>A Aguardar</button>
            )}
            <button onClick={async () => {
              if (!confirm('Marcar ' + prospect.empresa + ' como Sem Interesse?')) return;
              setSave('saving');
              try {
                const r = await fetch('/api/comercial/sdr/sem-interesse', {
                  method:'POST', credentials:'include',
                  headers:{ 'Content-Type':'application/json' },
                  body: JSON.stringify({ prospect_id: prospect.id, empresa_nome: prospect.empresa, campanha: campanhaNome }),
                });
                if (r.ok) { setSave('saved'); if (onSaved) onSaved(); setTimeout(() => { setSave('idle'); onClose(); }, 1000); }
                else throw new Error();
              } catch (e) { setSave('error'); setTimeout(() => setSave('idle'), 3000); }
            }} style={{ padding:'7px 14px', borderRadius:6, border:'1px solid #fecaca', background:'#fef2f2', fontSize:12, cursor:'pointer', color:'#991b1b', fontWeight:500 }}>Sem Interesse</button>
            <button onClick={onClose} style={{ padding:'7px 16px', borderRadius:6, border:'1px solid var(--dgd-border-1)', background:'transparent', fontSize:13, cursor:'pointer', color:'var(--dgd-fg-2)' }}>Fechar</button>
            {allBantTrue && (
              <button
                onClick={async () => {
                  if (passadoComercial) return;
                  if (!confirm('Passar ' + prospect.empresa + ' ao comercial?')) return;
                  setSave('saving');
                  try {
                    const r = await fetch('/api/comercial/sdr/passar-comercial', {
                      method:'POST', credentials:'include',
                      headers:{ 'Content-Type':'application/json' },
                      body: JSON.stringify({ prospect_id: prospect.id, empresa_nome: prospect.empresa, campanha: campanhaNome }),
                    });
                    if (r.ok) { setPassadoComercial(true); setSave('saved'); if (onSaved) onSaved(); setTimeout(() => { setSave('idle'); onClose(); }, 1200); }
                    else throw new Error();
                  } catch (e) { setSave('error'); setTimeout(() => setSave('idle'), 3000); }
                }}
                disabled={saveState === 'saving'}
                style={{ padding:'7px 16px', borderRadius:6, border: passadoComercial ? 'none' : '1px solid #166534', background: passadoComercial ? '#16a34a' : 'transparent', color: passadoComercial ? '#fff' : '#166534', fontSize:13, fontWeight:600, cursor: passadoComercial || saveState==='saving' ? 'not-allowed' : 'pointer', whiteSpace:'nowrap' }}
              >{passadoComercial ? '✓ Passado ao Comercial' : 'Passar ao Comercial'}</button>
            )}
            <button
              onClick={handleSave}
              disabled={saveState === 'saving'}
              style={{ padding:'7px 18px', borderRadius:6, border:'none', background: saveState==='saved' ? '#16a34a' : '#112954', color:'#fff', fontSize:13, fontWeight:600, cursor: saveState==='saving' ? 'not-allowed' : 'pointer', transition:'background 0.2s', minWidth:120 }}
            >
              {saveState === 'saving' ? 'A guardar...' : saveState === 'saved' ? '✓ Guardado' : 'Guardar BANT'}
            </button>
          </div>
        </div>
      </div>
    </div>
    {oppDetailData && window.OpDetailPanel && (
      <div onClick={e => { if (e.target === e.currentTarget) setOppDetailData(null); }}
        style={{ position:'fixed', inset:0, background:'rgba(0,0,0,0.45)', zIndex:3000, display:'flex', alignItems:'center', justifyContent:'center', padding:24 }}>
        <div style={{ width:'100%', maxWidth:520, maxHeight:'88vh', overflowY:'auto', borderRadius:12, boxShadow:'0 16px 56px rgba(0,0,0,0.28)' }}>
          <window.OpDetailPanel
            op={{ ...oppDetailData, _mobileModal: true }}
            empresa={oppDetailData._tenant || 'PTDIG'}
            userName={user?.name || ''}
            onClose={() => setOppDetailData(null)}
          />
        </div>
      </div>
    )}
    </React.Fragment>
  );
};

// ─── Markdown renderer (conteúdo Claude) ─────────────────────────────────────
function mdInline(text) {
  if (!text) return text;
  return text.split('**').map(function(seg, i) {
    if (i % 2 === 1) return <strong key={i}>{seg}</strong>;
    return seg;
  });
}

function renderMdLines(text, keyPfx) {
  var lines = (text || '').split('\n');
  var out = [];
  var i = 0;
  while (i < lines.length) {
    var line = lines[i];
    var k = (keyPfx || '') + i;
    if (!line.trim()) { i++; continue; }
    if (line.startsWith('# ')) {
      out.push(<div key={k} style={{fontWeight:700,fontSize:15,color:'#112954',marginTop:4,marginBottom:8}}>{mdInline(line.slice(2))}</div>);
    } else if (line.startsWith('## ')) {
      out.push(<div key={k} style={{fontWeight:700,fontSize:13,color:'#112954',marginTop:20,marginBottom:6,paddingBottom:4,borderBottom:'2px solid var(--dgd-border-1)'}}>{mdInline(line.slice(3))}</div>);
    } else if (line.startsWith('### ')) {
      out.push(<div key={k} style={{fontWeight:600,fontSize:11,color:'var(--dgd-fg-3)',marginTop:12,marginBottom:3,fontFamily:'var(--dgd-font-mono,monospace)',textTransform:'uppercase',letterSpacing:'0.06em'}}>{line.slice(4)}</div>);
    } else if (line === '---') {
      out.push(<hr key={k} style={{border:'none',borderTop:'1px solid var(--dgd-border-1)',margin:'20px 0'}}/>);
    } else if (line.startsWith('> ')) {
      out.push(<div key={k} style={{borderLeft:'3px solid #6366f1',paddingLeft:10,fontStyle:'italic',fontSize:12,color:'var(--dgd-fg-2)',margin:'4px 0'}}>{line.slice(2).replace(/^\*|\*$/g,'')}</div>);
    } else if (line.startsWith('|') && lines[i+1] && /^\|[-|\s]+\|$/.test(lines[i+1])) {
      var headers = line.split('|').filter(function(c){return c.trim();}).map(function(c){return c.trim();});
      i += 2;
      var rows = [];
      while (i < lines.length && lines[i].startsWith('|')) {
        rows.push(lines[i].split('|').filter(function(c){return c.trim();}).map(function(c){return c.trim();}));
        i++;
      }
      var noteClr = function(v) { return {A:'#16a34a',B:'#2563eb','B+':'#2563eb',C:'#d97706',D:'#dc2626'}[v] || 'var(--dgd-fg-1)'; };
      out.push(
        <table key={'t'+k} style={{borderCollapse:'collapse',fontSize:12,margin:'8px 0'}}>
          <thead><tr>{headers.map(function(h,hi){return <th key={hi} style={{textAlign:'left',padding:'4px 10px',borderBottom:'2px solid var(--dgd-border-1)',color:'var(--dgd-fg-3)',fontWeight:600,fontSize:11,textTransform:'uppercase'}}>{h}</th>;})}</tr></thead>
          <tbody>{rows.map(function(row,ri){return <tr key={ri}>{row.map(function(cell,ci){return <td key={ci} style={{padding:'4px 10px',color:ci===1?noteClr(cell):'var(--dgd-fg-1)',fontWeight:ci===1?700:400,borderBottom:'1px solid var(--dgd-border-1)'}}>{cell}</td>;})}</tr>;})}</tbody>
        </table>
      );
      continue;
    } else if (/^\d+\./.test(line)) {
      out.push(
        <div key={k} style={{display:'flex',gap:6,margin:'4px 0',fontSize:13,alignItems:'flex-start'}}>
          <span style={{color:'#6366f1',fontWeight:700,minWidth:18,flexShrink:0}}>{line.match(/^(\d+)/)[1]}.</span>
          <span style={{lineHeight:1.6}}>{mdInline(line.replace(/^\d+\.\s*/,''))}</span>
        </div>
      );
    } else {
      out.push(<div key={k} style={{fontSize:13,lineHeight:1.6,color:'var(--dgd-fg-1)',margin:'3px 0'}}>{mdInline(line)}</div>);
    }
    i++;
  }
  return out;
}

// ─── Coach Tab (admin) ────────────────────────────────────────────────────────
const SdrCoachTab = () => {
  const [data, setData] = React.useState(null);
  const [loading, setLoading] = React.useState(true);
  React.useEffect(() => {
    fetch('/api/comercial/sdr/coaching/relatorio', { credentials:'include' })
      .then(function(r){return r.json();}).catch(function(){return null;})
      .then(function(d){ setData(d); setLoading(false); });
  }, []);

  if (loading) return <div style={{padding:20,color:'var(--dgd-fg-3)',fontSize:12}}>A carregar coaching...</div>;
  if (!data || !data.relatorio) return <div style={{padding:20,color:'var(--dgd-fg-3)',fontSize:12}}>Sem relatório de coaching para hoje.</div>;

  var parts = (data.relatorio || '').split('\n\n---\n\n');
  var nivel1 = parts[0] || ''; var nivel2 = parts[1] || ''; var nivel3 = parts[2] || '';

  return (
    <div style={{maxWidth:860}}>
      <div style={{fontSize:10,color:'var(--dgd-fg-3)',marginBottom:16}}>Visível apenas para admin</div>
      {data.paragrafos && data.paragrafos.length > 0 && (
        <div style={{marginBottom:24}}>
          <div style={{fontSize:10,fontWeight:700,color:'#4338ca',fontFamily:'var(--dgd-font-mono,monospace)',textTransform:'uppercase',letterSpacing:'0.08em',marginBottom:10}}>COACHING POR SDR</div>
          {data.paragrafos.map(function(p){return (
            <div key={p.email} style={{marginBottom:12,padding:'12px 16px',background:'color-mix(in oklch,#6366f1 5%,transparent)',borderLeft:'3px solid #6366f1',borderRadius:8}}>
              <div style={{fontSize:10,fontWeight:700,color:'#4338ca',textTransform:'uppercase',marginBottom:6}}>{p.nome}</div>
              <p style={{margin:0,fontSize:13,lineHeight:1.6}}>{p.conteudo.split('**').map(function(seg,i){return i%2===1?<strong key={i}>{seg}</strong>:seg;})}</p>
            </div>
          );})}
        </div>
      )}

      {data.retornos && (
        <div style={{marginBottom:24}}>
          <div style={{fontSize:10,fontWeight:700,color:'#b91c1c',fontFamily:'var(--dgd-font-mono,monospace)',textTransform:'uppercase',letterSpacing:'0.08em',marginBottom:10}}>RETORNOS DE HOJE</div>
          <div style={{padding:'12px 16px',background:'color-mix(in oklch,#dc2626 5%,transparent)',borderLeft:'3px solid #dc2626',borderRadius:8}}>
            {renderMdLines(data.retornos,'r')}
          </div>
        </div>
      )}

      {[['NÍVEL 1 — DESEMPENHO SDR', nivel1, 'n1'], ['NÍVEL 2 — BRIEFING / GUIÃO / CAMPANHA', nivel2, 'n2'], ['NÍVEL 3 — SISTEMA TÉCNICO', nivel3, 'n3']].map(function(item){return (
        <div key={item[2]} style={{marginBottom:24}}>
          <div style={{fontSize:10,fontWeight:700,color:'var(--dgd-fg-3)',fontFamily:'var(--dgd-font-mono,monospace)',textTransform:'uppercase',letterSpacing:'0.08em',marginBottom:10}}>{item[0]}</div>
          <div style={{background:'var(--dgd-bg-card,white)',border:'1px solid var(--dgd-border-1)',borderRadius:8,padding:'16px 20px'}}>
            {renderMdLines(item[1], item[2])}
          </div>
        </div>
      );})}
    </div>
  );
};

// ─── Coaching Card (matinal por SDR) ─────────────────────────────────────────
const SdrCoachingCard = ({ email, dismissible }) => {
  const [state, setState] = React.useState({ paragrafo: null, data: null, visible: false });
  React.useEffect(() => {
    if (!email) return;
    setState({ paragrafo: null, data: null, visible: false });
    const url = '/api/comercial/sdr/coaching/hoje?email=' + encodeURIComponent(email);
    fetch(url, { credentials: 'include' })
      .then(r => r.json()).catch(() => ({}))
      .then(d => {
        if (!d.paragrafo) return;
        if (dismissible) {
          const key = 'coaching_dismissed_' + d.data + '_' + email;
          if (localStorage.getItem(key)) return;
        }
        setState({ paragrafo: d.paragrafo, data: d.data, visible: true });
      });
  }, [email]);
  if (!state.visible) return null;
  return (
    <div style={{ position:'relative', borderLeft:'3px solid #6366f1', background:'color-mix(in oklch,#6366f1 5%,transparent)', padding:'12px 16px', borderRadius:8, marginBottom:12 }}>
      <div style={{ fontSize:10, fontWeight:700, color:'#4338ca', fontFamily:'var(--dgd-font-mono,monospace)', textTransform:'uppercase', letterSpacing:'0.08em', marginBottom:6 }}>
        COACH SDR · {state.data}
      </div>
      <p style={{ margin:0, fontSize:13, color:'var(--dgd-fg-1)', lineHeight:1.6 }}>
        {state.paragrafo.split('**').map((part, i) =>
          i % 2 === 1 ? <strong key={i}>{part}</strong> : part
        )}
      </p>
      {dismissible && (
        <button onClick={() => { localStorage.setItem('coaching_dismissed_' + state.data + '_' + email, '1'); setState(s => ({ ...s, visible: false })); }}
          style={{ position:'absolute', top:8, right:10, background:'none', border:'none', cursor:'pointer', fontSize:16, color:'var(--dgd-fg-3)', lineHeight:1 }}>×</button>
      )}
    </div>
  );
};

// ─── Prospects em Campanha (SDR Humano) ──────────────────────────────────────
const SdrProspectsCampanha = ({ user, sdrEmail }) => {
  const [prospects, setProspects]   = React.useState([]);
  const [loading, setLoading]       = React.useState(true);
  const [selC, setSelC]             = React.useState(null);
  const [bantModal, setBantModal]   = React.useState(null);
  const [subTab, setSubTab]         = React.useState('daily'); // daily | oportunidades | inativas

  const fetchProspects = React.useCallback(function(showLoading) {
    if (showLoading) setLoading(true);
    const url = sdrEmail
      ? '/api/comercial/sdr/prospects-campanha?sdr_email=' + encodeURIComponent(sdrEmail)
      : '/api/comercial/sdr/prospects-campanha';
    return fetch(url, { credentials: 'include' })
      .then(function(r) { return r.json(); })
      .then(function(d) { if (Array.isArray(d)) setProspects(d); })
      .catch(function() {})
      .finally(function() { if (showLoading) setLoading(false); });
  }, [sdrEmail]);

  React.useEffect(function() {
    setLoading(true);
    setSelC(null);
    fetchProspects(true);
    const iv = setInterval(function() { fetchProspects(false); }, 60000);
    return function() { clearInterval(iv); };
  }, [sdrEmail]);

  const normalize = function(s) { return (s||'').normalize('NFD').replace(/[\u0300-\u036f]/g,'').toLowerCase(); };
  const [search, setSearch]   = React.useState('');
  const [sort, setSort] = React.useState({ col: null, dir: 'asc' });
  const sortCol = sort.col;
  const sortDir = sort.dir;
  const handleSort = function(col) {
    setSort(function(prev) {
      if (prev.col === col) return { col: col, dir: prev.dir === 'asc' ? 'desc' : 'asc' };
      return { col: col, dir: 'asc' };
    });
  };
  const estadoOrdem = { respondeu:0, empresa_com_lead:1, so_base:2, novo:3, contactado:4, a_aguardar:5, bant_completo:6, passado_comercial:7, sem_interesse:8 };
  const estadoCfg = {
    novo:              { label:'Novo',               color:'#1d4ed8', bg:'#eff6ff', border:'#bfdbfe' },
    contactado:        { label:'Em contacto',        color:'#92400e', bg:'#fffbeb', border:'#fde68a' },
    a_aguardar:        { label:'A Aguardar',         color:'#7c3aed', bg:'#f5f3ff', border:'#c4b5fd' },
    bant_completo:     { label:'BANT Completo',      color:'#166534', bg:'#f0fdf4', border:'#bbf7d0' },
    passado_comercial: { label:'Passado Comercial',  color:'#065f46', bg:'#ecfdf5', border:'#6ee7b7' },
    sem_interesse:     { label:'Sem Interesse',      color:'#991b1b', bg:'#fef2f2', border:'#fecaca' },
    respondeu:         { label:'Respondeu',          color:'#166534', bg:'#f0fdf4', border:'#bbf7d0' },
    empresa_com_lead:  { label:'Empresa com lead',   color:'#9a3412', bg:'#fff7ed', border:'#fdba74' },
    so_base:           { label:'Só na base',         color:'#334155', bg:'#f8fafc', border:'#cbd5e1' },
  };

  const campanhas = [...new Set(prospects.map(function(p) { return p.campanha; }))];
  const searchNorm = normalize(search.trim());

  // Separar prospects pelos 3 grupos
  const baseFilter = function(p) {
    if (selC && p.campanha !== selC) return false;
    if (searchNorm && !normalize(p.empresa).includes(searchNorm) && !normalize(p.contacto_nome||'').includes(searchNorm)) return false;
    return true;
  };
  const dailyProspects   = prospects.filter(function(p) { return baseFilter(p) && p.estado !== 'passado_comercial' && p.estado !== 'sem_interesse'; });
  const oportunidades    = prospects.filter(function(p) { return baseFilter(p) && p.estado === 'passado_comercial'; });
  const inativas         = prospects.filter(function(p) { return baseFilter(p) && p.estado === 'sem_interesse'; });

  const applySort = function(list) {
    if (!sortCol) return list;
    return [...list].sort(function(a, b) {
      var va, vb;
      if (sortCol === 'estado') { va = estadoOrdem[a.estado] || 0; vb = estadoOrdem[b.estado] || 0; }
      else if (sortCol === 'next_date') { va = a.next_date || '9999'; vb = b.next_date || '9999'; }
      else { va = (a[sortCol] || '').toLowerCase(); vb = (b[sortCol] || '').toLowerCase(); }
      if (va < vb) return sortDir === 'asc' ? -1 : 1;
      if (va > vb) return sortDir === 'asc' ? 1 : -1;
      return 0;
    });
  };

  const sortArrow = function(col) { return sortCol === col ? (sortDir === 'asc' ? ' \u25B2' : ' \u25BC') : ''; };
  const thBase = { 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', cursor:'pointer', userSelect:'none' };
  const thNoSort = { ...thBase, cursor:'default' };
  const td = { padding:'9px 12px', fontSize:12.5, borderBottom:'1px solid var(--dgd-border-1)', color:'var(--dgd-fg-2)' };

  const BantDots = function({ p }) {
    return (
      <div style={{ display:'flex', gap:3 }}>
        {[['B',p.bant_budget],['A',p.bant_authority],['N',p.bant_need],['T',p.bant_timeline]].map(function(bv) {
          const v = bv[1];
          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 key={bv[0]} 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 }}>{bv[0]}</span>;
        })}
      </div>
    );
  };

  const tabStyle = function(active) { return {
    padding:'7px 14px', fontSize:11.5, fontWeight:600, cursor:'pointer', border:'none', background:'transparent',
    borderBottom: active ? '2px solid var(--dgd-fg-1)' : '2px solid transparent',
    color: active ? 'var(--dgd-fg-1)' : 'var(--dgd-fg-3)',
  }; };

  const handleRestaurar = async function(p) {
    if (!confirm('Restaurar ' + (p.contacto_nome || p.empresa) + ' para Daily Prospect?')) return;
    await fetch('/api/comercial/sdr/restaurar-prospect', {
      method:'POST', credentials:'include',
      headers:{ 'Content-Type':'application/json' },
      body: JSON.stringify({ prospect_id: p.id, empresa_nome: p.empresa, campanha: p.campanha }),
    }).catch(() => {});
    fetchProspects(false);
  };

  return (
    <>
    <div style={{ marginTop:20 }}>
      <div style={{ display:'flex', alignItems:'center', gap:8, marginBottom:12, flexWrap:'wrap' }}>
        <div style={{ flex:1 }}>
          <div style={{ fontSize:10, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', letterSpacing:'0.08em', marginBottom:3 }}>BD PROSPECÇÃO · MARKETING</div>
          <div style={{ fontSize:15, fontWeight:600, color:'var(--dgd-fg-1)' }}>Leads Prospect Atribuídas</div>
        </div>
        <div style={{ display:'flex', gap:4, flexWrap:'wrap', alignItems:'center' }}>
          <input type="text" value={search} onChange={e => setSearch(e.target.value)} placeholder="Pesquisar..." style={{ padding:'5px 10px', border:'1px solid var(--dgd-border-1)', borderRadius:6, fontSize:12, outline:'none', color:'var(--dgd-fg-1)', background:'var(--dgd-bg-surface,#fff)', width:160 }} />
          <button onClick={() => setSelC(null)} style={{ padding:'4px 12px', borderRadius:99, border:'1px solid', fontSize:11.5, cursor:'pointer', fontWeight:selC===null?700:400, background:selC===null?'#112954':'transparent', color:selC===null?'#fff':'var(--dgd-fg-2)', borderColor:selC===null?'#112954':'var(--dgd-border-1)' }}>Todas</button>
          {campanhas.map(c => (
            <button key={c} onClick={() => setSelC(c)} style={{ padding:'4px 12px', borderRadius:99, border:'1px solid', fontSize:11.5, cursor:'pointer', fontWeight:selC===c?700:400, background:selC===c?'#112954':'transparent', color:selC===c?'#fff':'var(--dgd-fg-2)', borderColor:selC===c?'#112954':'var(--dgd-border-1)' }}>{c}</button>
          ))}
        </div>
      </div>

      <div style={{ background:'var(--dgd-bg-card,white)', border:'1px solid var(--dgd-border-1)', borderRadius:8, overflow:'hidden' }}>
        {/* Header */}
        <div style={{ padding:'10px 14px', borderBottom:'1px solid var(--dgd-border-1)', display:'flex', alignItems:'center', gap:10, background:'var(--dgd-bg,#f8fafc)' }}>
          <span style={{ fontSize:13, fontWeight:700, color:'var(--dgd-fg-1)' }}>Leads Prospect Atribuídas</span>
          <span style={{ display:'inline-flex', alignItems:'center', justifyContent:'center', minWidth:22, height:22, borderRadius:99, background:'var(--dgd-bg-surface,#fff)', border:'1.5px solid var(--dgd-border-1)', fontSize:12, fontWeight:700, color:'var(--dgd-fg-2)', padding:'0 7px' }}>{prospects.length}</span>
        </div>

        {/* Sub-tabs */}
        <div style={{ display:'flex', borderBottom:'1px solid var(--dgd-border-1)', padding:'0 6px', background:'var(--dgd-bg-card,white)' }}>
          <button style={tabStyle(subTab==='daily')} onClick={() => setSubTab('daily')}>
            Daily Prospect <span style={{ marginLeft:4, fontSize:10.5, fontWeight:700, color:'inherit', opacity:.7 }}>{dailyProspects.length}</span>
          </button>
          <button style={tabStyle(subTab==='oportunidades')} onClick={() => setSubTab('oportunidades')}>
            Oportunidades Criadas <span style={{ marginLeft:4, fontSize:10.5, fontWeight:700, color:'inherit', opacity:.7 }}>{oportunidades.length}</span>
          </button>
          <button style={tabStyle(subTab==='inativas')} onClick={() => setSubTab('inativas')}>
            Inativas <span style={{ marginLeft:4, fontSize:10.5, fontWeight:700, color:'inherit', opacity:.7 }}>{inativas.length}</span>
          </button>
        </div>

        {loading && <div style={{ padding:32, textAlign:'center', color:'var(--dgd-fg-3)', fontSize:12 }}>A carregar...</div>}

        {/* Tab: Daily Prospect */}
        {!loading && subTab === 'daily' && (
          dailyProspects.length === 0
            ? <div style={{ padding:32, textAlign:'center', color:'var(--dgd-fg-3)', fontSize:12 }}>Sem prospects activos.</div>
            : <div style={{ overflowX:'auto' }}>
              <table style={{ width:'100%', borderCollapse:'collapse', fontSize:12 }}>
                <thead>
                  <tr>
                    {[['contacto_nome','Nome'],['empresa','Empresa'],['segmento','Segmento'],['localidade','Localidade'],['campanha','Campanha'],['','Email'],['','BANT'],['estado','Estado'],['next_date','Próximo'],['','']].map(function(h) {
                      return <th key={h[1]||h[0]} style={h[0] ? thBase : thNoSort} onClick={h[0] ? function(){handleSort(h[0]);} : undefined}>{h[1]}{h[0] ? sortArrow(h[0]) : ''}</th>;
                    })}
                  </tr>
                </thead>
                <tbody>
                  {applySort(dailyProspects).map(function(p) {
                    const ec = estadoCfg[p.estado] || estadoCfg.novo;
                    const nd = p.next_date ? new Date(p.next_date).toLocaleDateString('pt-PT', { day:'2-digit', month:'2-digit' }) : '';
                    return (
                      <tr key={p.inscricao_id || p.id} style={{ cursor:'pointer' }}
                        onMouseEnter={e => e.currentTarget.style.background='var(--dgd-bg,#f8fafc)'}
                        onMouseLeave={e => e.currentTarget.style.background='transparent'}
                        onClick={() => setBantModal({ prospect: p, campanhaNome: p.campanha })}
                      >
                        <td style={{ ...td, fontWeight:600, color:'var(--dgd-fg-1)' }}>{p.contacto_nome || '—'}</td>
                        <td style={{ ...td, fontSize:12, color:'var(--dgd-fg-2)' }}>{p.empresa}</td>
                        <td style={td}>{p.segmento}</td>
                        <td style={{ ...td, fontSize:11.5, color:'var(--dgd-fg-3)' }}>{p.localidade}</td>
                        <td style={td}>
                          {p.email_respondeu ? (
                            <span style={{ display:'inline-block', padding:'2px 7px', borderRadius:99, fontSize:10, fontWeight:700, color:'#166534', background:'#f0fdf4', border:'1px solid #bbf7d0' }}>Respondeu</span>
                          ) : p.email_abriu ? (
                            <span style={{ display:'inline-block', padding:'2px 7px', borderRadius:99, fontSize:10, fontWeight:600, color:'#92400e', background:'#fffbeb', border:'1px solid #fde68a' }}>Abriu</span>
                          ) : null}
                        </td>
                        <td style={{ ...td, fontSize:11.5 }}>{p.campanha}</td>
                        <td style={td}><BantDots p={p} /></td>
                        <td style={td}><span style={{ display:'inline-block', padding:'2px 8px', borderRadius:99, fontSize:10.5, fontWeight:600, color:ec.color, background:ec.bg, border:`1px solid ${ec.border}` }}>{ec.label}</span></td>
                        <td style={{ ...td, fontSize:11, fontFamily:'var(--dgd-font-mono,monospace)', color: nd ? '#7c3aed' : 'var(--dgd-fg-3)' }}>{nd || '—'}</td>
                        <td style={td} onClick={e => e.stopPropagation()}>
                          <button onClick={() => setBantModal({ prospect: p, campanhaNome: p.campanha })}
                            style={{ padding:'4px 10px', borderRadius:5, border:'1px solid #112954', background:'#112954', fontSize:11.5, cursor:'pointer', color:'#fff', fontWeight:600 }}>Abrir BANT</button>
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
        )}

        {/* Tab: Oportunidades Criadas */}
        {!loading && subTab === 'oportunidades' && (
          oportunidades.length === 0
            ? <div style={{ padding:32, textAlign:'center', color:'var(--dgd-fg-3)', fontSize:12 }}>Sem oportunidades criadas.</div>
            : <div style={{ overflowX:'auto' }}>
              <table style={{ width:'100%', borderCollapse:'collapse', fontSize:12 }}>
                <thead>
                  <tr>
                    <th style={thBase} onClick={() => handleSort('contacto_nome')}>Nome{sortArrow('contacto_nome')}</th>
                    <th style={thBase} onClick={() => handleSort('empresa')}>Empresa{sortArrow('empresa')}</th>
                    <th style={thBase} onClick={() => handleSort('campanha')}>Campanha{sortArrow('campanha')}</th>
                    <th style={thNoSort}>BANT</th>
                    <th style={thNoSort}>Acção</th>
                  </tr>
                </thead>
                <tbody>
                  {applySort(oportunidades).map(function(p) {
                    return (
                      <tr key={p.inscricao_id || p.id} style={{ cursor:'pointer' }}
                        onMouseEnter={e => e.currentTarget.style.background='var(--dgd-bg,#f8fafc)'}
                        onMouseLeave={e => e.currentTarget.style.background='transparent'}
                        onClick={() => setBantModal({ prospect: p, campanhaNome: p.campanha })}
                      >
                        <td style={{ ...td, fontWeight:600, color:'var(--dgd-fg-1)' }}>{p.contacto_nome || '—'}</td>
                        <td style={{ ...td, fontSize:12 }}>{p.empresa}</td>
                        <td style={{ ...td, fontSize:11.5 }}>{p.campanha}</td>
                        <td style={td}><BantDots p={p} /></td>
                        <td style={td} onClick={e => e.stopPropagation()}>
                          <button onClick={() => setBantModal({ prospect: p, campanhaNome: p.campanha })}
                            style={{ padding:'4px 10px', borderRadius:5, border:'1px solid #166534', background:'transparent', fontSize:11.5, cursor:'pointer', color:'#166534', fontWeight:600 }}>Ver</button>
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
        )}

        {/* Tab: Inativas */}
        {!loading && subTab === 'inativas' && (
          inativas.length === 0
            ? <div style={{ padding:32, textAlign:'center', color:'var(--dgd-fg-3)', fontSize:12 }}>Sem prospects inativas.</div>
            : <div style={{ overflowX:'auto' }}>
              <table style={{ width:'100%', borderCollapse:'collapse', fontSize:12 }}>
                <thead>
                  <tr>
                    <th style={thBase} onClick={() => handleSort('contacto_nome')}>Nome{sortArrow('contacto_nome')}</th>
                    <th style={thBase} onClick={() => handleSort('empresa')}>Empresa{sortArrow('empresa')}</th>
                    <th style={thBase} onClick={() => handleSort('campanha')}>Campanha{sortArrow('campanha')}</th>
                    <th style={thNoSort}>BANT</th>
                    <th style={thNoSort}>Estado</th>
                    <th style={thNoSort}></th>
                  </tr>
                </thead>
                <tbody>
                  {applySort(inativas).map(function(p) {
                    const ec = estadoCfg[p.estado] || estadoCfg.sem_interesse;
                    return (
                      <tr key={p.inscricao_id || p.id} style={{ cursor:'pointer' }}
                        onMouseEnter={e => e.currentTarget.style.background='var(--dgd-bg,#f8fafc)'}
                        onMouseLeave={e => e.currentTarget.style.background='transparent'}
                        onClick={() => setBantModal({ prospect: p, campanhaNome: p.campanha })}
                      >
                        <td style={{ ...td, fontWeight:600, color:'var(--dgd-fg-1)' }}>{p.contacto_nome || '—'}</td>
                        <td style={{ ...td, fontSize:12 }}>{p.empresa}</td>
                        <td style={{ ...td, fontSize:11.5 }}>{p.campanha}</td>
                        <td style={td}><BantDots p={p} /></td>
                        <td style={td}><span style={{ display:'inline-block', padding:'2px 8px', borderRadius:99, fontSize:10.5, fontWeight:600, color:ec.color, background:ec.bg, border:`1px solid ${ec.border}` }}>{ec.label}</span></td>
                        <td style={td} onClick={e => e.stopPropagation()}>
                          <button onClick={() => handleRestaurar(p)}
                            style={{ padding:'3px 10px', borderRadius:6, border:'1px solid #fde68a', background:'#fffbeb', color:'#92400e', fontSize:11, cursor:'pointer', fontWeight:500, whiteSpace:'nowrap' }}>Restaurar</button>
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
        )}
      </div>
    </div>
    {bantModal && (
      <SdrBantModal
        prospect={bantModal.prospect}
        campanhaNome={bantModal.campanhaNome}
        onClose={() => setBantModal(null)}
        onSaved={() => fetchProspects(false)}
        user={user}
      />
    )}
    </>
  );
};

// ─── Modal detalhe de lead qualificada ────────────────────────────────────────
const SdrQualificadaModal = ({ row, onClose }) => {
  const [data, setData]       = React.useState(null);
  const [loading, setLoading] = React.useState(true);
  const [err, setErr]         = React.useState('');

  React.useEffect(function() {
    if (!row.prospect_id) { setLoading(false); return; }
    fetch('/api/comercial/sdr/prospect/' + row.prospect_id, { credentials: 'include' })
      .then(function(r) { return r.json(); })
      .then(function(d) { if (d.error) throw new Error(d.error); setData(d); })
      .catch(function(e) { setErr(e.message); })
      .finally(function() { setLoading(false); });
  }, [row.prospect_id]);

  const overlay = { position:'fixed', inset:0, zIndex:2100, background:'rgba(0,0,0,0.45)', display:'flex', alignItems:'center', justifyContent:'center', padding:24 };
  const card    = { width:'100%', maxWidth:780, maxHeight:'88vh', overflowY:'auto', background:'var(--dgd-bg-surface,#fff)', border:'1px solid var(--dgd-border-1)', borderRadius:12, boxShadow:'0 12px 48px rgba(0,0,0,0.22)' };
  const thS     = { padding:'6px 12px', textAlign:'left', fontSize:10, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', letterSpacing:'0.06em', textTransform:'uppercase', fontWeight:600, background:'var(--dgd-bg,#f8fafc)', borderBottom:'1px solid var(--dgd-border-1)' };
  const tdL     = { padding:'7px 0', borderBottom:'1px solid var(--dgd-border-1)', color:'var(--dgd-fg-3)', fontSize:11, width:110, verticalAlign:'top', paddingRight:8 };
  const tdV     = { padding:'7px 0', borderBottom:'1px solid var(--dgd-border-1)', color:'var(--dgd-fg-1)', fontSize:12.5, verticalAlign:'top' };

  const bantFields = [['Budget','bant_budget'],['Authority','bant_authority'],['Need','bant_need'],['Timeline','bant_timeline']];
  const bantDone = bantFields.every(function(f) { return row[f[1]] === true; });

  const empresa = data?.empresa;
  const contactos = data?.contactos || [];
  const fm_ops = data?.fm_ops || [];
  const noGestor = empresa && !empresa.fm_entidade_id;

  return (
    <div style={overlay} onClick={function(e) { if (e.target === e.currentTarget) onClose(); }}>
      <div style={card}>
        {/* Header */}
        <div style={{ padding:'16px 20px', borderBottom:'1px solid var(--dgd-border-1)', display:'flex', alignItems:'flex-start', gap:12 }}>
          <div style={{ flex:1 }}>
            <div style={{ fontSize:10, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', letterSpacing:'0.08em', marginBottom:3 }}>LEAD QUALIFICADA · SDR</div>
            <div style={{ fontSize:15, fontWeight:700, color:'var(--dgd-fg-1)' }}>{row.empresa_nome}</div>
            <div style={{ fontSize:12, color:'var(--dgd-fg-3)', marginTop:2 }}>{row.campanha} · {row.sdr_nome_curto || row.sdr_nome}</div>
          </div>
          {/* FM sync badge */}
          {empresa && (
            empresa.fm_entidade_id
              ? <span style={{ padding:'4px 10px', borderRadius:6, fontSize:10.5, fontWeight:600, background:'#f0fdf4', border:'1px solid #bbf7d0', color:'#166534', whiteSpace:'nowrap' }}>✓ No Gestor</span>
              : <span style={{ padding:'4px 10px', borderRadius:6, fontSize:10.5, fontWeight:600, background:'#fffbeb', border:'1px solid #fde68a', color:'#92400e', whiteSpace:'nowrap' }}>Não sincronizado</span>
          )}
          <button onClick={onClose} style={{ background:'transparent', border:'none', cursor:'pointer', color:'var(--dgd-fg-3)', padding:6, flexShrink:0 }}>
            <svg width="16" height="16" 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={{ padding:20, display:'flex', flexDirection:'column', gap:20 }}>
          {loading && <div style={{ textAlign:'center', padding:32, color:'var(--dgd-fg-3)', fontSize:13 }}>A carregar...</div>}
          {err && <div style={{ padding:12, background:'#fee2e2', borderRadius:8, color:'#991b1b', fontSize:13 }}>{err}</div>}

          {/* BANT + Notas */}
          <div style={{ background:'var(--dgd-bg,#f8fafc)', border:'1px solid var(--dgd-border-1)', borderRadius:8, overflow:'hidden' }}>
            <div style={thS}>Qualificação BANT</div>
            <div style={{ padding:'14px 16px' }}>
              <div style={{ display:'flex', gap:10, marginBottom:14, flexWrap:'wrap' }}>
                {bantFields.map(function(f) {
                  const v = row[f[1]];
                  const color  = v===true?'#166534':v===false?'#991b1b':'#64748b';
                  const bg     = v===true?'#f0fdf4':v===false?'#fef2f2':'#f1f5f9';
                  const border = v===true?'#bbf7d0':v===false?'#fecaca':'#e2e8f0';
                  const label  = v===true?'Sim':v===false?'Não':'?';
                  return (
                    <div key={f[0]} style={{ padding:'8px 14px', borderRadius:8, border:'1px solid '+border, background:bg, minWidth:90, textAlign:'center' }}>
                      <div style={{ fontSize:10, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', marginBottom:3 }}>{f[0]}</div>
                      <div style={{ fontSize:14, fontWeight:700, color }}>{label}</div>
                    </div>
                  );
                })}
                {bantDone && (
                  <div style={{ padding:'8px 14px', borderRadius:8, border:'1px solid #bbf7d0', background:'#f0fdf4', display:'flex', alignItems:'center', gap:6 }}>
                    <span style={{ fontSize:13, fontWeight:700, color:'#166534' }}>✓ BANT Completo</span>
                  </div>
                )}
              </div>
              {row.nif_cliente && (
                <div style={{ display:'flex', gap:8, alignItems:'center', marginBottom:10 }}>
                  <span style={{ fontSize:10.5, fontWeight:600, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)' }}>NIF</span>
                  <span style={{ fontSize:13, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-1)', fontWeight:600 }}>{row.nif_cliente}</span>
                </div>
              )}
              {row.notas && (
                <div>
                  <div style={{ fontSize:10, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', marginBottom:5, letterSpacing:'0.06em' }}>NOTAS</div>
                  <div style={{ fontSize:13, color:'var(--dgd-fg-1)', lineHeight:1.6, whiteSpace:'pre-wrap' }}>{row.notas}</div>
                </div>
              )}
              <div style={{ marginTop:10, fontSize:10.5, color:'var(--dgd-fg-3)' }}>
                Qualificado por <strong style={{ color:'var(--dgd-fg-2)' }}>{row.sdr_nome_curto || row.sdr_nome}</strong> · actualizado {new Date(row.updated_at).toLocaleDateString('pt-PT', { day:'2-digit', month:'long', year:'numeric', hour:'2-digit', minute:'2-digit' })}
              </div>
            </div>
          </div>

          {/* Empresa */}
          {empresa && (
            <div style={{ background:'var(--dgd-bg,#f8fafc)', border:'1px solid var(--dgd-border-1)', borderRadius:8, overflow:'hidden' }}>
              <div style={thS}>Empresa</div>
              <div style={{ padding:'14px 16px' }}>
                <table style={{ width:'100%', borderCollapse:'collapse', fontSize:12.5 }}>
                  <tbody>
                    {[
                      ['Segmento', empresa.segmento || '—'],
                      ['Tipo', empresa.segmento_tipo || '—'],
                      ['Cód. Postal', row.codigo_postal || empresa.codigo_postal || '—'],
                      ['Localidade', row.localidade || empresa.cidade || '—'],
                      ['Distrito', row.distrito || empresa.distrito || '—'],
                      ['Concelho', row.concelho || '—'],
                      ['CAE', empresa.cae_desc || '—'],
                      ['Funcionários', empresa.funcionarios ? `~${empresa.funcionarios}` : '—'],
                      ['Website', empresa.website ? <a href={empresa.website} target="_blank" rel="noreferrer" style={{ color:'#112954' }}>{empresa.website.replace(/^https?:\/\//,'')}</a> : '—'],
                      ['Telefone', empresa.telefone || '—'],
                      ['No Gestor', empresa.fm_entidade_id ? <span style={{ color:'#166534', fontWeight:600 }}>{empresa.fm_entidade_id} ({empresa.fm_tenant})</span> : <span style={{ color:'#92400e' }}>Não sincronizado</span>],
                    ].map(function(kv) { return (
                      <tr key={kv[0]}>
                        <td style={tdL}>{kv[0]}</td>
                        <td style={tdV}>{kv[1]}</td>
                      </tr>
                    ); })}
                  </tbody>
                </table>
              </div>
            </div>
          )}

          {/* Contactos */}
          {contactos.length > 0 && (
            <div style={{ background:'var(--dgd-bg,#f8fafc)', border:'1px solid var(--dgd-border-1)', borderRadius:8, overflow:'hidden' }}>
              <div style={thS}>Contactos</div>
              <div style={{ padding:'14px 16px', display:'flex', flexDirection:'column', gap:8 }}>
                {contactos.map(function(c, i) { return (
                  <div key={i} style={{ padding:'10px 12px', border:'1px solid var(--dgd-border-1)', borderRadius:8, background: i===0 ? 'color-mix(in oklch,#112954 4%,transparent)' : 'transparent' }}>
                    {i===0 && <div style={{ fontSize:9.5, fontFamily:'var(--dgd-font-mono,monospace)', color:'#112954', fontWeight:700, letterSpacing:'0.06em', marginBottom:4 }}>CONTACTO PRINCIPAL</div>}
                    <div style={{ fontWeight:600, fontSize:13, color:'var(--dgd-fg-1)' }}>{c.nome_completo}</div>
                    <div style={{ fontSize:12, color:'var(--dgd-fg-2)', marginTop:2 }}>{c.cargo}{c.senioridade ? ' · '+c.senioridade : ''}</div>
                    <div style={{ display:'flex', gap:14, marginTop:6, flexWrap:'wrap' }}>
                      {c.email    && <span style={{ fontSize:12, color:'var(--dgd-fg-2)' }}>✉ {c.email}</span>}
                      {c.telemovel && <span style={{ fontSize:12, color:'var(--dgd-fg-2)' }}>📞 {c.telemovel}</span>}
                      {c.linkedin_url && <a href={c.linkedin_url} target="_blank" rel="noreferrer" style={{ fontSize:11.5, color:'#0a66c2' }}>LinkedIn</a>}
                    </div>
                  </div>
                ); })}
              </div>
            </div>
          )}

          {/* OPs activas no FM */}
          {empresa?.fm_entidade_id && (
            <div style={{ background:'var(--dgd-bg,#f8fafc)', border:'1px solid var(--dgd-border-1)', borderRadius:8, overflow:'hidden' }}>
              <div style={thS}>Oportunidades Activas no Gestor</div>
              <div style={{ padding:'14px 16px' }}>
                {fm_ops.length === 0
                  ? <div style={{ fontSize:12.5, color:'var(--dgd-fg-3)' }}>Sem oportunidades activas.</div>
                  : fm_ops.map(function(op, i) { return (
                    <div key={i} style={{ display:'flex', gap:12, alignItems:'center', padding:'6px 0', borderBottom: i<fm_ops.length-1 ? '1px solid var(--dgd-border-1)':'' }}>
                      <span style={{ fontSize:11, fontFamily:'var(--dgd-font-mono,monospace)', color:'var(--dgd-fg-3)', minWidth:80 }}>{op.id_op}</span>
                      <span style={{ flex:1, fontSize:12.5, color:'var(--dgd-fg-1)' }}>{op.produto}</span>
                      <span style={{ fontSize:11.5, color:'#1d4ed8', fontWeight:600 }}>{op.stage}</span>
                      {op.valor_k && <span style={{ fontSize:11.5, color:'var(--dgd-fg-2)' }}>{op.valor_k}k</span>}
                    </div>
                  ); })
                }
              </div>
            </div>
          )}

          {/* Alerta não sincronizado + BANT completo */}
          {noGestor && bantDone && (
            <div style={{ padding:'12px 16px', borderRadius:8, background:'#fffbeb', border:'1px solid #fde68a', fontSize:13, color:'#92400e', lineHeight:1.6 }}>
              <strong>BANT completo mas empresa não está no Gestor.</strong> Criar entidade no FileMaker antes de passar ao comercial.
            </div>
          )}
        </div>

        <div style={{ padding:'12px 20px', borderTop:'1px solid var(--dgd-border-1)', display:'flex', justifyContent:'flex-end', background:'var(--dgd-bg,#f8fafc)' }}>
          <button onClick={onClose} style={{ padding:'7px 18px', borderRadius:6, border:'1px solid var(--dgd-border-1)', background:'transparent', fontSize:13, cursor:'pointer', color:'var(--dgd-fg-2)' }}>Fechar</button>
        </div>
      </div>
    </div>
  );
};

// ─── Tab Qualificadas — visão transversal de todos os BANTs guardados ─────────
const SdrQualificadasTab = ({ sdrEmailFilter }) => {
  const [rows, setRows]       = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [selSdr, setSelSdr]   = React.useState(sdrEmailFilter || null);
  const [search, setSearch]   = React.useState('');
  const [selRow, setSelRow]   = React.useState(null);

  React.useEffect(function() {
    fetch('/api/comercial/sdr/qualificadas', { credentials: 'include' })
      .then(function(r) { return r.json(); })
      .then(function(d) { if (Array.isArray(d)) setRows(d); })
      .catch(function() {})
      .finally(function() { setLoading(false); });
  }, []);

  const sdrs = [...new Map(rows.filter(r => r.sdr_email).map(r => [r.sdr_email, r.sdr_nome_curto || r.sdr_nome])).entries()];

  const filtered = rows.filter(function(r) {
    if (selSdr && r.sdr_email !== selSdr) return false;
    if (search) {
      const q = search.toLowerCase();
      if (!r.empresa_nome?.toLowerCase().includes(q) && !r.campanha?.toLowerCase().includes(q)) return false;
    }
    return true;
  });

  const bantDone = function(r) { return r.bant_budget && r.bant_authority && r.bant_need && r.bant_timeline; };
  const bantPartial = function(r) { return !bantDone(r) && (r.bant_budget !== null || r.bant_authority !== null || r.bant_need !== null || r.bant_timeline !== null); };

  const th = { 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' };
  const td = { padding:'9px 12px', fontSize:12.5, borderBottom:'1px solid var(--dgd-border-1)', color:'var(--dgd-fg-2)', verticalAlign:'top' };

  const totais = { total: filtered.length, completo: filtered.filter(bantDone).length, parcial: filtered.filter(bantPartial).length };

  return (
    <div style={{ marginTop:20 }}>
      {/* Header + filtros */}
      <div style={{ display:'flex', alignItems:'center', gap:8, marginBottom:12, flexWrap:'wrap' }}>
        <div style={{ flex:1 }}>
          <div style={{ fontSize:10, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', letterSpacing:'0.08em', marginBottom:3 }}>LEADS QUALIFICADAS · SDR</div>
          <div style={{ fontSize:15, fontWeight:600, color:'var(--dgd-fg-1)' }}>Pipeline de Prospecção</div>
        </div>
        <input
          value={search} onChange={function(e) { setSearch(e.target.value); }}
          placeholder="Pesquisar empresa ou campanha..."
          style={{ padding:'5px 10px', borderRadius:6, border:'1px solid var(--dgd-border-1)', fontSize:12, outline:'none', width:220, color:'var(--dgd-fg-1)', background:'var(--dgd-bg-surface,#fff)' }}
        />
      </div>

      {/* Pills SDR — só para admin */}
      {!sdrEmailFilter && sdrs.length > 0 && (
        <div style={{ display:'flex', alignItems:'center', gap:6, marginBottom:14, flexWrap:'wrap' }}>
          <span style={{ fontSize:11, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', letterSpacing:'0.06em', marginRight:2 }}>SDR</span>
          <button onClick={function() { setSelSdr(null); }} style={{ padding:'4px 12px', borderRadius:99, border:'1px solid', fontSize:11.5, cursor:'pointer', fontWeight:selSdr===null?700:400, background:selSdr===null?'#112954':'transparent', color:selSdr===null?'#fff':'var(--dgd-fg-2)', borderColor:selSdr===null?'#112954':'var(--dgd-border-1)' }}>Todos</button>
          {sdrs.map(function(s) { return (
            <button key={s[0]} onClick={function() { setSelSdr(s[0]); }} style={{ padding:'4px 12px', borderRadius:99, border:'1px solid', fontSize:11.5, cursor:'pointer', fontWeight:selSdr===s[0]?700:400, background:selSdr===s[0]?'#112954':'transparent', color:selSdr===s[0]?'#fff':'var(--dgd-fg-2)', borderColor:selSdr===s[0]?'#112954':'var(--dgd-border-1)' }}>{s[1]}</button>
          ); })}
        </div>
      )}

      {/* KPI cards */}
      <div style={{ display:'flex', gap:8, marginBottom:14 }}>
        {[
          { l:'Total', v:totais.total,    c:'#1d4ed8' },
          { l:'BANT Completo', v:totais.completo, c:'#166534' },
          { l:'Em Progresso',  v:totais.parcial,  c:'#92400e' },
        ].map(function(k) { return (
          <div key={k.l} style={{ flex:1, padding:'10px 14px', background:'var(--dgd-bg-card,white)', border:'1px solid var(--dgd-border-1)', borderRadius:8 }}>
            <div style={{ fontSize:10, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', marginBottom:4 }}>{k.l}</div>
            <div style={{ fontSize:22, fontWeight:700, color:k.c }}>{k.v}</div>
          </div>
        ); })}
      </div>

      {/* Tabela */}
      <div style={{ background:'var(--dgd-bg-card,white)', border:'1px solid var(--dgd-border-1)', borderRadius:8, overflow:'hidden' }}>
        {loading ? (
          <div style={{ padding:32, textAlign:'center', color:'var(--dgd-fg-3)', fontSize:12 }}>A carregar...</div>
        ) : filtered.length === 0 ? (
          <div style={{ padding:32, textAlign:'center', color:'var(--dgd-fg-3)', fontSize:12 }}>Sem leads qualificadas.</div>
        ) : (
          <div style={{ overflowX:'auto' }}>
            <table style={{ width:'100%', borderCollapse:'collapse' }}>
              <thead>
                <tr>
                  {['Empresa','Campanha','SDR','BANT','NIF','Notas','Actualizado'].map(function(h) { return <th key={h} style={th}>{h}</th>; })}
                </tr>
              </thead>
              <tbody>
                {filtered.map(function(r) {
                  const done = bantDone(r);
                  return (
                    <tr key={r.id}
                      onClick={function() { setSelRow(r); }}
                      style={{ cursor:'pointer' }}
                      onMouseEnter={function(e) { e.currentTarget.style.background='var(--dgd-bg,#f8fafc)'; }}
                      onMouseLeave={function(e) { e.currentTarget.style.background='transparent'; }}
                    >
                      <td style={{ ...td, fontWeight:500, color:'var(--dgd-fg-1)', whiteSpace:'nowrap' }}>{r.empresa_nome}</td>
                      <td style={{ ...td, fontSize:11.5 }}>{r.campanha}</td>
                      <td style={{ ...td, fontSize:11.5, whiteSpace:'nowrap' }}>{r.sdr_nome_curto || r.sdr_nome || r.sdr_email}</td>
                      <td style={td}>
                        <div style={{ display:'flex', gap:3 }}>
                          {[['B',r.bant_budget],['A',r.bant_authority],['N',r.bant_need],['T',r.bant_timeline]].map(function(bv) {
                            const v = bv[1];
                            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 key={bv[0]} 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 }}>{bv[0]}</span>;
                          })}
                          {done && <span style={{ marginLeft:4, fontSize:10, fontWeight:600, color:'#166534' }}>✓</span>}
                        </div>
                      </td>
                      <td style={{ ...td, fontSize:11.5, fontFamily:'var(--dgd-font-mono,monospace)' }}>{r.nif_cliente || '—'}</td>
                      <td style={{ ...td, fontSize:11.5, maxWidth:240, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }} title={r.notas || ''}>{r.notas || '—'}</td>
                      <td style={{ ...td, fontSize:11, color:'var(--dgd-fg-3)', whiteSpace:'nowrap' }}>
                        {r.updated_at ? new Date(r.updated_at).toLocaleDateString('pt-PT', { day:'2-digit', month:'short', hour:'2-digit', minute:'2-digit' }) : '—'}
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        )}
      </div>
      {selRow && <SdrQualificadaModal row={selRow} onClose={function() { setSelRow(null); }} />}
    </div>
  );
};

// ─── Tabela funil SDR Humano (completa) ───────────────────────────────────────

const SdrFunilTable = ({ rows, onCellClick }) => {
  const mesIdx = (() => { const m = SDR_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 ytd = rows.reduce((s, r) => ({
    atribuidos_sdr:     s.atribuidos_sdr     + r.atribuidos_sdr,
    atribuidos_prospect:s.atribuidos_prospect + r.atribuidos_prospect,
    contactados_sdr:    s.contactados_sdr    + r.contactados_sdr,
    contactados_prospect:s.contactados_prospect + r.contactados_prospect,
    qualificados: s.qualificados + r.qualificados,
    agendadas:    s.agendadas    + r.agendadas,
    passados:     s.passados     + r.passados,
    pipeline_k:   s.pipeline_k   + r.pipeline_k,
  }), { atribuidos_sdr:0, atribuidos_prospect:0, contactados_sdr:0, contactados_prospect:0, qualificados:0, agendadas:0, passados:0, pipeline_k:0 });

  const atTotal  = r => r.atribuidos_sdr + r.atribuidos_prospect;
  const ctTotal  = r => r.contactados_sdr + r.contactados_prospect;
  const clickStyle = { cursor:'pointer', textDecoration:'underline', textDecorationStyle:'dotted' };
  const cl = (metric, mes, val) => onCellClick ? { onClick: () => onCellClick(metric, mes, val) } : {};
  const ytdAt    = ytd.atribuidos_sdr + ytd.atribuidos_prospect;
  const ytdCt    = ytd.contactados_sdr + ytd.contactados_prospect;
  const tcYTD   = sdrPct(ytdCt, ytdAt);
  const tqYTD   = sdrPct(ytd.qualificados, ytdCt);
  const tqcYTD  = sdrPct(ytd.passados, ytd.qualificados);

  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' };

  return (
    <div style={{ overflowX:'auto' }}>
      <table style={{ borderCollapse:'collapse', width:'100%', fontSize:12 }}>
        <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?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>
          <SdrSectionRow cols={nCols}>Funil de Prospecção</SdrSectionRow>
          <tr>
            <td style={tdL}>Leads SDR Atribuídas</td>
            <td style={{ ...tdBase, color:'var(--dgd-fg-3)' }}>--</td>
            {rows.map((r,i) => <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?700:400, ...(onCellClick?clickStyle:{}) }} {...cl('atribuidos_sdr', r.mes, r.atribuidos_sdr)}>{fv(r.atribuidos_sdr, i)}</td>)}
            <td style={{ ...tdBase, fontWeight:700, color:'var(--dgd-fg-1)' }}>{ytd.atribuidos_sdr}</td>
          </tr>
          <tr>
            <td style={tdL}>Leads Prospect Atribuídas</td>
            <td style={{ ...tdBase, color:'var(--dgd-fg-3)' }}>--</td>
            {rows.map((r,i) => <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?700:400, ...(onCellClick?clickStyle:{}) }} {...cl('atribuidos_prospect', r.mes, r.atribuidos_prospect)}>{fv(r.atribuidos_prospect, i)}</td>)}
            <td style={{ ...tdBase, fontWeight:700, color:'var(--dgd-fg-1)' }}>{ytd.atribuidos_prospect}</td>
          </tr>
          <tr>
            <td style={tdL}>Leads SDR Contactadas</td>
            <td style={{ ...tdBase, color:'var(--dgd-fg-3)' }}>--</td>
            {rows.map((r,i) => <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?700:400, ...(onCellClick?clickStyle:{}) }} {...cl('contactados_sdr', r.mes, r.contactados_sdr)}>{fv(r.contactados_sdr, i)}</td>)}
            <td style={{ ...tdBase, fontWeight:700, color:'var(--dgd-fg-1)' }}>{ytd.contactados_sdr}</td>
          </tr>
          <tr>
            <td style={tdL}>Leads Prospect Contactadas</td>
            <td style={{ ...tdBase, color:'var(--dgd-fg-3)' }}>--</td>
            {rows.map((r,i) => <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?700:400, ...(onCellClick?clickStyle:{}) }} {...cl('contactados_prospect', r.mes, r.contactados_prospect)}>{fv(r.contactados_prospect, i)}</td>)}
            <td style={{ ...tdBase, fontWeight:700, color:'var(--dgd-fg-1)' }}>{ytd.contactados_prospect}</td>
          </tr>
          <tr>
            <td style={tdL}>Taxa de Contacto</td>
            <td style={{ ...tdBase, color:'#1d4ed8', fontWeight:600 }}>&gt;={SDR_METAS.taxa_contacto}%</td>
            {rows.map((r,i) => {
              const v = i > mesIdx ? null : sdrPct(ctTotal(r), atTotal(r));
              return <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?700:400, color:sdrColor(v,SDR_METAS.taxa_contacto), background:i===mesIdx?sdrBg(v,SDR_METAS.taxa_contacto):'transparent' }}>{v === null ? '—' : `${v}%`}</td>;
            })}
            <td style={{ ...tdBase, fontWeight:700, color:sdrColor(tcYTD,SDR_METAS.taxa_contacto) }}>{tcYTD === null ? '—' : `${tcYTD}%`}</td>
          </tr>
          <tr>
            <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?700:400, ...(onCellClick?clickStyle:{}) }} {...cl('qualificados', r.mes, r.qualificados)}>{fv(r.qualificados, i)}</td>)}
            <td style={{ ...tdBase, fontWeight:700, color:'var(--dgd-fg-1)', ...(onCellClick?clickStyle:{}) }} {...cl('qualificados', 'YTD', ytd.qualificados)}>{ytd.qualificados}</td>
          </tr>
          <tr>
            <td style={tdL}>Taxa de Qualificação BANT</td>
            <td style={{ ...tdBase, color:'#1d4ed8', fontWeight:600 }}>&gt;={SDR_METAS.taxa_qualif}%</td>
            {rows.map((r,i) => {
              const v = i > mesIdx ? null : sdrPct(r.qualificados, ctTotal(r));
              return <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?700:400, color:sdrColor(v,SDR_METAS.taxa_qualif), background:i===mesIdx?sdrBg(v,SDR_METAS.taxa_qualif):'transparent' }}>{v === null ? '—' : `${v}%`}</td>;
            })}
            <td style={{ ...tdBase, fontWeight:700, color:sdrColor(tqYTD,SDR_METAS.taxa_qualif) }}>{tqYTD === null ? '—' : `${tqYTD}%`}</td>
          </tr>
          <SdrSectionRow cols={nCols}>Oportunidades &amp; SLA</SdrSectionRow>
          <tr>
            <td style={{ ...tdL, fontWeight:600, color:'var(--dgd-fg-1)' }}>Oportunidades Passadas</td>
            <td style={{ ...tdBase, color:'var(--dgd-fg-3)' }}>--</td>
            {rows.map((r,i) => <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?700:400 }}>{fv(r.passados, i)}</td>)}
            <td style={{ ...tdBase, fontWeight:700, color:'var(--dgd-fg-1)' }}>{ytd.passados}</td>
          </tr>
          <tr>
            <td style={{ ...tdL, paddingLeft:22, color:'var(--dgd-fg-3)' }}>↳ Demos Agendadas</td>
            <td style={{ ...tdBase, color:'#1d4ed8', fontWeight:600 }}>&gt;={SDR_METAS.agendadas_mes}/mes</td>
            {rows.map((r,i) => <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?700:400, color:i>mesIdx?'var(--dgd-fg-3)':sdrColor(r.agendadas,SDR_METAS.agendadas_mes), background:i===mesIdx?sdrBg(r.agendadas,SDR_METAS.agendadas_mes):'transparent' }}>{fv(r.agendadas, i)}</td>)}
            <td style={{ ...tdBase, fontWeight:700, color:'var(--dgd-fg-1)' }}>{ytd.agendadas}</td>
          </tr>
          <tr>
            <td style={tdL}>Taxa de qualificação comercial</td>
            <td style={{ ...tdBase, color:'#1d4ed8', fontWeight:600 }}>&gt;={SDR_METAS.conv_pct}%</td>
            {rows.map((r,i) => {
              const v = i > mesIdx ? null : sdrPct(r.passados, r.qualificados);
              return <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?700:400, color:sdrColor(v,SDR_METAS.conv_pct), background:i===mesIdx?sdrBg(v,SDR_METAS.conv_pct):'transparent' }}>{v === null ? '—' : `${v}%`}</td>;
            })}
            <td style={{ ...tdBase, fontWeight:700, color:sdrColor(tqcYTD,SDR_METAS.conv_pct) }}>{tqcYTD === null ? '—' : `${tqcYTD}%`}</td>
          </tr>
          <tr>
            <td style={tdL}>Taxa de No-Show (Demos)</td>
            <td style={{ ...tdBase, color:'#1d4ed8', fontWeight:600 }}>&lt;={SDR_METAS.noshow_pct}%</td>
            {rows.map((r,i) => <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?700:400, color:i>mesIdx?'var(--dgd-fg-3)':sdrColor(r.noshow_pct,SDR_METAS.noshow_pct,false), background:i===mesIdx?sdrBg(r.noshow_pct,SDR_METAS.noshow_pct,false):'transparent' }}>{i>mesIdx?'—':`${r.noshow_pct}%`}</td>)}
            <td style={{ ...tdBase, color:'var(--dgd-fg-3)' }}>--</td>
          </tr>
          <tr>
            <td style={tdL}>Tempo de Resposta a Lead Novo</td>
            <td style={{ ...tdBase, color:'#1d4ed8', fontWeight:600 }}>&lt;={SDR_METAS.tempo_resp}h</td>
            {rows.map((r,i) => <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?700:400, color:i>mesIdx?'var(--dgd-fg-3)':sdrColor(r.tempo_resp,SDR_METAS.tempo_resp,false), background:i===mesIdx?sdrBg(r.tempo_resp,SDR_METAS.tempo_resp,false):'transparent' }}>{i>mesIdx?'—':`${r.tempo_resp}h`}</td>)}
            <td style={{ ...tdBase, color:'var(--dgd-fg-3)' }}>--</td>
          </tr>
          <SdrSectionRow cols={nCols}>Resultado</SdrSectionRow>
          <tr>
            <td style={tdL}>Pipeline Gerado</td>
            <td style={{ ...tdBase, color:'var(--dgd-fg-3)' }}>--</td>
            {rows.map((r,i) => <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?700:400, color:'#1d4ed8' }}>{r.pipeline_k}k</td>)}
            <td style={{ ...tdBase, fontWeight:700, color:'#1d4ed8' }}>{ytd.pipeline_k}k</td>
          </tr>
          <tr>
            <td style={tdL}>Taxa Conv. Qualificado→Lost</td>
            <td style={{ ...tdBase, color:'#1d4ed8', fontWeight:600 }}>&lt;=30%</td>
            {rows.map((r,i) => {
              const v = i > mesIdx ? null : sdrPct(r.qualificados - r.passados, r.qualificados);
              return <td key={r.mes} style={{ ...tdBase, fontWeight:i===mesIdx?700:400, color:sdrColor(v,30,false), background:i===mesIdx?sdrBg(v,30,false):'transparent' }}>{v === null ? '—' : `${v}%`}</td>;
            })}
            {(() => { const v = sdrPct(ytd.qualificados - ytd.passados, ytd.qualificados); return <td style={{ ...tdBase, fontWeight:700, color:sdrColor(v,30,false) }}>{v === null ? '—' : `${v}%`}</td>; })()}
          </tr>
        </tbody>
      </table>
    </div>
  );
};

// ─── Screen principal ─────────────────────────────────────────────────────────

const SDR_FUNIL_EMPTY = ['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez'].map(mes => ({
  mes, atribuidos_sdr:0, atribuidos_prospect:0, contactados_sdr:0, contactados_prospect:0,
  qualificados:0, agendadas:0, passados:0, noshow_pct:0, tempo_resp:0, pipeline_k:0, conv_pct:0,
}));

const ScreenComercialRpcSDR = ({ user }) => {
  // isAdmin: derivado da sdrList (carregada do API) + tipo_utilizador
  // Quando o email do user está na sdrList E não é tipo admin → SDR restrito
  // Não depende de portal_subs (que pode não estar no user prop da shell)
  const _isAdminType = ['admin','chairman','c_suite','superadmin'].includes(user?.tipo_utilizador)
    || (Array.isArray(user?.modos_acesso) && user.modos_acesso.includes('dev'));
  // isSdrOnly: via portal_subs (ver-como passa do shell) OU via email na sdrList (login directo)
  const _hasSdrSub = user?.portal_subs != null
    && Array.isArray(user?.portal_subs?.comercial)
    && user.portal_subs.comercial.includes('rpc-sdr');

  const [tab,             setTab]          = React.useState('sdr-ai');
  const [selSDR,          setSelSDR]       = React.useState(null);
  const [selTenant,       setSelTenant]    = React.useState(null);
  const [sdrList,         setSdrList]      = React.useState([]);
  const [selAno,          setSelAno]       = React.useState(new Date().getFullYear());
  const [modal,           setModal]        = React.useState(null);
  const [funilData,       setFunilData]    = React.useState(SDR_FUNIL_EMPTY);
  const [funilTick,       setFunilTick]    = React.useState(0);
  const [aiKpis,          setAiKpis]       = React.useState(null);
  // aiFunil / aiLeads → geridos dentro de window.SdrAITab (screen_comercial_rpc_sdr_ai.jsx)

  // isAdmin: false quando tem sub SDR (ver-como) OU email na sdrList (login directo) — e não é tipo admin
  const isAdmin = _isAdminType || (!_hasSdrSub && !sdrList.some(s => s.email === user?.email));

  // Quando isAdmin muda para false (sdrList carregou): bloquear tab + selSDR no próprio email
  React.useEffect(() => {
    if (!isAdmin && user?.email) {
      setTab('sdr-humano');
      setSelSDR(user.email);
    }
  }, [isAdmin, user?.email]);

  React.useEffect(() => {
    const onKpis = (e) => setAiKpis(e.detail || null);
    window.addEventListener('sdr-ai-kpis', onKpis);
    return () => window.removeEventListener('sdr-ai-kpis', onKpis);
  }, []);

  // ai-funil / ai-leads fetch → dentro de window.SdrAITab

  React.useEffect(() => {
    fetch('/api/comercial/sdr/list', { credentials:'include' })
      .then(r => r.json()).catch(() => [])
      .then(rows => { if (Array.isArray(rows)) setSdrList(rows); });
  }, []);

  const visibleSdrs  = React.useMemo(() => selTenant ? sdrList.filter(s => s.tenant === selTenant) : sdrList, [selTenant, sdrList]);
  const selSdrEmail  = selSDR; // selSDR já é o email directamente
  const refreshFunil = React.useCallback(() => setFunilTick(t => t + 1), []);

  const handleSetTenant = (t) => {
    setSelTenant(t);
    // reset SDR se não pertencer ao novo tenant
    if (t && selSDR) {
      const stillValid = sdrList.some(s => s.email === selSDR && s.tenant === t);
      if (!stillValid) setSelSDR(null);
    }
  };

  React.useEffect(() => {
    let url = `/api/comercial/sdr/funil?ano=${selAno}`;
    if (selSdrEmail) {
      url += `&sdr_email=${encodeURIComponent(selSdrEmail)}`;
    } else if (visibleSdrs.length > 0) {
      url += `&sdr_emails=${encodeURIComponent(visibleSdrs.map(s => s.email).join(','))}`;
    }
    fetch(url, { credentials:'include' })
      .then(r => r.json()).catch(() => null)
      .then(data => { if (Array.isArray(data) && data.length) setFunilData(data); else setFunilData(SDR_FUNIL_EMPTY); });
  }, [selSdrEmail, visibleSdrs, selAno, funilTick]);

  const allRows = funilData;
  const mesIdx  = (() => { const m = SDR_MESES[new Date().getMonth()]; const i = allRows.findIndex(r => r.mes === m); return i >= 0 ? i : allRows.length - 1; })();
  const ultimo  = allRows[mesIdx] || SDR_FUNIL_EMPTY[0];

  const ytd = allRows.reduce((s, r) => ({
    atribuidos_sdr:      s.atribuidos_sdr      + r.atribuidos_sdr,
    atribuidos_prospect: s.atribuidos_prospect  + r.atribuidos_prospect,
    contactados_sdr:     s.contactados_sdr     + r.contactados_sdr,
    contactados_prospect:s.contactados_prospect + r.contactados_prospect,
    qualificados: s.qualificados + r.qualificados,
    agendadas:    s.agendadas    + r.agendadas,
    passados:     s.passados     + r.passados,
    pipeline_k:   s.pipeline_k   + r.pipeline_k,
  }), { atribuidos_sdr:0, atribuidos_prospect:0, contactados_sdr:0, contactados_prospect:0, qualificados:0, agendadas:0, passados:0, pipeline_k:0 });

  const totalSDR = SDR_POR_SDR.reduce((s, r) => ({
    atribuidos:   s.atribuidos   + r.atribuidos,
    contactados:  s.contactados  + r.contactados,
    qualificados: s.qualificados + r.qualificados,
    agendadas:    s.agendadas    + r.agendadas,
    pipeline_k:   s.pipeline_k   + r.pipeline_k,
  }), { atribuidos:0, contactados:0, qualificados:0, agendadas:0, pipeline_k:0 });

  const atTotal  = (r) => r.atribuidos_sdr + r.atribuidos_prospect;
  const ctTotal  = (r) => r.contactados_sdr + r.contactados_prospect;
  const tcMes  = sdrPct(ctTotal(ultimo), atTotal(ultimo));
  const tqMes  = sdrPct(ultimo.qualificados, ctTotal(ultimo));
  const tqcMes = sdrPct(ultimo.passados, ultimo.qualificados);

  const kpis = [
    { l:'Taxa de Contacto',       v:`${tcMes ?? 0}%`,          d:`Obj. >= ${SDR_METAS.taxa_contacto}%`,   c:sdrColor(tcMes, SDR_METAS.taxa_contacto) },
    { l:'Qualificação BANT',      v:`${tqMes ?? 0}%`,          d:`Obj. >= ${SDR_METAS.taxa_qualif}%`,     c:sdrColor(tqMes, SDR_METAS.taxa_qualif) },
    { l:'Oportunidades Passadas', v:ultimo.passados,            d:`${ytd.passados} YTD · ${ytd.agendadas} demos`, c:'var(--dgd-fg-1)' },
    { l:'Taxa qualif. comercial', v:`${tqcMes ?? 0}%`,         d:`Obj. >= ${SDR_METAS.conv_pct}%`,        c:sdrColor(tqcMes, SDR_METAS.conv_pct) },
    { l:'Pipeline Gerado',        v:`${ultimo.pipeline_k}k`,   d:`${ytd.pipeline_k}k YTD`,                c:'#1d4ed8' },
  ];

  const funilRows = funilData;

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

  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' };

  // handleCellClick → dentro de window.SdrAITab
  const SdrAITabView = window.SdrAITab;

  const handleHumanoCellClick = async (metric, mes) => {
    const titles = {
      atribuidos_sdr:       `Leads SDR Atribuídas — ${mes}`,
      atribuidos_prospect:  `Leads Prospect Atribuídas — ${mes}`,
      contactados_sdr:      `Leads SDR Contactadas — ${mes}`,
      contactados_prospect: `Leads Prospect Contactadas — ${mes}`,
      qualificados:         `Qualificados BANT — ${mes}`,
    };
    const title = titles[metric] || mes;
    setModal({ title, leads: null }); // null = loading

    const mesNum = SDR_MESES.indexOf(mes) + 1;
    if (!mesNum) return;

    let url = `/api/comercial/sdr/leads?mes=${mesNum}&ano=${selAno}`;
    if (selSdrEmail) {
      url += `&sdr_email=${encodeURIComponent(selSdrEmail)}`;
    } else if (visibleSdrs.length > 0) {
      url += `&sdr_emails=${encodeURIComponent(visibleSdrs.map(s => s.email).join(','))}`;
    }

    const data = await fetch(url, { credentials: 'include' }).then(r => r.json()).catch(() => []);

    const isContactado = l => l.action_updated_at !== null || l.tipo_inicial !== 'sem_contacto';
    const mapStatus = l => {
      if (l.acao === 'passar_oportunidade' || l.acao === 'agendar_demo') return 'passado_comercial';
      const t = l.action_tipo || l.tipo_inicial || 'sem_contacto';
      if (t === 'bant_completo')  return 'bant_completo';
      if (t === 'sem_contacto')   return 'atribuido';
      if (t === 'em_qualificacao' || t === 'nao_qualificado') return t;
      return 'contactado';
    };

    let filtered = [];
    if (metric === 'atribuidos_sdr')           filtered = data.filter(l => l.categoria === 'sdr');
    else if (metric === 'atribuidos_prospect')  filtered = data.filter(l => l.categoria === 'prospect');
    else if (metric === 'contactados_sdr')      filtered = data.filter(l => l.categoria === 'sdr' && isContactado(l));
    else if (metric === 'contactados_prospect') filtered = data.filter(l => l.categoria === 'prospect' && isContactado(l));
    else if (metric === 'qualificados')         filtered = data.filter(l => (l.action_tipo || l.tipo_inicial) === 'bant_completo');

    const leads = filtered.map(l => ({
      id:        l.id,
      nome:      l.nome,
      empresa:   l.empresa,
      segmento:  l.segmento,
      status:    mapStatus(l),
      ultimo_wa: l.action_updated_at
        ? new Date(l.action_updated_at).toLocaleDateString('pt-PT', { day:'2-digit', month:'2-digit' })
        : null,
    }));

    setModal({ title, leads });
  };

  return (
    <div className="scrollbar" style={{ height:'100%', overflowY:'auto', background:'var(--dgd-bg-app,#f8fafc)' }}>
      <div style={{ padding:'18px 24px 80px' }}>

        {/* Header */}
        <div style={{ marginBottom:16 }}>
          <div style={{ fontSize:10, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', letterSpacing:'0.1em', marginBottom:2 }}>COMERCIAL · RPC SDR · {selAno}</div>
          <div style={{ display:'flex', alignItems:'center', gap:10 }}>
            <h2 className="font-display" style={{ margin:0, fontSize:21, fontWeight:600, letterSpacing:'-0.01em', color:'var(--dgd-fg-1)', flexGrow:1 }}>
              RPC SDR — Inbound, Outbound &amp; Prospecção
              {isAdmin && <span style={{ fontSize:11, fontWeight:400, color:'#b45309', marginLeft:10, fontFamily:'var(--dgd-font-mono,monospace)', background:'color-mix(in oklch,#f59e0b 10%,transparent)', padding:'2px 7px', borderRadius:4, border:'1px solid color-mix(in oklch,#f59e0b 35%,transparent)' }}>MOCK</span>}
            </h2>
            <span style={{ display:'flex', alignItems:'center', gap:0, border:'1px solid var(--dgd-border-1)', borderRadius:6, overflow:'hidden', flexShrink:0 }}>
              {[2025, 2026, 2027].map(a => (
                <button key={a} onClick={() => setSelAno(a)}
                  style={{ padding:'4px 10px', fontSize:11, fontFamily:'var(--dgd-font-mono,monospace)', border:'none', borderRight: a < 2027 ? '1px solid var(--dgd-border-1)' : 'none', cursor:'pointer', background: selAno===a ? 'var(--dgd-fg-1)' : 'transparent', color: selAno===a ? 'white' : 'var(--dgd-fg-2)', fontWeight: selAno===a ? 600 : 400 }}>
                  {a}
                </button>
              ))}
            </span>
          </div>
        </div>

        {/* KPIs — na tab SDR AI medem a actividade da Digi; nas outras, o funil humano */}
        <div style={{ display:'flex', gap:8, marginBottom:14, flexWrap:'wrap' }}>
          {(tab === 'sdr-ai' ? (aiKpis || [
            { l:'Taxa de Contacto', v:'—', d:'Obj. >= 70%', c:'var(--dgd-fg-3)' },
            { l:'Qualificação BANT', v:'—', d:'Obj. >= 40%', c:'var(--dgd-fg-3)' },
            { l:'Oportunidades Passadas', v:'—', d:'Digi AI', c:'var(--dgd-fg-3)' },
            { l:'Taxa qualif. comercial', v:'—', d:'Obj. >= 40%', c:'var(--dgd-fg-3)' },
            { l:'Pipeline Gerado', v:'—', d:'Digi AI', c:'var(--dgd-fg-3)' },
          ]) : kpis).map(k => <SdrKpiTile key={k.l} label={k.l} value={k.v} sub={k.d} color={k.c} />)}
        </div>

        {/* Sub-tabs — SDR puro não vê a barra (só tem um tab) */}
        {isAdmin && <div style={{ display:'flex', gap:2, marginBottom:16, borderBottom:'1px solid var(--dgd-border-1)', flexWrap:'wrap' }}>
          {SDR_TABS.map(t => (
            <button key={t.id} onClick={() => setTab(t.id)}
              style={{ padding:'7px 14px', fontSize:12, fontWeight:tab===t.id?700:400, color:tab===t.id?'var(--dgd-fg-1)':'var(--dgd-fg-3)', background:'none', border:'none', borderBottom:tab===t.id?'2px solid var(--dgd-fg-1)':'2px solid transparent', cursor:'pointer', marginBottom:-1, whiteSpace:'nowrap' }}>
              {t.label}
            </button>
          ))}
        </div>}

        {/* ── Tab: SDR AI ── (componente isolado — screen_comercial_rpc_sdr_ai.jsx) */}
        {tab === 'sdr-ai' && SdrAITabView && (
          <SdrAITabView selAno={selAno} sdrList={sdrList} />
        )}

        {/* ── Tab: SDR Humano ── */}
        {tab === 'sdr-humano' && (
          <>
            {isAdmin !== false && (
              <>
                <div style={{ display:'flex', alignItems:'center', gap:6, marginBottom:8, flexWrap:'wrap' }}>
                  <span style={{ fontSize:11, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', letterSpacing:'0.06em', marginRight:2 }}>EMPRESA</span>
                  {[{ id: null, label: 'Todos' }, { id: 'PT', label: 'Digidelta PT' }, { id: 'ES', label: 'Digidelta ES' }, { id: 'NS', label: 'Netscreen' }, { id: 'TAS', label: 'TAS' }].map(t => (
                    <button key={t.id ?? 'all'} onClick={() => handleSetTenant(t.id)} style={selTenant===t.id ? pillActive : pillInactive}>{t.label}</button>
                  ))}
                </div>
                <div style={{ display:'flex', alignItems:'center', gap:6, marginBottom:14, flexWrap:'wrap' }}>
                  <span style={{ fontSize:11, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', letterSpacing:'0.06em', marginRight:2 }}>VER COMO</span>
                  <button onClick={() => setSelSDR(null)} style={selSDR===null ? pillActive : pillInactive}>Todos</button>
                  {visibleSdrs.map(s => (
                    <button key={s.email} onClick={() => setSelSDR(s.email)} style={selSDR===s.email ? pillActive : pillInactive}>{s.nome}</button>
                  ))}
                </div>
              </>
            )}
            <div style={{ background:'var(--dgd-bg-card,white)', border:'1px solid var(--dgd-border-1)', borderRadius:8, overflow:'hidden' }}>
              <SdrFunilTable rows={funilRows} onCellClick={handleHumanoCellClick} />
            </div>
            {selSdrEmail && <div style={{ margin:'16px 0' }}><SdrCoachingCard email={selSdrEmail} dismissible={false} /></div>}
            <SdrDailyProspect user={user} sdrEmail={selSdrEmail} sdrEmailsStr={selSdrEmail ? null : visibleSdrs.map(s => s.email).join(',')} ano={selAno} tenant={selTenant} onLeadUpdated={refreshFunil} />
            <SdrProspectsCampanha user={user} sdrEmail={selSdrEmail} />
          </>
        )}

        {/* ── Tab: Por SDR ── */}
        {tab === 'por-sdr' && (
          <>
            <div style={{ background:'var(--dgd-bg-card,white)', border:'1px solid var(--dgd-border-1)', borderRadius:8, overflow:'hidden', marginBottom:12 }}>
              <div style={{ padding:'10px 14px 0', fontSize:10, color:'var(--dgd-fg-3)', fontFamily:'var(--dgd-font-mono,monospace)', letterSpacing:'0.08em' }}>
                {SDR_MESES[mesIdx]} {selAno} -- desempenho por SDR
              </div>
              <div style={{ overflowX:'auto' }}>
                <table style={{ borderCollapse:'collapse', width:'100%', fontSize:12 }}>
                  <thead>
                    <tr>
                      <th style={{ ...thL, minWidth:200 }}>SDR</th>
                      <th style={th}>Atribuidos</th>
                      <th style={th}>Contactados</th>
                      <th style={th}>Taxa Contacto</th>
                      <th style={th}>Qualificados</th>
                      <th style={th}>Taxa Qualif.</th>
                      <th style={th}>Agendadas</th>
                      <th style={th}>Pipeline</th>
                    </tr>
                  </thead>
                  <tbody>
                    {SDR_POR_SDR.map(r => {
                      const tc = sdrPct(r.contactados, r.atribuidos);
                      const tq = sdrPct(r.qualificados, r.contactados);
                      return (
                        <tr key={r.nome}>
                          <td style={{ ...tdL, fontWeight:600, color:r.isAI?'#4338ca':'var(--dgd-fg-1)' }}>{r.nome}</td>
                          <td style={tdBase}>{r.atribuidos}</td>
                          <td style={tdBase}>{r.contactados}</td>
                          <td style={{ ...tdBase, color:sdrColor(tc,SDR_METAS.taxa_contacto), background:sdrBg(tc,SDR_METAS.taxa_contacto) }}>{tc}%</td>
                          <td style={tdBase}>{r.qualificados}</td>
                          <td style={{ ...tdBase, color:sdrColor(tq,SDR_METAS.taxa_qualif), background:sdrBg(tq,SDR_METAS.taxa_qualif) }}>{tq}%</td>
                          <td style={tdBase}>{r.agendadas}</td>
                          <td style={{ ...tdBase, color:'#1d4ed8', fontWeight:600 }}>{r.pipeline_k}k</td>
                        </tr>
                      );
                    })}
                    <tr style={{ borderTop:'2px solid var(--dgd-border-1)' }}>
                      <td style={{ ...tdL, fontWeight:700 }}>Total</td>
                      <td style={{ ...tdBase, fontWeight:700, color:'var(--dgd-fg-1)' }}>{totalSDR.atribuidos}</td>
                      <td style={{ ...tdBase, fontWeight:700, color:'var(--dgd-fg-1)' }}>{totalSDR.contactados}</td>
                      <td style={{ ...tdBase, fontWeight:700, color:sdrColor(sdrPct(totalSDR.contactados,totalSDR.atribuidos),SDR_METAS.taxa_contacto) }}>{sdrPct(totalSDR.contactados,totalSDR.atribuidos)}%</td>
                      <td style={{ ...tdBase, fontWeight:700, color:'var(--dgd-fg-1)' }}>{totalSDR.qualificados}</td>
                      <td style={{ ...tdBase, fontWeight:700, color:sdrColor(sdrPct(totalSDR.qualificados,totalSDR.contactados),SDR_METAS.taxa_qualif) }}>{sdrPct(totalSDR.qualificados,totalSDR.contactados)}%</td>
                      <td style={{ ...tdBase, fontWeight:700, color:'var(--dgd-fg-1)' }}>{totalSDR.agendadas}</td>
                      <td style={{ ...tdBase, fontWeight:700, color:'#1d4ed8' }}>{totalSDR.pipeline_k}k</td>
                    </tr>
                  </tbody>
                </table>
              </div>
            </div>
            <div style={{ padding:'10px 14px', borderRadius:7, background:'color-mix(in oklch,#6366f1 6%,transparent)', border:'1px solid color-mix(in oklch,#6366f1 20%,transparent)', fontSize:12, color:'var(--dgd-fg-2)', lineHeight:1.6 }}>
              O SDR AI gera volume mas qualifica pouco sozinho (taxa baixa): o seu papel e filtrar e escalar os leads quentes para a Carina fechar o BANT -- daí a taxa de qualificacao dela rondar os 90%. E o padrao esperado.
            </div>
          </>
        )}

        {/* ── Tab: Qualificadas ── */}
        {tab === 'qualificadas' && <SdrQualificadasTab sdrEmailFilter={isAdmin ? (selSdrEmail || null) : user?.email} />}

        {/* ── Tab: Coach ── */}
        {tab === 'coach' && <SdrCoachTab />}

        {/* ── Tab: Definicoes ── */}
        {tab === 'definicoes' && (
          <>
            <div style={{ background:'var(--dgd-bg-card,white)', border:'1px solid var(--dgd-border-1)', borderRadius:8, overflow:'hidden', marginBottom:12 }}>
              <div style={{ overflowX:'auto' }}>
                <table style={{ borderCollapse:'collapse', width:'100%', fontSize:12 }}>
                  <thead>
                    <tr>
                      <th style={{ ...thL, minWidth:200 }}>KPI</th>
                      <th style={{ ...thL, minWidth:220, whiteSpace:'normal' }}>Formula</th>
                      <th style={{ ...th, minWidth:80 }}>Meta</th>
                      <th style={{ ...thL, minWidth:300, whiteSpace:'normal' }}>Fonte / Regra</th>
                    </tr>
                  </thead>
                  <tbody>
                    {SDR_DEFINICOES.map(row => (
                      <tr key={row.kpi}>
                        <td style={{ ...tdL, fontWeight:600, color:'var(--dgd-fg-1)', whiteSpace:'nowrap' }}>{row.kpi}</td>
                        <td style={{ ...tdL, whiteSpace:'normal', lineHeight:1.5 }}>{row.formula}</td>
                        <td style={{ ...tdBase, color:'#1d4ed8', fontWeight:600 }}>{row.meta}</td>
                        <td style={{ ...tdL, whiteSpace:'normal', lineHeight:1.5, color:'var(--dgd-fg-3)' }}>{row.regra}</td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            </div>
            <div style={{ padding:'10px 14px', borderRadius:7, background:'color-mix(in oklch,#ef4444 6%,transparent)', border:'1px solid color-mix(in oklch,#ef4444 20%,transparent)', fontSize:12, color:'var(--dgd-fg-2)', lineHeight:1.6 }}>
              <strong style={{ color:'#991b1b' }}>Regra de ouro:</strong> um lead só sai de "em qualificação" quando os 4 campos BANT estão preenchidos — sem isso, não conta para a taxa de qualificação nem pode ser agendado. O SDR AI nunca fecha o funil sozinho: todo o handoff para a equipa comercial passa por confirmação humana.
            </div>
          </>
        )}

      </div>

      {/* Modal leads */}
      {modal && <SdrLeadListModal title={modal.title} leads={modal.leads} onClose={() => setModal(null)} />}
    </div>
  );
};

window.ScreenComercialRpcSDR = ScreenComercialRpcSDR;
