/* Digi AI SP Marketing — dock global do Marketing.
   Uma conversa por utilizador em todos os módulos; o sub-agente muda com o ecrã.
   Só aparece quando /api/marketing/digi/sp/config diz activo para o utilizador.
   Nos ecrãs com chat próprio (config.ocultar_em) não se mostra. */
(function () {
  const API = '/api/marketing/digi/sp';
  const PISCAR_PAINEL_MS = 4000;
  const VERIFICAR_MS = 5 * 60 * 1000;

  const LABELS = {
    inicio: 'Início', objectivos: 'Objectivos', marcas: 'Marcas e Estratégia', estrategia: 'Marcas e Estratégia',
    'plano-comunicacao': 'Plano de Comunicação', briefings: 'Briefings', campanhas: 'Campanhas',
    conteudos: 'Produção de Conteúdos', producao: 'Produção de Conteúdos', publicacao: 'Activação', activacao: 'Activação',
    'open-houses': 'Open Houses', audiencias: 'Audiências', crm: 'Audiências',
    'leads-outbound': 'Outbound', 'leads-campanhas': 'Outbound', 'leads-inbound': 'Inbound', sdr: 'SDR AI', 'sdr-humano': 'SDR Suporte',
    resultados: 'Resultados', 'resultados-analise': 'Resultados', 'resultados-mimaki': 'Resultados', 'resultados-faturado': 'Resultados', 'performance-ads': 'Resultados', 'analise-campanhas': 'Análise de campanhas', budget: 'Budget', clipping: 'Clipping', seo: 'SEO', ligacoes: 'Ligações', 'chamada-teste': 'Chamada teste',
  };
  const QUICK = ['O que está pendente aqui?', 'Qual é o estado deste módulo?', 'Como uso este ecrã?'];
  const QUICK_SDR = ['Continua de onde ficámos', 'O essencial desta marca', 'Onde abro isto?'];

  function qs(email, extra) {
    const p = new URLSearchParams(window.location.search || '');
    const e = email || window.currentUser?.email || '';
    if (e && !p.get('email')) p.set('email', e);
    Object.entries(extra || {}).forEach(([k, v]) => { if (v != null && v !== '') p.set(k, v); });
    const s = p.toString();
    return s ? `?${s}` : '';
  }

  function hashParams() {
    try { return new URLSearchParams((window.location.hash || '').replace(/^#/, '')); } catch { return new URLSearchParams(); }
  }

  function marcaActual() {
    return hashParams().get('marca') || 'todas';
  }

  function ecraActual() {
    const h = hashParams();
    const out = {};
    ['lista', 'tab', 'vista', 'periodo', 'camp'].forEach(k => { const v = h.get(k); if (v) out[k] = v; });
    return out;
  }

  function nomeMarca(id) {
    if (!id || id === 'todas') return 'Todas';
    const b = (window.MKT_BRANDS || []).find(x => x.id === id);
    return b?.nome || id;
  }

  function irPara(link) {
    if (!link) return;
    if (link.hash) window.location.hash = link.hash;
    else if (link.sub && window.mktNavToSub) window.mktNavToSub(link.sub);
  }

  // Som curto gerado no browser; só toca depois de o utilizador ter interagido com a página.
  let interagiu = false;
  let audioCtx = null;
  ['pointerdown', 'keydown'].forEach(ev => window.addEventListener(ev, () => { interagiu = true; }, { once: true, capture: true }));
  function tocarSom() {
    if (!interagiu) return;
    try {
      audioCtx = audioCtx || new (window.AudioContext || window.webkitAudioContext)();
      const t0 = audioCtx.currentTime;
      [[880, 0], [1320, 0.12]].forEach(([freq, dt]) => {
        const o = audioCtx.createOscillator();
        const g = audioCtx.createGain();
        o.type = 'sine';
        o.frequency.value = freq;
        g.gain.setValueAtTime(0.0001, t0 + dt);
        g.gain.exponentialRampToValueAtTime(0.08, t0 + dt + 0.02);
        g.gain.exponentialRampToValueAtTime(0.0001, t0 + dt + 0.22);
        o.connect(g).connect(audioCtx.destination);
        o.start(t0 + dt);
        o.stop(t0 + dt + 0.25);
      });
    } catch {}
  }

  const IconeDigi = ({ size = 18, color = 'currentColor' }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth="1.8">
      <path d="M9.5 2A2.5 2.5 0 0 1 12 4.5v15a2.5 2.5 0 0 1-4.96-.46 2.5 2.5 0 0 1-2.96-3.08 3 3 0 0 1-.34-5.58 2.5 2.5 0 0 1 1.32-4.24 2.5 2.5 0 0 1 4.44-1.14Z"/>
      <path d="M14.5 2A2.5 2.5 0 0 0 12 4.5v15a2.5 2.5 0 0 0 4.96-.46 2.5 2.5 0 0 0 2.96-3.08 3 3 0 0 0 .34-5.58 2.5 2.5 0 0 0-1.32-4.24 2.5 2.5 0 0 0-4.44-1.14Z"/>
    </svg>
  );

  function partirTutor(texto) {
    const s = String(texto || '');
    const marca = s.search(/\n\s*OPCOES:\s*/i);
    const limparLinha = (l) => l.replace(/^[-*•\d.)\s]+/, '').trim();
    if (marca < 0) {
      const parcial = s.search(/\n\s*OPC(?:O|OE|OES?)?:?\s*$/i);
      return { texto: (parcial >= 0 ? s.slice(0, parcial) : s).replace(/\s+$/, ''), opcoes: [] };
    }
    const opcoes = s.slice(marca).replace(/^[\s\S]*?OPCOES:\s*/i, '').split('\n')
      .map(limparLinha)
      .filter(l => l && l.length < 80 && !/^opcoes:?$/i.test(l))
      .slice(0, 3);
    return { texto: s.slice(0, marca).trim(), opcoes };
  }

  function textoTutor(m) {
    if (Array.isArray(m.opcoes) && m.opcoes.length) return m.content;
    return partirTutor(m.content).texto || m.content;
  }

  function opcoesTutor(m) {
    if (Array.isArray(m.opcoes) && m.opcoes.length) return m.opcoes.slice(0, 3);
    return partirTutor(m.content).opcoes;
  }

  const semMarkdown = (t) => String(t || '')
    .replace(/\*\*(.+?)\*\*/g, '$1')
    .replace(/(^|\n)#{1,6}\s+/g, '$1')
    .replace(/(^|\n)[*-]\s+/g, '$1');

  const corPrioridade = (p) => p === 'p0' ? 'var(--danger, #dc2626)' : p === 'p1' ? 'var(--warning, #d97706)' : 'var(--text-muted)';

  const Pendente = ({ p }) => (
    <button onClick={() => irPara(p.link)} title="Abrir no ecrã" style={{
      display: 'flex', alignItems: 'flex-start', gap: 8, width: '100%', textAlign: 'left', padding: '7px 10px', marginTop: 6,
      borderRadius: 8, border: '1px solid var(--border)', background: 'var(--bg)', color: 'var(--text)', cursor: 'pointer', fontSize: 12, lineHeight: 1.4,
    }}>
      <span style={{ width: 7, height: 7, borderRadius: '50%', background: corPrioridade(p.prioridade), marginTop: 5, flexShrink: 0 }} />
      <span style={{ flex: 1 }}>{p.titulo}</span>
    </button>
  );

  const Mensagem = ({ m, mostrarCabecalho, labelAgente, rotulo }) => {
    const user = m.role === 'user';
    return (
      <div style={{ display: 'flex', flexDirection: 'column', alignItems: user ? 'flex-end' : 'flex-start', marginBottom: 10, animation: 'mkt-digi-dock-msg-in .2s ease-out' }}>
        {!user && mostrarCabecalho && (
          <div style={{ fontSize: 10, fontFamily: 'var(--font-mono)', color: 'var(--text-dim)', marginBottom: 4, letterSpacing: '.04em' }}>
            {rotulo || `Digi AI${labelAgente ? ` · ${labelAgente}` : ''}`}
          </div>
        )}
        <div style={{
          maxWidth: '88%', padding: '9px 12px', borderRadius: user ? '12px 12px 4px 12px' : '12px 12px 12px 4px',
          background: user ? 'var(--ai-500)' : (m.tipo === 'aviso' ? 'color-mix(in oklch, var(--warning, #d97706) 10%, var(--bg))' : 'var(--bg)'),
          color: user ? 'var(--text-on-ai, #fff)' : 'var(--text)',
          border: user ? 'none' : `1px solid ${m.tipo === 'aviso' ? 'color-mix(in oklch, var(--warning, #d97706) 40%, transparent)' : 'var(--border)'}`,
          fontSize: 12.5, lineHeight: 1.55, whiteSpace: 'pre-wrap', wordBreak: 'break-word',
        }}>
          {user ? m.content : semMarkdown(m.content)}
          {Array.isArray(m.pendentes) && m.pendentes.map((p, i) => <Pendente key={i} p={p} />)}
        </div>
      </div>
    );
  };

  const MktDigiDockInner = ({ sub, userName, userEmail }) => {
    const [cfg, setCfg] = React.useState(null);
    const [open, setOpen] = React.useState(false);
    const [expanded, setExpanded] = React.useState(false);
    const [msgs, setMsgs] = React.useState([]);
    const [pendentes, setPendentes] = React.useState([]);
    const [inp, setInp] = React.useState('');
    const [loading, setLoading] = React.useState(false);
    const [piscar, setPiscar] = React.useState(false);
    const [agenteResp, setAgenteResp] = React.useState(null);
    const [hashTick, setHashTick] = React.useState(0);
    const [campsSdr, setCampsSdr] = React.useState([]);
    const [modo, setModo] = React.useState('video');
    const [retrato, setRetrato] = React.useState(true);
    const [aSair, setASair] = React.useState(false);
    const [videosMod, setVideosMod] = React.useState({});
    const [aTocar, setATocar] = React.useState(false);
    const [avisoIntro, setAvisoIntro] = React.useState('');
    const bodyRef = React.useRef(null);
    const panelRef = React.useRef(null);
    const fabRef = React.useRef(null);
    const videoRef = React.useRef(null);
    const retratoRef = React.useRef(null);
    const email = userEmail || window.currentUser?.email || '';

    React.useEffect(() => {
      let cancel = false;
      fetch(`${API}/config${qs(email)}`)
        .then(r => r.ok ? r.json() : null)
        .then(d => { if (!cancel) setCfg(d || { activo: false }); })
        .catch(() => { if (!cancel) setCfg({ activo: false }); });
      return () => { cancel = true; };
    }, [email]);

    const activo = !!cfg?.activo;
    const oculto = !activo || (cfg.ocultar_em || []).includes(sub);
    const sdr = sub === 'sdr-humano';
    const chatAberto = open;
    const introId = (() => {
      void hashTick;
      const h = hashParams();
      const licao = h.get('licao');
      if (licao) return licao;
      const inicial = h.get('inicial');
      if (inicial) return inicial;
      const marca = h.get('marca');
      if (marca && marca !== 'todas') return marca;
      return 'papel';
    })();
    const urlIntro = videosMod[introId] || '';

    React.useEffect(() => {
      if (!sdr) return;
      let cancel = false;
      fetch(`/api/marketing/sdr-humano/modulos${qs(email)}`)
        .then(r => r.ok ? r.json() : null)
        .then(d => {
          if (cancel) return;
          const map = {};
          (d?.modulos || []).forEach(m => { if (m.video) map[m.id] = m.video; });
          setVideosMod(map);
        })
        .catch(() => {});
      return () => { cancel = true; };
    }, [sdr, email]);

    React.useEffect(() => {
      setATocar(false);
      setAvisoIntro('');
    }, [urlIntro]);

    React.useEffect(() => {
      const fn = () => setHashTick(t => t + 1);
      window.addEventListener('hashchange', fn);
      return () => window.removeEventListener('hashchange', fn);
    }, []);

    React.useEffect(() => {
      if (!activo) return;
      let cancel = false;
      setAgenteResp(null);
      fetch(`${API}/sessao${qs(email, sdr ? { escopo: 'sdr-humano' } : {})}`)
        .then(r => r.ok ? r.json() : null)
        .then(d => { if (!cancel) setMsgs(d?.messages || []); })
        .catch(() => {});
      return () => { cancel = true; };
    }, [activo, email, sdr]);

    React.useEffect(() => {
      if (!sdr) return;
      let cancel = false;
      fetch(`/api/marketing/sdr-humano/campanhas${qs(email)}`)
        .then(r => r.ok ? r.json() : null)
        .then(d => { if (!cancel) setCampsSdr(d?.rows || []); })
        .catch(() => {});
      return () => { cancel = true; };
    }, [sdr, email]);

    React.useEffect(() => {
      if (oculto || sdr) return;
      let cancel = false;
      const verificar = async () => {
        const marca = marcaActual();
        try {
          const r = await fetch(`${API}/pendentes${qs(email, { modulo: sub, marca })}`);
          if (!r.ok || cancel) return;
          const d = await r.json();
          if (cancel) return;
          setPendentes(d.pendentes || []);
          if (!(d.novos || []).length) return;
          const a = await fetch(`${API}/pendentes/avisado${qs(email)}`, {
            method: 'POST', headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ modulo: sub, marca, hashes: d.novos }),
          });
          const av = a.ok ? await a.json() : null;
          if (cancel || !av?.mensagem) return;
          setMsgs(m => [...m, av.mensagem]);
          if (cfg.som !== false) tocarSom();
          setPiscar(true);
        } catch {}
      };
      verificar();
      const t = setInterval(verificar, VERIFICAR_MS);
      return () => { cancel = true; clearInterval(t); };
    }, [sub, oculto, email]);

    React.useEffect(() => {
      if (!piscar || !chatAberto) return;
      const t = setTimeout(() => setPiscar(false), PISCAR_PAINEL_MS);
      return () => clearTimeout(t);
    }, [piscar, chatAberto]);

    React.useEffect(() => {
      if (chatAberto && bodyRef.current) bodyRef.current.scrollTop = bodyRef.current.scrollHeight;
    }, [msgs, chatAberto, loading]);

    React.useEffect(() => {
      if (!chatAberto) return;
      const fecharChat = () => setOpen(false);
      const onKey = (e) => { if (e.key === 'Escape') { if (expanded) setExpanded(false); else fecharChat(); } };
      const onClick = (e) => {
        if (expanded) return;
        const noPainel = panelRef.current && !panelRef.current.contains(e.target);
        const noFab = !fabRef.current || !fabRef.current.contains(e.target);
        if (noPainel && noFab) fecharChat();
      };
      document.addEventListener('keydown', onKey);
      document.addEventListener('mousedown', onClick);
      return () => { document.removeEventListener('keydown', onKey); document.removeEventListener('mousedown', onClick); };
    }, [chatAberto, expanded, sdr]);

    React.useEffect(() => {
      if (sdr) setOpen(true);
    }, [sdr]);

    const enviar = async (texto) => {
      const t = String(texto ?? inp).trim();
      if (!t || loading) return;
      const marca = marcaActual();
      const ts = new Date().toISOString();
      const campEnvio = ecraActual().camp || '';
      setMsgs(m => [...m, { role: 'user', content: t, ts, modulo: sub, marca, camp: campEnvio }, { role: 'assistant', content: '', ts, modulo: sub, marca, camp: campEnvio, _stream: true }]);
      setInp('');
      setLoading(true);
      const actualizar = (fn) => setMsgs(m => {
        const i = m.length - 1;
        if (i < 0 || !m[i]._stream) return m;
        const c = m.slice();
        c[i] = fn(c[i]);
        return c;
      });
      try {
        const resp = await fetch(`${API}/chat${qs(email)}`, {
          method: 'POST', headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ message: t, canal: 'portal', modulo: sub, marca, ecra: ecraActual() }),
        });
        if (!resp.ok || !resp.body) throw new Error(`HTTP ${resp.status}`);
        const reader = resp.body.getReader();
        const decoder = new TextDecoder();
        let buf = '';
        for (;;) {
          const { done, value } = await reader.read();
          if (done) break;
          buf += decoder.decode(value, { stream: true });
          const linhas = buf.split('\n');
          buf = linhas.pop() || '';
          for (const l of linhas) {
            if (!l.startsWith('data: ')) continue;
            let ev;
            try { ev = JSON.parse(l.slice(6)); } catch { continue; }
            if (ev.type === 'agente') { setAgenteResp(ev.label); actualizar(x => ({ ...x, agente: ev.agente, agenteLabel: ev.label })); }
            else if (ev.type === 'delta') actualizar(x => ({ ...x, content: x.content + ev.text }));
            else if (ev.type === 'error') actualizar(x => ({ ...x, content: x.content || `Erro: ${ev.message}` }));
          }
        }
      } catch {
        actualizar(x => ({ ...x, content: x.content || 'Sem ligação ao servidor.' }));
      } finally {
        actualizar(x => { const { _stream, ...rest } = x; return rest; });
        setLoading(false);
      }
    };

    if (oculto) return null;

    const label = LABELS[sub] || 'Marketing';
    const labelDeAgente = (id) => (cfg.agentes || []).find(a => a.id === id)?.label || '';
    const nPend = sdr ? 0 : pendentes.length;
    const primeiroNome = String(userName || '').split(' ')[0];
    const marcaAgora = hashTick >= 0 ? marcaActual() : 'todas';
    const campAgora = ecraActual().camp || '';
    const campAberta = campsSdr.find(c => String(c.campanha?.id) === String(campAgora));
    const visiveis = msgs.filter(m => {
      if (!sdr) return m.modulo !== 'sdr-humano';
      return m.modulo === 'sdr-humano' || m._stream;
    });
    const ultimaTutor = sdr ? [...visiveis].reverse().find(m => m.role !== 'user' && (m.content || (m.opcoes || []).length)) : null;
    const opcoesUltima = ultimaTutor ? opcoesTutor(ultimaTutor) : [];
    const atalhos = opcoesUltima.length ? opcoesUltima : (sdr ? QUICK_SDR : QUICK);
    const nome = nomeMarca(marcaAgora);
    const subtituloSdr = campAberta?.campanha?.titulo || 'Briefings das campanhas no ar';

    const cabecalho = (
      <div style={{ padding: expanded ? '14px 20px 12px' : '12px 16px 10px', borderBottom: '1px solid var(--border)', background: 'var(--bg-elev)', flexShrink: 0, display: 'flex', alignItems: 'center', gap: 10 }}>
        <div style={{ width: 32, height: 32, borderRadius: 10, background: 'var(--ai-500)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
          <IconeDigi size={16} color="var(--text-on-ai, #fff)" />
        </div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--text)', display: 'flex', alignItems: 'center', gap: 6 }}>
            {sdr ? 'Digi AI SDR Suporte' : 'Digi AI'}
            <span style={{ fontSize: 9, fontWeight: 700, fontFamily: 'var(--font-mono)', padding: '2px 7px', borderRadius: 4, background: 'color-mix(in oklch, var(--ai-500) 14%, transparent)', color: 'var(--ai-500)', letterSpacing: '.08em', textTransform: 'uppercase' }}>{sdr ? (marcaAgora === 'todas' ? 'Curso' : nome) : label}</span>
          </div>
          <div style={{ fontSize: 10, color: 'var(--text-muted)', fontFamily: 'var(--font-mono)', marginTop: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
            {sdr ? subtituloSdr : `SP Marketing${agenteResp && agenteResp !== label ? ` · última resposta: ${agenteResp}` : ''}`}
          </div>
        </div>
        <button title={expanded ? 'Reduzir' : 'Expandir'} onClick={() => setExpanded(e => !e)} style={{ width: 28, height: 28, borderRadius: 6, border: '1px solid var(--border)', background: 'transparent', color: 'var(--text-dim)', cursor: 'pointer' }}>
          {expanded ? '–' : '⤢'}
        </button>
        <button title="Fechar" onClick={() => { setOpen(false); setExpanded(false); }} style={{ width: 28, height: 28, borderRadius: 6, border: '1px solid var(--border)', background: 'transparent', color: 'var(--text-dim)', cursor: 'pointer' }}>×</button>
      </div>
    );

    const corpo = (
      <>
        <div ref={bodyRef} className="scrollbar" style={{ flex: 1, overflowY: 'auto', padding: expanded ? '18px 20px 8px' : '14px 14px 6px', minHeight: 0 }}>
          {!sdr && nPend > 0 && (
            <div style={{ marginBottom: 12, padding: '8px 10px', borderRadius: 10, border: '1px solid var(--border)', background: 'var(--bg-elev)' }}>
              <div style={{ fontSize: 10, fontWeight: 700, fontFamily: 'var(--font-mono)', color: 'var(--text-dim)', textTransform: 'uppercase', letterSpacing: '.06em' }}>
                {nPend} pendente{nPend === 1 ? '' : 's'} em {label}
              </div>
              {pendentes.map(p => <Pendente key={p.hash} p={p} />)}
            </div>
          )}
          {visiveis.length === 0 && (
            <div style={{ fontSize: 12.5, color: 'var(--text-muted)', lineHeight: 1.55 }}>
              {sdr
                ? ('Sou a Digi AI SDR Suporte. Diz-me a chamada, o lead ou a campanha no ar em que estás' + (marcaAgora === 'todas' ? '.' : '. ' + nome + ' está em primeiro plano.'))
                : ((primeiroNome ? 'Olá ' + primeiroNome + '. ' : 'Olá. ') + 'Estou contigo em todos os módulos do Marketing. Pergunta-me o que está pendente, o estado de ' + label + ' ou como usar este ecrã.')}
            </div>
          )}
          {visiveis.map((m, i) => (
            <Mensagem key={`${m.ts}-${i}`} m={sdr && m.role !== 'user' ? { ...m, content: textoTutor(m) } : m}
              mostrarCabecalho={m.role !== 'user' && (i === 0 || visiveis[i - 1].role === 'user' || visiveis[i - 1].agente !== m.agente)}
              rotulo={sdr ? 'Digi AI SDR Suporte' : ''}
              labelAgente={sdr ? '' : (m.agenteLabel || labelDeAgente(m.agente) || LABELS[m.modulo] || '')} />
          ))}
          {loading && visiveis[visiveis.length - 1]?.content === '' && (
            <div style={{ display: 'flex', gap: 4, margin: '-4px 0 10px 4px' }}>
              {[0, 1, 2].map(i => <div key={i} style={{ width: 6, height: 6, borderRadius: '50%', background: 'var(--ai-500)', opacity: 0.5, animation: `mkt-digi-dock-dot ${0.7 + i * 0.18}s ease-in-out infinite alternate` }} />)}
            </div>
          )}
        </div>
        <div style={{ padding: expanded ? '6px 20px 0' : '6px 14px 0', display: 'flex', flexDirection: sdr ? 'column' : 'row', gap: 5, flexWrap: sdr ? 'nowrap' : 'wrap', alignItems: sdr ? 'stretch' : 'center', flexShrink: 0 }}>
          {atalhos.map(q => (
            <button key={q} onClick={() => enviar(q)} disabled={loading} style={{ fontSize: 11, padding: '6px 10px', borderRadius: sdr ? 10 : 999, border: '1px solid var(--border)', background: 'var(--bg-elev)', color: 'var(--text-muted)', cursor: loading ? 'default' : 'pointer', textAlign: 'left', lineHeight: 1.35, width: sdr ? '100%' : undefined }}>{q}</button>
          ))}
        </div>
        <div style={{ padding: expanded ? '8px 20px 16px' : '8px 14px 14px', display: 'flex', gap: 8, alignItems: 'flex-end', flexShrink: 0 }}>
          <textarea value={inp} onChange={e => setInp(e.target.value)} rows={2}
            onKeyDown={e => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); enviar(); } }}
            placeholder={sdr ? 'Pergunta o que precisares' : `Pergunta sobre ${label}... (Enter envia)`}
            style={{ flex: 1, resize: 'none', padding: '8px 12px', borderRadius: 10, border: '1px solid var(--border)', background: 'var(--bg)', color: 'var(--text)', fontSize: 12, fontFamily: 'var(--font-body)', lineHeight: 1.5, outline: 'none' }} />
          <button onClick={() => enviar()} disabled={!inp.trim() || loading} style={{
            width: 38, height: 38, borderRadius: 10, border: 'none', cursor: inp.trim() && !loading ? 'pointer' : 'default',
            background: inp.trim() && !loading ? 'var(--ai-500)' : 'var(--bg-sunken)', color: inp.trim() && !loading ? 'var(--text-on-ai, #fff)' : 'var(--text-dim)',
            display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
          }}>
            <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="m22 2-7 20-4-9-9-4 20-7z"/></svg>
          </button>
        </div>
      </>
    );

    return (
      <>
        {!expanded && (!sdr || !open) && (
          <div ref={fabRef} style={{ position: 'fixed', bottom: 28, right: 28, zIndex: 200 }}>
            {nPend > 0 && !open && (
              <div style={{ position: 'absolute', top: -5, right: -5, zIndex: 201, minWidth: 19, height: 19, padding: '0 4px', borderRadius: 10, background: 'var(--warning, #d97706)', color: '#fff', border: '2px solid var(--bg)', fontSize: 10, fontWeight: 700, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                {nPend > 9 ? '9+' : nPend}
              </div>
            )}
            <button onClick={() => { setOpen(o => sdr ? true : !o); setPiscar(false); }} title={sdr ? 'Digi AI SDR Suporte' : `Digi AI · ${label}`}
              className={piscar && !open ? 'mkt-digi-dock-piscar' : ''}
              style={{
                width: 52, height: 52, borderRadius: '50%', border: 'none', cursor: 'pointer',
                background: open ? 'var(--brand-900)' : 'var(--ai-500)', color: 'var(--text-on-ai, #fff)',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                boxShadow: '0 4px 18px color-mix(in oklch, var(--ai-500) 38%, transparent)',
              }}>
              {open ? <span style={{ fontSize: 20, lineHeight: 1 }}>×</span> : <IconeDigi size={21} />}
            </button>
          </div>
        )}
        {chatAberto && !expanded && (
          <div ref={panelRef} className={piscar ? 'mkt-digi-dock-piscar-painel' : ''} style={{
            position: 'fixed', bottom: sdr ? 28 : 92, right: 28, width: 420, height: 620, maxHeight: 'calc(100vh - 120px)', zIndex: 199,
            background: 'var(--bg-elev)', border: '1px solid var(--border)', borderRadius: 16,
            boxShadow: '0 20px 60px color-mix(in oklch, var(--ai-500) 14%, transparent)',
            display: 'flex', flexDirection: 'column', overflow: 'hidden', animation: 'mkt-digi-dock-in .22s ease-out',
          }}>
            {cabecalho}
            {corpo}
          </div>
        )}
        {chatAberto && expanded && ReactDOM.createPortal(
          <>
            <div onClick={() => setExpanded(false)} style={{ position: 'fixed', inset: 0, background: 'color-mix(in oklch, var(--text) 54%, transparent)', zIndex: 298 }} />
            <div style={{
              position: 'fixed', top: '50%', left: '50%', transform: 'translate(-50%,-50%)', width: 'min(1040px, 92vw)', height: '82vh', zIndex: 299,
              background: 'var(--bg-elev)', border: '1px solid var(--border)', borderRadius: 18, boxShadow: 'var(--shadow-lg)',
              display: 'flex', flexDirection: 'column', overflow: 'hidden',
            }}>
              {cabecalho}
              {corpo}
            </div>
          </>,
          document.body
        )}
        <style>{`
          @keyframes mkt-digi-dock-in { from { opacity:0; transform:translateY(12px) scale(.96); } to { opacity:1; transform:none; } }
          @keyframes mkt-digi-dock-msg-in { from { opacity:0; transform:translateY(6px); } to { opacity:1; transform:none; } }
          @keyframes mkt-digi-dock-dot { from { opacity:.3; transform:translateY(0); } to { opacity:1; transform:translateY(-3px); } }
          @keyframes mkt-digi-dock-piscar {
            0%, 100% { box-shadow: 0 0 0 0 color-mix(in oklch, var(--warning, #d97706) 70%, transparent); transform: scale(1); }
            50% { box-shadow: 0 0 0 12px color-mix(in oklch, var(--warning, #d97706) 0%, transparent); transform: scale(1.08); }
          }
          .mkt-digi-dock-piscar { animation: mkt-digi-dock-piscar 1s ease-in-out infinite; }
          @keyframes mkt-digi-dock-piscar-painel { 0%, 100% { border-color: var(--border); } 50% { border-color: var(--warning, #d97706); } }
          .mkt-digi-dock-piscar-painel { animation: mkt-digi-dock-piscar-painel .8s ease-in-out 5; }
          .mkt-tutor-video{position:fixed;right:28px;bottom:0;z-index:180;width:min(336px,calc((100vh - 72px) * 9 / 16));aspect-ratio:9/16;background:#fff;border:1px solid var(--border);border-bottom:none;border-radius:22px 22px 0 0;overflow:hidden;box-shadow:0 12px 36px rgba(17,41,84,.1);display:flex;align-items:flex-end;justify-content:center;transform:translateY(110%);animation:mkt-tutor-in .4s ease-out forwards}
          .mkt-tutor-video.mkt-tutor-sai{animation:mkt-tutor-out .35s ease-in forwards}
          @keyframes mkt-tutor-in{from{transform:translateY(110%)}to{transform:translateY(0)}}
          @keyframes mkt-tutor-out{from{transform:translateY(0)}to{transform:translateY(110%)}}
          .mkt-tutor-video video{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;background:#fff}
          .mkt-tutor-vazio{position:absolute;inset:0;display:flex;align-items:flex-end;justify-content:center;padding-bottom:92px;background:#fff}
          .mkt-tutor-aviso{position:absolute;left:16px;right:16px;bottom:78px;padding:8px 10px;border-radius:8px;background:#fff;border:1px solid var(--border);color:var(--text-muted);font-size:12px;line-height:1.4;text-align:center}
          .mkt-tutor-accao{position:absolute;left:14px;right:14px;bottom:16px;display:flex;gap:8px}
          .mkt-tutor-play,.mkt-tutor-msg{flex:1;height:40px;border-radius:999px;border:1px solid var(--border);background:#fff;color:var(--text);font-size:13px;font-weight:650;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:6px}
          .mkt-tutor-play{background:var(--ai-500);border-color:transparent;color:#fff}
          .mkt-tutor-fechar{position:absolute;top:12px;right:12px;z-index:2;width:32px;height:32px;border-radius:50%;border:1px solid var(--border);background:#fff;color:var(--text);font-size:18px;line-height:1;cursor:pointer;opacity:0;transition:opacity .15s}
          .mkt-tutor-video:hover .mkt-tutor-fechar{opacity:1}
        `}</style>
      </>
    );
  };

  class MktDigiDockBoundary extends React.Component {
    constructor(props) { super(props); this.state = { erro: false }; }
    static getDerivedStateFromError() { return { erro: true }; }
    componentDidCatch(error) { console.error('[MktDigiDock]', error); }
    render() { return this.state.erro ? null : this.props.children; }
  }

  window.MktDigiDock = (props) => (
    <MktDigiDockBoundary>
      <MktDigiDockInner {...props} />
    </MktDigiDockBoundary>
  );
})();
