// Tela: Jornadas do Cliente — kanban de fluxo

const { useState: useJornState, useRef: useJornRef, useEffect: useJornEffect } = React;

const CHAT_MSGS = [
  { id: 1, from: 'them', text: 'Olá! Queria saber mais sobre os serviços de vocês.', time: '09:14' },
  { id: 2, from: 'me', ai: true, text: 'Oi! Que ótimo falar com você 😊 Me conta — qual é o principal desafio que você quer resolver agora?', time: '09:15' },
  { id: 3, from: 'them', text: 'Preciso melhorar meu processo comercial, tá bem desorganizado.', time: '09:17' },
  { id: 4, from: 'me', ai: true, text: 'Entendo! Você já usa alguma ferramenta hoje, ou está tudo em planilha?', time: '09:18' },
  { id: 5, from: 'them', text: 'Só planilha mesmo, já não aguento mais 😅', time: '09:19' },
  { id: 6, from: 'me', ai: true, text: 'Haha, a planilha sempre chega no limite! 📊 Tenho uma solução que encaixa certinho. Posso agendar uma demo rápida com nosso especialista esta semana?', time: '09:21' },
  { id: 7, from: 'them', text: 'Pode ser! Prefiro quinta ou sexta pela manhã.', time: '09:23' },
];

const AI_REPLIES = [
  'Perfeito! Vou confirmar a disponibilidade do nosso especialista e já te retorno com o link de agendamento. 📅',
  'Ótimo! Enquanto isso, posso te enviar um material rápido sobre como empresas do seu segmento usam nossa solução?',
  'Entendido! Para personalizar a demo, qual é o tamanho da sua equipe comercial hoje?',
  'Que legal! Com esse perfil você vai ver resultado muito rápido. Animada para a demo? 🚀',
];

// Atendentes do fluxo com contagem de casos ativos
const ATENDENTES_FLUXO = [
  { nome: 'Ana Beatriz',  casos: 4, avatarIdx: 0 },
  { nome: 'Bruno Souza',  casos: 2, avatarIdx: 1 },
  { nome: 'Camila Lima',  casos: 3, avatarIdx: 2 },
  { nome: 'Diego Rocha',  casos: 1, avatarIdx: 3 },
  { nome: 'Eva Pinto',    casos: 4, avatarIdx: 4 },
  { nome: 'Felipe Couto', casos: 2, avatarIdx: 5 },
  { nome: 'Gabriela Sá',  casos: 3, avatarIdx: 6 },
];

function ConversaDrawer({ contato, onClose }) {
  const [msg, setMsg] = useJornState('');
  const [msgs, setMsgs] = useJornState(CHAT_MSGS);
  const [isAi, setIsAi] = useJornState(true);
  const [aiTyping, setAiTyping] = useJornState(false);
  const [sending, setSending] = useJornState(false);
  const [analise, setAnalise] = useJornState(null);
  const [analisando, setAnalisando] = useJornState(false);
  const [showAnalise, setShowAnalise] = useJornState(false);
  const endRef = useJornRef(null);
  const fileRef = useJornRef(null);
  const aiReplyIdx = useJornRef(0);
  const toast = useToast();

  const analisarConversa = async () => {
    setAnalisando(true);
    setShowAnalise(true);
    try {
      const historico = msgs.filter(m => m.text).map(m => ({ from: m.from, text: m.text }));
      const res = await fetch('/api/ai/analise-conversa', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ contato, historico }),
      });
      const data = await res.json();
      if (res.ok && data.ok) setAnalise(data);
      else toast('Erro na análise: ' + (data.error || 'tente novamente'));
    } catch {
      toast('⚠️ Proxy offline — análise indisponível');
    } finally {
      setAnalisando(false);
    }
  };

  const handleFile = (e) => {
    const file = e.target.files?.[0];
    if (!file) return;
    const kb = (file.size / 1024).toFixed(0);
    const mb = file.size > 1024 * 1024 ? (file.size / (1024 * 1024)).toFixed(1) + ' MB' : kb + ' KB';
    const isImg = file.type.startsWith('image/');
    if (isImg) {
      const url = URL.createObjectURL(file);
      setMsgs(prev => [...prev, { id: Date.now(), from: 'me', ai: false, type: 'img', url, name: file.name, size: mb, time: now() }]);
    } else {
      setMsgs(prev => [...prev, { id: Date.now(), from: 'me', ai: false, type: 'file', name: file.name, size: mb, time: now() }]);
    }
    toast('📎 Arquivo anexado — envio de mídia via API em breve');
    e.target.value = '';
  };

  const now = () => new Date().toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit' });

  // Converte "(21) 98821-4490" ou "+55 21 9 8821-4490" → "5521988214490"
  const toE164 = (raw = '') => {
    const digits = (raw || '').replace(/\D/g, '');
    return digits.startsWith('55') ? digits : '55' + digits;
  };

  const triggerAiReply = async (currentMsgs) => {
    setAiTyping(true);
    try {
      const historico = (currentMsgs || msgs).filter(m => m.text).map(m => ({ from: m.from, text: m.text }));
      const res = await fetch('/api/ai/sdr-reply', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ contato, historico }),
      });
      const data = await res.json();
      const text = (res.ok && data.reply) ? data.reply : AI_REPLIES[aiReplyIdx.current % AI_REPLIES.length];
      aiReplyIdx.current += 1;
      setAiTyping(false);
      setMsgs(prev => [...prev, { id: Date.now(), from: 'me', ai: true, text, time: now() }]);
    } catch {
      // fallback para resposta estática se proxy offline
      const text = AI_REPLIES[aiReplyIdx.current % AI_REPLIES.length];
      aiReplyIdx.current += 1;
      setAiTyping(false);
      setMsgs(prev => [...prev, { id: Date.now(), from: 'me', ai: true, text, time: now() }]);
    }
  };

  const send = async () => {
    if (!msg.trim() || sending) return;
    const text = msg.trim();
    // Adiciona na UI imediatamente (optimistic)
    setMsgs(prev => [...prev, { id: Date.now(), from: 'me', ai: false, text, time: now() }]);
    setMsg('');

    // Tenta enviar via WhatsApp real
    const phone = toE164(contato?.whatsapp || contato?.fone || '');
    if (phone.length >= 12) {
      setSending(true);
      try {
        const res = await fetch('/api/whatsapp/send', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ to: phone, message: text }),
        });
        const data = await res.json();
        if (res.ok && data.ok) {
          toast('✅ Mensagem enviada via WhatsApp');
        } else {
          toast('⚠️ Mensagem salva localmente — ' + (data.error || 'erro no envio'));
        }
      } catch {
        toast('⚠️ Proxy offline — mensagem salva localmente');
      } finally {
        setSending(false);
      }
    }
  };

  const simulateLead = () => {
    const leadMsgs = ['Tudo bem! Quando seria a demo?', 'Quantos usuários posso ter no plano inicial?', 'Tem integração com WhatsApp?', 'Qual é o valor mensal?'];
    const text = leadMsgs[Math.floor(Math.random() * leadMsgs.length)];
    const newMsg = { id: Date.now(), from: 'them', text, time: now() };
    setMsgs(prev => {
      const updated = [...prev, newMsg];
      if (isAi) triggerAiReply(updated);
      return updated;
    });
  };

  const onKey = (e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); send(); } };

  useJornEffect(() => { endRef.current?.scrollIntoView({ behavior: 'smooth' }); }, [msgs, aiTyping]);

  const WaIcon = () => (
    <svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor">
      <path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z"/>
    </svg>
  );

  const BoltIcon = () => (
    <svg width="11" height="11" viewBox="0 0 24 24" fill="currentColor"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg>
  );

  return (
    <>
      <div className="conv-backdrop" onClick={onClose} />
      <div className="conv-drawer">

        {/* ── cabeçalho ── */}
        <div className="conv-head">
          <img className="conv-head-av" src={contato.avatar} alt="" />
          <div className="conv-head-info">
            <div className="conv-head-name">{contato.nome}</div>
            <div className="conv-head-status">online agora</div>
          </div>
          <div className="conv-wa-badge"><WaIcon /> WhatsApp</div>
          <button className="conv-analise-btn" title="Analisar conversa com Gemini" onClick={analisarConversa}>
            <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><circle cx="11" cy="11" r="8"/><path d="M21 21l-4.35-4.35"/><path d="M11 8v6M8 11h6"/></svg>
            Analisar
          </button>
          <button className="conv-close" onClick={onClose}>{ICN.x}</button>
        </div>

        {/* ── painel análise Gemini ── */}
        {showAnalise && (
          <div className="conv-analise-panel">
            <div className="conv-analise-header">
              <span>✦ Análise Gemini</span>
              <button onClick={() => setShowAnalise(false)} style={{background:'none',border:'none',cursor:'pointer',color:'inherit',padding:0,lineHeight:1,fontSize:14}}>✕</button>
            </div>
            {analisando ? (
              <div style={{display:'flex',alignItems:'center',gap:8,padding:'10px 0',color:'var(--ink-muted)',fontSize:12}}>
                <span className="conv-ia-dots"><span/><span/><span/></span> Analisando conversa…
              </div>
            ) : analise ? (
              <div style={{display:'flex',flexDirection:'column',gap:8}}>
                <div style={{display:'grid',gridTemplateColumns:'1fr 1fr 1fr',gap:6}}>
                  {[
                    { label:'Sentimento', value: analise.sentimento, color: analise.sentimento==='positivo'?'oklch(0.45 0.18 155)':analise.sentimento==='negativo'?'oklch(0.50 0.20 25)':'oklch(0.45 0.12 255)' },
                    { label:'Urgência',   value: analise.urgencia,   color: analise.urgencia==='alta'?'oklch(0.50 0.20 25)':analise.urgencia==='media'?'oklch(0.55 0.18 75)':'oklch(0.45 0.12 255)' },
                    { label:'Interesse',  value: analise.interesse+'%', color: analise.interesse>=70?'oklch(0.45 0.18 155)':analise.interesse>=40?'oklch(0.55 0.18 75)':'oklch(0.50 0.20 25)' },
                  ].map(({label,value,color}) => (
                    <div key={label} style={{background:'white',borderRadius:8,padding:'8px 10px',border:'1px solid var(--ink-line)'}}>
                      <div style={{fontSize:9,fontWeight:700,letterSpacing:'0.07em',color:'var(--ink-muted)',textTransform:'uppercase',marginBottom:3}}>{label}</div>
                      <div style={{fontSize:13,fontWeight:700,color}}>{value}</div>
                    </div>
                  ))}
                </div>
                <div style={{background:'oklch(0.97 0.02 270)',borderRadius:8,padding:'8px 10px',fontSize:12,color:'var(--ink-soft)',lineHeight:1.4}}>
                  <span style={{fontWeight:600,color:'var(--ink)'}}>Situação: </span>{analise.resumo_curto}
                </div>
                <div style={{background:'oklch(0.96 0.04 155)',borderRadius:8,padding:'8px 10px',fontSize:12,color:'oklch(0.30 0.12 155)',lineHeight:1.4,borderLeft:'3px solid oklch(0.65 0.18 155)'}}>
                  <span style={{fontWeight:700}}>💡 Ação: </span>{analise.sugestao}
                </div>
              </div>
            ) : null}
          </div>
        )}

        {/* ── banner IA ── */}
        <div className={`conv-ai-bar ${isAi ? 'conv-ai-bar-on' : 'conv-ai-bar-off'}`}>
          <div className="conv-ai-bar-left">
            <div className={`conv-ai-dot ${isAi ? '' : 'conv-ai-dot-off'}`} />
            <span>{isAi ? 'IA SDR respondendo automaticamente' : 'Modo manual — você está no controle'}</span>
          </div>
          {isAi
            ? <button className="conv-assumir" onClick={() => setIsAi(false)}>Assumir conversa</button>
            : <button className="conv-ativar-ia" onClick={() => setIsAi(true)}><BoltIcon /> Ativar IA</button>
          }
        </div>

        {/* ── mensagens ── */}
        <div className="conv-msgs">
          <div className="conv-date-sep">Hoje</div>
          {msgs.map(m => (
            <div key={m.id} className={`conv-msg conv-msg-${m.from}`}>
              {m.from === 'me' && m.ai && (
                <div className="conv-ai-label"><BoltIcon /> IA SDR</div>
              )}
              <div className={`conv-bubble ${m.from === 'me' && m.ai ? 'conv-bubble-ai' : ''}`}>
                {m.type === 'img' ? (
                  <div style={{display:'flex',flexDirection:'column',gap:4}}>
                    <img src={m.url} alt={m.name} style={{maxWidth:200,borderRadius:8,display:'block'}} />
                    <span style={{fontSize:11,opacity:0.6}}>{m.name} · {m.size}</span>
                  </div>
                ) : m.type === 'file' ? (
                  <div style={{display:'flex',alignItems:'center',gap:8}}>
                    <span style={{fontSize:20}}>📄</span>
                    <div style={{display:'flex',flexDirection:'column',lineHeight:1.3}}>
                      <span style={{fontSize:13,fontWeight:500}}>{m.name}</span>
                      <span style={{fontSize:11,opacity:0.6}}>{m.size}</span>
                    </div>
                  </div>
                ) : m.text}
              </div>
              <div className="conv-time">{m.time}{m.from === 'me' && ' ✓✓'}</div>
            </div>
          ))}

          {aiTyping && (
            <div className="conv-msg conv-msg-me">
              <div className="conv-ai-label"><BoltIcon /> IA SDR</div>
              <div className="conv-bubble conv-bubble-ai conv-typing">
                <span /><span /><span />
              </div>
            </div>
          )}
          <div ref={endRef} />
        </div>

        {/* ── botão demo ── */}
        <div style={{padding: '8px 14px', borderTop: '0.5px solid var(--ink-line)', background: 'oklch(0.975 0.008 245)', display: 'flex', justifyContent: 'center'}}>
          <button className="conv-sim-btn" onClick={simulateLead}>↙ Simular mensagem do lead</button>
        </div>

        {/* ── input ── */}
        <div className="conv-input-area">
          {isAi ? (
            <div className="conv-ia-input-hint">
              <span className="conv-ia-hint-text"><BoltIcon /> IA está respondendo<span className="conv-ia-dots"><span/><span/><span/></span></span>
              <button className="conv-assumir-btn" onClick={() => setIsAi(false)}>
                <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"/><polyline points="10 17 15 12 10 7"/><line x1="15" y1="12" x2="3" y2="12"/></svg>
                Assumir conversa
              </button>
            </div>
          ) : (
            <>
              <input ref={fileRef} type="file" accept="image/*,.pdf,.doc,.docx,.xls,.xlsx,.txt" style={{display:'none'}} onChange={handleFile} />
              <button className="conv-ic-btn" title="Anexar arquivo" onClick={() => fileRef.current?.click()}>{ICN.upload}</button>
              <textarea
                className="conv-input"
                placeholder="Digite uma mensagem..."
                value={msg}
                onChange={e => setMsg(e.target.value)}
                onKeyDown={onKey}
                rows={1}
              />
              <button className="conv-send" onClick={send} disabled={sending} style={sending ? {opacity:0.5} : {}}>
                {sending ? '...' : ICN.send}
              </button>
            </>
          )}
        </div>

        <style>{`
          .conv-backdrop { position: fixed; inset: 0; z-index: 50; }
          .conv-drawer {
            position: fixed; top: 0; right: 0; bottom: 0; width: 390px;
            background: var(--card-solid);
            border-left: 0.5px solid var(--ink-line);
            display: flex; flex-direction: column;
            box-shadow: -24px 0 64px -20px rgba(20,30,60,.22);
            z-index: 51;
            animation: conv-in .3s cubic-bezier(.2,.8,.2,1);
          }
          @keyframes conv-in {
            from { transform: translateX(40px); opacity: 0; }
            to   { transform: translateX(0);    opacity: 1; }
          }

          .conv-head { padding: 14px 16px; border-bottom: 0.5px solid var(--ink-line); display: flex; align-items: center; gap: 11px; }
          .conv-head-av { width: 40px; height: 40px; border-radius: 50%; object-fit: cover; flex-shrink: 0; }
          .conv-head-info { flex: 1; min-width: 0; }
          .conv-head-name { font-size: 14px; font-weight: 600; letter-spacing: -0.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
          .conv-head-status { font-size: 10.5px; color: var(--ok); margin-top: 2px; display: flex; align-items: center; gap: 4px; }
          .conv-head-status::before { content:''; width:6px; height:6px; border-radius:50%; background:var(--ok); display:inline-block; }
          .conv-wa-badge { display:flex; align-items:center; gap:5px; background:oklch(0.94 0.04 155); color:oklch(0.34 0.12 160); padding:5px 10px; border-radius:999px; font-size:11px; font-weight:600; flex-shrink:0; }
          .conv-close { width:32px; height:32px; border-radius:50%; border:none; background:oklch(0.95 0.012 250); display:grid; place-items:center; cursor:default; color:var(--ink-muted); flex-shrink:0; transition:background .15s; }
          .conv-close:hover { background:oklch(0.91 0.012 250); }
          .conv-analise-btn { display:flex; align-items:center; gap:5px; background:oklch(0.94 0.04 270); color:oklch(0.35 0.15 270); border:1.5px solid oklch(0.82 0.08 270); border-radius:999px; padding:5px 11px; font-family:inherit; font-size:11px; font-weight:700; cursor:default; letter-spacing:-0.01em; transition:all .15s; flex-shrink:0; }
          .conv-analise-btn:hover { background:oklch(0.88 0.07 270); border-color:oklch(0.70 0.12 270); transform:scale(1.03); }
          .conv-analise-panel { margin:0 12px 0; background:oklch(0.975 0.015 270); border:1px solid oklch(0.88 0.06 270); border-radius:12px; padding:12px 14px; display:flex; flex-direction:column; gap:8px; }
          .conv-analise-header { display:flex; align-items:center; justify-content:space-between; font-size:11px; font-weight:700; color:oklch(0.40 0.15 270); letter-spacing:0.03em; text-transform:uppercase; }

          /* IA banner */
          .conv-ai-bar { display:flex; align-items:center; justify-content:space-between; gap:10px; padding:9px 14px; font-size:11.5px; font-weight:600; border-bottom:0.5px solid var(--ink-line); transition:background .3s; }
          .conv-ai-bar-on  { background:oklch(0.96 0.02 295); color:oklch(0.38 0.16 295); }
          .conv-ai-bar-off { background:oklch(0.97 0.01 250); color:var(--ink-muted); }
          .conv-ai-bar-left { display:flex; align-items:center; gap:8px; }
          .conv-ai-dot { width:7px; height:7px; border-radius:50%; background:oklch(0.55 0.18 295); animation:conv-pulse 1.6s ease-in-out infinite; flex-shrink:0; }
          .conv-ai-dot-off { background:var(--ink-faint); animation:none; }
          @keyframes conv-pulse {
            0%,100% { box-shadow:0 0 0 0 oklch(0.55 0.18 295 / 0.5); }
            50%      { box-shadow:0 0 0 5px oklch(0.55 0.18 295 / 0); }
          }
          .conv-assumir { background:oklch(0.22 0.01 255); color:white; border:none; border-radius:999px; padding:5px 13px; font-family:inherit; font-size:11px; font-weight:700; cursor:default; letter-spacing:-0.005em; transition:background .15s; flex-shrink:0; }
          .conv-assumir:hover { background:oklch(0.10 0.008 255); }
          .conv-ativar-ia { background:oklch(0.93 0.04 295); color:oklch(0.38 0.16 295); border:none; border-radius:999px; padding:5px 12px; font-family:inherit; font-size:11px; font-weight:700; cursor:default; display:flex; align-items:center; gap:5px; transition:background .15s; flex-shrink:0; }
          .conv-ativar-ia:hover { background:oklch(0.90 0.06 295); }

          /* mensagens */
          .conv-msgs { flex:1; overflow-y:auto; padding:16px 14px; display:flex; flex-direction:column; gap:10px; background:oklch(0.975 0.008 245); }
          .conv-msgs::-webkit-scrollbar { width:4px; }
          .conv-msgs::-webkit-scrollbar-thumb { background:oklch(0.88 0.012 255); border-radius:99px; }
          .conv-date-sep { align-self:center; font-size:11px; font-weight:600; color:var(--ink-muted); background:oklch(0.92 0.01 255 / 0.85); padding:4px 13px; border-radius:999px; backdrop-filter:blur(6px); margin-bottom:4px; }
          .conv-msg { display:flex; flex-direction:column; max-width:82%; }
          .conv-msg-them { align-self:flex-start; }
          .conv-msg-me   { align-self:flex-end; }
          .conv-bubble { padding:9px 13px; border-radius:18px; font-size:13px; line-height:1.5; letter-spacing:-0.003em; }
          .conv-msg-them .conv-bubble { background:white; color:var(--ink); border-bottom-left-radius:5px; box-shadow:0 1px 3px rgba(20,30,60,.07); }
          .conv-msg-me .conv-bubble { background:oklch(0.80 0.09 250); color:oklch(0.16 0.015 255); border-bottom-right-radius:5px; }
          .conv-bubble-ai { background:oklch(0.88 0.06 295) !important; color:oklch(0.22 0.08 295) !important; }
          .conv-ai-label { display:flex; align-items:center; gap:4px; font-size:10px; font-weight:700; color:oklch(0.50 0.16 295); text-transform:uppercase; letter-spacing:0.06em; margin-bottom:3px; padding-right:4px; justify-content:flex-end; }
          .conv-time { font-size:10px; color:var(--ink-faint); margin-top:3px; padding:0 5px; }
          .conv-msg-me .conv-time { text-align:right; }

          /* IA digitando */
          .conv-typing { display:flex; align-items:center; gap:5px; padding:12px 16px !important; }
          .conv-typing span { width:7px; height:7px; border-radius:50%; background:oklch(0.50 0.14 295); animation:conv-dot 1.2s ease-in-out infinite; }
          .conv-typing span:nth-child(2) { animation-delay:.2s; }
          .conv-typing span:nth-child(3) { animation-delay:.4s; }
          @keyframes conv-dot {
            0%,80%,100% { transform:scale(0.7); opacity:0.5; }
            40%          { transform:scale(1);   opacity:1; }
          }

          /* botão demo */
          .conv-sim-btn { font-family:inherit; font-size:11px; font-weight:600; color:var(--ink-muted); background:none; border:0.5px dashed var(--ink-line); border-radius:999px; padding:5px 14px; cursor:default; transition:border-color .15s, color .15s; }
          .conv-sim-btn:hover { border-color:var(--ink-soft); color:var(--ink-soft); }

          /* input */
          .conv-input-area { padding:12px 14px; border-top:0.5px solid var(--ink-line); display:flex; align-items:center; gap:8px; background:var(--card-solid); min-height:60px; }
          .conv-ia-input-hint { flex:1; font-size:12px; color:var(--ink-muted); display:flex; align-items:center; justify-content:space-between; gap:8px; }
          .conv-ia-hint-text { display:flex; align-items:center; gap:5px; font-size:12px; color:var(--ink-muted); }
          .conv-ia-dots { display:inline-flex; align-items:center; gap:2px; margin-left:2px; }
          .conv-ia-dots span { width:3px; height:3px; border-radius:50%; background:currentColor; opacity:0.5; animation:ia-dot 1.2s infinite; }
          .conv-ia-dots span:nth-child(2) { animation-delay:.2s; }
          .conv-ia-dots span:nth-child(3) { animation-delay:.4s; }
          @keyframes ia-dot { 0%,80%,100%{opacity:0.25;transform:scale(0.8)} 40%{opacity:1;transform:scale(1)} }
          .conv-assumir-btn { display:flex; align-items:center; gap:5px; background:oklch(0.94 0.04 295); color:oklch(0.35 0.15 295); border:1.5px solid oklch(0.82 0.08 295); border-radius:999px; padding:5px 12px; font-family:inherit; font-size:11px; font-weight:700; cursor:default; letter-spacing:-0.01em; transition:all .15s; white-space:nowrap; flex-shrink:0; }
          .conv-assumir-btn:hover { background:oklch(0.88 0.07 295); color:oklch(0.25 0.18 295); border-color:oklch(0.72 0.12 295); transform:scale(1.03); }
          .conv-input { flex:1; background:oklch(0.96 0.01 250); border:0.5px solid var(--ink-line); border-radius:22px; padding:9px 15px; font-family:inherit; font-size:13px; color:var(--ink); outline:none; resize:none; line-height:1.4; max-height:100px; overflow-y:auto; transition:border-color .15s, background .15s; }
          .conv-input:focus { border-color:oklch(0.72 0.08 250); background:white; }
          .conv-input::placeholder { color:var(--ink-faint); }
          .conv-send { width:38px; height:38px; border-radius:50%; background:var(--ink); color:white; border:none; display:grid; place-items:center; cursor:default; flex-shrink:0; transition:background .15s, transform .1s; }
          .conv-send:hover { background:oklch(0.10 0.008 255); transform:scale(1.05); }
          .conv-send:active { transform:scale(0.94); }
          .conv-ic-btn { width:34px; height:34px; border-radius:50%; background:none; border:none; display:grid; place-items:center; color:var(--ink-muted); cursor:default; flex-shrink:0; transition:background .15s; }
          .conv-ic-btn:hover { background:oklch(0.93 0.01 255); }

        `}</style>
      </div>
    </>
  );
}

// ── JCardDrawer — detalhe + edição do card ─────────────────────────────────
function JCardDrawer({ card, colId, allCols, onClose, onSave, onDelete, onChat, onMove }) {
  const [editing, setEditing] = useJornState(false);
  const [titulo, setTitulo] = useJornState(card.titulo);
  const [due, setDue] = useJornState(card.due || '');
  const [status, setStatus] = useJornState(card.status || 'pending');
  const toast = useToast();

  const colAtual = allCols.find(c => c.id === colId);
  const colMap = { blue: 'var(--acc-blue)', yellow: 'var(--acc-yellow)', pink: 'var(--acc-pink)', lav: 'var(--acc-lav)', mint: 'var(--acc-mint)' };

  const save = () => {
    onSave({ ...card, titulo, due, status });
    setEditing(false);
    toast('Card atualizado ✓');
  };

  const statusOpts = [
    { id: 'ok',      label: '✓ Concluído', bg: 'oklch(0.93 0.07 155)', fg: 'oklch(0.30 0.12 155)' },
    { id: 'warn',    label: '⚠ Atenção',   bg: 'oklch(0.94 0.08 75)',  fg: 'oklch(0.38 0.14 75)'  },
    { id: 'pending', label: '○ Pendente',  bg: 'oklch(0.95 0.01 250)', fg: 'var(--ink-muted)'      },
  ];

  return (
    <>
      <div className="conv-backdrop" onClick={onClose} />
      <div className="jcard-drawer">

        {/* ── cabeçalho ── */}
        <div className="jcard-drawer-head">
          <div className="jcard-drawer-stage">
            <span style={{ width: 8, height: 8, borderRadius: 99, background: colMap[colAtual?.color] || 'var(--ink-faint)', display: 'inline-block', marginRight: 7, flexShrink: 0 }} />
            {colAtual?.nome}
          </div>
          <div className="mini-btn" onClick={onClose}>{ICN.x}</div>
        </div>

        {/* ── corpo ── */}
        <div className="jcard-drawer-body">

          {/* título */}
          {editing
            ? <input className="jcard-title-input" value={titulo} onChange={e => setTitulo(e.target.value)} autoFocus onKeyDown={e => e.key === 'Enter' && save()} />
            : <div className="jcard-title" onClick={() => setEditing(true)} title="Clique para editar">{titulo}</div>
          }

          {/* status */}
          <div className="jcard-section">
            <div className="jcard-lbl">Status</div>
            <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
              {statusOpts.map(s => (
                <button key={s.id}
                  className="jcard-status-btn"
                  style={status === s.id ? { background: s.bg, color: s.fg, borderColor: 'transparent' } : {}}
                  onClick={() => setStatus(s.id)}>
                  {s.label}
                </button>
              ))}
            </div>
          </div>

          {/* prazo */}
          <div className="jcard-section">
            <div className="jcard-lbl">Prazo</div>
            {editing
              ? <input className="jcard-field-input" value={due} onChange={e => setDue(e.target.value)} placeholder="Ex: Hoje, Quinta, 30/05" />
              : <div className="jcard-field-val" onClick={() => setEditing(true)}>{due || <span style={{color:'var(--ink-faint)'}}>Sem prazo — clique para adicionar</span>}</div>
            }
          </div>

          {/* contato */}
          {card.contato && (
            <div className="jcard-section">
              <div className="jcard-lbl">Contato</div>
              <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                <img src={card.contato.avatar} alt="" style={{ width: 32, height: 32, borderRadius: '50%', flexShrink: 0 }} />
                <div>
                  <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--ink)' }}>{card.contato.nome}</div>
                  {card.contato.empresa && <div style={{ fontSize: 11, color: 'var(--ink-muted)', marginTop: 1 }}>{card.contato.empresa}</div>}
                </div>
              </div>
            </div>
          )}

          {/* mover para outra coluna */}
          <div className="jcard-section">
            <div className="jcard-lbl">Mover para</div>
            <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
              {allCols.filter(c => c.id !== colId).map(c => (
                <button key={c.id} className="jcard-move-btn"
                  onClick={() => { onMove(card.id, colId, c.id); onClose(); }}>
                  <span style={{ width: 6, height: 6, borderRadius: 99, background: colMap[c.color] || '#ccc', display: 'inline-block', marginRight: 5 }} />
                  {c.nome}
                </button>
              ))}
            </div>
          </div>
        </div>

        {/* ── ações ── */}
        <div className="jcard-drawer-actions">
          {card.contato && (
            <button className="jcard-action-wa" onClick={() => { onChat(card.contato); onClose(); }}>
              {ICN.whatsapp} Abrir conversa
            </button>
          )}
          <div style={{ display: 'flex', gap: 8, flex: 1 }}>
            {editing
              ? <button className="jcard-action-save" onClick={save}>Salvar</button>
              : <button className="jcard-action-edit" onClick={() => setEditing(true)}>{ICN.edit} Editar</button>
            }
            <button className="jcard-action-del" onClick={() => { onDelete(card.id, colId); onClose(); }}>{ICN.trash}</button>
          </div>
        </div>

        <style>{`
          .jcard-drawer {
            position: fixed; top: 0; right: 0; bottom: 0; width: 360px;
            background: var(--card-solid); border-left: 0.5px solid var(--ink-line);
            display: flex; flex-direction: column;
            box-shadow: -24px 0 64px -20px rgba(20,30,60,.22); z-index: 51;
            animation: conv-in .25s cubic-bezier(.2,.8,.2,1);
          }
          .jcard-drawer-head { padding: 14px 16px; border-bottom: 0.5px solid var(--ink-line); display: flex; align-items: center; justify-content: space-between; }
          .jcard-drawer-stage { font-size: 12px; font-weight: 600; color: var(--ink-muted); display: flex; align-items: center; }
          .jcard-drawer-body { flex: 1; overflow-y: auto; padding: 20px 18px; display: flex; flex-direction: column; gap: 20px; }
          .jcard-title { font-size: 17px; font-weight: 700; color: var(--ink); letter-spacing: -0.015em; line-height: 1.35; cursor: text; }
          .jcard-title:hover { color: oklch(0.40 0.14 250); }
          .jcard-title-input { font-size: 17px; font-weight: 700; color: var(--ink); letter-spacing: -0.015em; width: 100%; border: none; border-bottom: 2px solid oklch(0.62 0.14 250); background: transparent; outline: none; padding-bottom: 4px; font-family: inherit; line-height: 1.35; }
          .jcard-section { display: flex; flex-direction: column; gap: 8px; }
          .jcard-lbl { font-size: 10px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-muted); }
          .jcard-status-btn { font-family: inherit; font-size: 12px; font-weight: 600; padding: 5px 13px; border-radius: 999px; border: 1.5px solid var(--ink-line); background: transparent; color: var(--ink-muted); cursor: default; transition: all .15s; }
          .jcard-field-val { font-size: 13px; font-weight: 500; color: var(--ink); cursor: text; }
          .jcard-field-val:hover { color: oklch(0.40 0.14 250); }
          .jcard-field-input { font-size: 13px; font-weight: 500; border: none; border-bottom: 1.5px solid oklch(0.62 0.14 250); background: transparent; outline: none; font-family: inherit; color: var(--ink); width: 100%; padding-bottom: 2px; }
          .jcard-move-btn { font-family: inherit; font-size: 11.5px; font-weight: 600; padding: 5px 12px; border-radius: 999px; border: 1px solid var(--ink-line); background: oklch(0.97 0.01 250); color: var(--ink-soft); cursor: default; transition: all .15s; display: flex; align-items: center; }
          .jcard-move-btn:hover { background: var(--ink); color: white; border-color: var(--ink); }
          .jcard-drawer-actions { padding: 14px 18px; border-top: 0.5px solid var(--ink-line); display: flex; flex-direction: column; gap: 8px; }
          .jcard-action-wa { display: flex; align-items: center; justify-content: center; gap: 7px; font-family: inherit; font-size: 13px; font-weight: 600; padding: 10px; border-radius: 12px; border: none; background: oklch(0.93 0.06 155); color: oklch(0.28 0.12 160); cursor: default; transition: background .15s; }
          .jcard-action-wa:hover { background: oklch(0.87 0.08 155); }
          .jcard-action-edit { flex: 1; display: flex; align-items: center; justify-content: center; gap: 6px; font-family: inherit; font-size: 13px; font-weight: 600; padding: 10px; border-radius: 12px; border: 1.5px solid var(--ink-line); background: transparent; color: var(--ink); cursor: default; transition: all .15s; }
          .jcard-action-edit:hover { background: oklch(0.96 0.01 250); }
          .jcard-action-save { flex: 1; font-family: inherit; font-size: 13px; font-weight: 700; padding: 10px; border-radius: 12px; border: none; background: var(--ink); color: white; cursor: default; transition: background .15s; }
          .jcard-action-save:hover { background: oklch(0.10 0.008 255); }
          .jcard-action-del { width: 42px; height: 42px; border-radius: 12px; border: 1.5px solid oklch(0.90 0.04 18); background: transparent; color: var(--danger); cursor: default; display: grid; place-items: center; transition: all .15s; flex-shrink: 0; }
          .jcard-action-del:hover { background: oklch(0.96 0.02 18); }
        `}</style>
      </div>
    </>
  );
}

function ColorDot({ c }) {
  const map = { blue: 'var(--acc-blue)', yellow: 'var(--acc-yellow)', pink: 'var(--acc-pink)', mint: 'var(--acc-mint)', lav: 'var(--acc-lav)' };
  return <span style={{ width: 8, height: 8, borderRadius: 99, background: map[c] || '#ccc', display: 'inline-block' }} />;
}

function JTaskRow({ card, onChat, onOpen, isDragging, onDragStart, onDragEnd }) {
  const statusIcon = card.status === 'ok'
    ? <span style={{color:'var(--ok)'}}>{ICN.doubleCheck}</span>
    : card.status === 'warn'
    ? <span style={{color:'var(--warn)'}}>{ICN.dot}</span>
    : null;

  const WaBadgeIcon = () => (
    <svg width="9" height="9" viewBox="0 0 24 24" fill="currentColor">
      <path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z"/>
    </svg>
  );

  return (
    <div
      className={`jrow ${isDragging ? 'jrow-dragging' : ''}`}
      draggable="true"
      onDragStart={onDragStart}
      onDragEnd={onDragEnd}
      onClick={() => !isDragging && onOpen && onOpen(card)}
    >
      {card.contato && (
        <div className="jrow-av-wrap" onClick={e => { e.stopPropagation(); onChat && onChat(card.contato); }} title={`WhatsApp · ${card.contato.nome.split(' ')[0]}`}>
          <img className="jrow-av" src={card.contato.avatar} alt="" />
          <span className="jrow-av-chat"><WaBadgeIcon /></span>
        </div>
      )}
      <div className="jrow-body">
        <div className="jrow-title">{card.titulo}</div>
        {card.due && <div className="jrow-due">{card.due}</div>}
      </div>
      {statusIcon && <div className="jrow-status">{statusIcon}</div>}
      {card.featured && <div className="jrow-more">{ICN.more}</div>}
    </div>
  );
}

function JColumn({ col, idx, onChat, onOpen, isOver, dragCardId, onDragStart, onDragEnd, onDragOver, onDragLeave, onDrop }) {
  return (
    <div
      className={`jcol jcol-${col.color} ${col.active ? 'jcol-active' : ''} ${isOver ? 'jcol-over' : ''}`}
      onDragOver={onDragOver}
      onDragLeave={onDragLeave}
      onDrop={onDrop}
    >
      <div className="jcol-head">
        <div>
          <div className="jcol-name">{col.nome}</div>
          <div className="jcol-sub">{col.descritor}</div>
        </div>
        <div className="jcol-count"><ColorDot c={col.color}/>{col.cards.length}</div>
      </div>
      <div className="jcol-body">
        {col.cards.map(card => {
          if (col.id === 'novos') {
            return (
              <div
                key={card.id}
                className={`jpill ${card.pinned ? 'jpill-pinned' : ''} ${dragCardId === card.id ? 'jpill-dragging' : ''}`}
                draggable="true"
                onDragStart={(e) => onDragStart(e, card.id)}
                onDragEnd={onDragEnd}
                onClick={() => onOpen && onOpen(card)}
              >
                {card.pinned && <span className="jpill-pin">{ICN.pin}</span>}
                {card.titulo}
              </div>
            );
          }
          return (
            <JTaskRow
              key={card.id}
              card={card}
              onChat={onChat}
              onOpen={onOpen}
              isDragging={dragCardId === card.id}
              onDragStart={(e) => onDragStart(e, card.id)}
              onDragEnd={onDragEnd}
            />
          );
        })}
      </div>
    </div>
  );
}

// ── Modal: Novo Fluxo — usa 100% o design system existente ────────────────
function NovoFluxoModal({ onClose, onSave }) {
  const [nome, setNome] = useJornState('');
  const [cor, setCor] = useJornState('blue');
  const [desc, setDesc] = useJornState('');

  const COR_OPTS = [
    { id: 'blue',   label: 'Azul',    bg: 'var(--acc-blue)'   },
    { id: 'yellow', label: 'Amarelo', bg: 'var(--acc-yellow)'  },
    { id: 'pink',   label: 'Rosa',    bg: 'var(--acc-pink)'    },
    { id: 'lav',    label: 'Lavanda', bg: 'var(--acc-lav)'     },
    { id: 'mint',   label: 'Verde',   bg: 'var(--acc-mint)'    },
  ];

  const submit = () => {
    if (!nome.trim()) return;
    onSave(nome.trim(), desc.trim(), cor);
  };

  return (
    <div className="modal-wrap" onClick={onClose}>
      <div className="card modal-card" onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <div>
            <div className="modal-title">Novo Fluxo <em>de Jornada</em></div>
            <div className="modal-sub muted">Configure o novo fluxo do kanban</div>
          </div>
          <div className="mini-btn" onClick={onClose}>{ICN.x}</div>
        </div>

        <div className="form-grid">
          <div className="field" style={{gridColumn:'1/-1'}}>
            <label className="field-lbl">Nome do fluxo *</label>
            <input
              className="ezz-input"
              placeholder="Ex: Onboarding de Clientes"
              value={nome}
              onChange={e => setNome(e.target.value)}
              onKeyDown={e => e.key === 'Enter' && submit()}
              autoFocus
            />
          </div>
          <div className="field" style={{gridColumn:'1/-1'}}>
            <label className="field-lbl">Descrição (opcional)</label>
            <input
              className="ezz-input"
              placeholder="Ex: Fluxo de boas-vindas para novos clientes"
              value={desc}
              onChange={e => setDesc(e.target.value)}
            />
          </div>
          <div className="field" style={{gridColumn:'1/-1'}}>
            <label className="field-lbl">Cor do fluxo</label>
            <div className="row" style={{gap: 10}}>
              {COR_OPTS.map(c => (
                <button
                  key={c.id}
                  title={c.label}
                  onClick={() => setCor(c.id)}
                  style={{
                    width: 32, height: 32, borderRadius: '50%',
                    background: c.bg,
                    border: cor === c.id ? '3px solid var(--ink)' : '3px solid transparent',
                    boxShadow: cor === c.id ? '0 0 0 2px white inset' : 'none',
                    transform: cor === c.id ? 'scale(1.15)' : 'scale(1)',
                    transition: 'all .15s', cursor: 'default',
                  }}
                />
              ))}
            </div>
          </div>
        </div>

        <div className="modal-actions">
          <button className="btn-ghost" onClick={onClose}>Cancelar</button>
          <button className="btn-primary" onClick={submit} disabled={!nome.trim()} style={{opacity: nome.trim() ? 1 : 0.5}}>
            {ICN.plus} Criar fluxo
          </button>
        </div>
      </div>
    </div>
  );
}

/* ── Modal: Novo item de Conhecimento ────────────────────── */
function NovoConhecimentoModal({ onClose, onAdd }) {
  const [assunto, setAssunto] = useJornState('');
  const [resp, setResp] = useJornState('');
  const [status, setStatus] = useJornState('Agendado');
  const [inicio, setInicio] = useJornState('');
  const [fim, setFim] = useJornState('');
  const toast = useToast();

  const STATUSES = [
    { label: 'Agendado',  pillCls: 'pill-yellow' },
    { label: 'Em curso',  pillCls: 'pill-blue'   },
    { label: 'Executado', pillCls: 'pill-mint'    },
    { label: 'Atrasado',  pillCls: 'pill-pink'    },
  ];
  const valid = assunto.trim().length > 0;

  const submit = () => {
    if (!valid) return;
    const st = STATUSES.find(s => s.label === status);
    onAdd({ assunto: assunto.trim(), status, pillCls: st.pillCls, inicio: inicio || '—', fim: fim || '—', resp: resp.trim() || '—' });
    toast(`"${assunto.trim()}" adicionado ✓`);
    onClose();
  };

  return (
    <div className="modal-wrap" onClick={onClose}>
      <div className="card modal-card" onClick={e => e.stopPropagation()} style={{width: 500}}>
        <div className="modal-head">
          <div>
            <div className="modal-title">Novo <em>Conhecimento</em></div>
            <div className="modal-sub muted">Adicionar à base de conhecimento sugerido</div>
          </div>
          <div className="mini-btn" onClick={onClose}>{ICN.x}</div>
        </div>
        <div className="form-grid">
          <div className="field field-full">
            <label className="field-lbl">Assunto *</label>
            <input className="ezz-input" placeholder="Ex: Revisão de contrato Q4" value={assunto} onChange={e => setAssunto(e.target.value)} autoFocus />
          </div>
          <div className="field">
            <label className="field-lbl">Início</label>
            <input className="ezz-input" type="datetime-local" value={inicio} onChange={e => setInicio(e.target.value)} />
          </div>
          <div className="field">
            <label className="field-lbl">Fim</label>
            <input className="ezz-input" type="datetime-local" value={fim} onChange={e => setFim(e.target.value)} />
          </div>
          <div className="field">
            <label className="field-lbl">Responsável</label>
            <input className="ezz-input" placeholder="Ex: Ana Carvalho" value={resp} onChange={e => setResp(e.target.value)} />
          </div>
          <div className="field">
            <label className="field-lbl">Status</label>
            <div className="row" style={{gap:6, flexWrap:'wrap'}}>
              {STATUSES.map(s => (
                <span key={s.label} className={`pill ${status === s.label ? s.pillCls : ''}`}
                  onClick={() => setStatus(s.label)} style={{cursor:'default', fontSize:11}}>{s.label}</span>
              ))}
            </div>
          </div>
        </div>
        <div className="modal-actions">
          <button className="btn-ghost" onClick={onClose}>Cancelar</button>
          <button className="btn-primary" onClick={submit} disabled={!valid} style={{opacity: valid ? 1 : 0.5}}>
            {ICN.plus} Adicionar
          </button>
        </div>
      </div>
    </div>
  );
}

/* ── Modal: Novo Ticket ──────────────────────────────────── */
function NovoTicketModal({ onClose, onCreate }) {
  const [titulo, setTitulo] = useJornState('');
  const [tipo, setTipo] = useJornState('Ativo');
  const [resp, setResp] = useJornState('');
  const toast = useToast();

  const TIPOS = [
    { label: 'Executado', pillCls: 'pill-mint'   },
    { label: 'Ativo',     pillCls: 'pill-pink'   },
    { label: 'Em revisão',pillCls: 'pill-yellow'  },
  ];
  const valid = titulo.trim().length > 0;

  const submit = () => {
    if (!valid) return;
    if (onCreate) onCreate(titulo.trim(), resp.trim());
    toast(`Ticket "${titulo.trim()}" criado ✓`);
    onClose();
  };

  return (
    <div className="modal-wrap" onClick={onClose}>
      <div className="card modal-card" onClick={e => e.stopPropagation()} style={{width: 460}}>
        <div className="modal-head">
          <div>
            <div className="modal-title">Novo <em>Ticket</em></div>
            <div className="modal-sub muted">Adicionar à Jornada de Tickets</div>
          </div>
          <div className="mini-btn" onClick={onClose}>{ICN.x}</div>
        </div>
        <div className="form-grid">
          <div className="field field-full">
            <label className="field-lbl">Título do ticket *</label>
            <input className="ezz-input" placeholder="Ex: Revisão de SLA com cliente" value={titulo} onChange={e => setTitulo(e.target.value)} autoFocus />
          </div>
          <div className="field field-full">
            <label className="field-lbl">Estágio</label>
            <div className="row" style={{gap:6}}>
              {TIPOS.map(t => (
                <span key={t.label} className={`pill ${tipo === t.label ? t.pillCls : ''}`}
                  onClick={() => setTipo(t.label)} style={{cursor:'default', fontSize:11}}>{t.label}</span>
              ))}
            </div>
          </div>
          <div className="field field-full">
            <label className="field-lbl">Responsável (opcional)</label>
            <input className="ezz-input" placeholder="Ex: Felipe Almeida" value={resp} onChange={e => setResp(e.target.value)} />
          </div>
        </div>
        <div className="modal-actions">
          <button className="btn-ghost" onClick={onClose}>Cancelar</button>
          <button className="btn-primary" onClick={submit} disabled={!valid} style={{opacity: valid ? 1 : 0.5}}>
            {ICN.plus} Criar ticket
          </button>
        </div>
      </div>
    </div>
  );
}

const jornHeaders = () => { const t = localStorage.getItem('ezza_token'); return { 'Content-Type':'application/json', ...(t?{'Authorization':`Bearer ${t}`}:{}) }; };

function Jornadas({ ticketStyle = 'rows', goto }) {
  const [activeChat, setActiveChat] = useJornState(null);
  const [activeCard, setActiveCard] = useJornState(null); // { card, colId }
  const [cols, setCols] = useJornState([]); // carregado do banco
  const [apiMode, setApiMode] = useJornState(false); // true quando dados vêm do banco

  // Carrega colunas + cards reais do banco
  useJornEffect(() => {
    fetch('/api/jornadas', { headers: jornHeaders() })
      .then(r => r.json())
      .then(d => {
        if (d.ok) {
          const cards = d.cards || [];
          setCols(d.colunas.map(col => ({
            id: col.id, nome: col.titulo, color: col.cor || 'blue', descritor: '',
            cards: cards.filter(c => c.coluna_id === col.id).map(c => ({
              id: c.id, titulo: c.titulo, descricao: c.descricao,
              contato: { nome: c.contato || '', avatar: AVATAR_URLS[(c.id || 0) % 12] },
              status: 'ok', due: '', valor: parseFloat(c.valor) || 0,
            })),
          })));
          setApiMode(true);
        } else {
          setCols(JORNADAS.map(c => ({ ...c, cards: [...c.cards] })));
        }
      })
      .catch(() => setCols(JORNADAS.map(c => ({ ...c, cards: [...c.cards] }))));
  }, []);
  const [dragInfo, setDragInfo] = useJornState(null);
  const [dragOverCol, setDragOverCol] = useJornState(null);
  const [showNovoFluxo, setShowNovoFluxo] = useJornState(false);
  const [filterAt, setFilterAt] = useJornState(null); // índice em ATENDENTES_FLUXO
  const [filterStatus, setFilterStatus] = useJornState(null); // 'ok' | 'warn' | 'pending'
  const [showFilterMenu, setShowFilterMenu] = useJornState(false);
  const [showNovoConhecimento, setShowNovoConhecimento] = useJornState(false);
  const [localConhecimento, setLocalConhecimento] = useJornState([
    { assunto: 'Sprint de design',       status: 'Executado', inicio: '30/09 01:12', fim: '01/10 01:11', resp: 'Sam Frank',     pillCls: 'pill-mint'   },
    { assunto: 'Encerramento de lead',   status: 'Agendado',  inicio: '02/10 17:41', fim: '02/10 18:41', resp: 'Nikki Olin',    pillCls: 'pill-yellow' },
    { assunto: 'Revisão de SLA Q2',      status: 'Em curso',  inicio: '03/10 09:00', fim: '03/10 11:00', resp: 'Ana Carvalho',  pillCls: 'pill-blue'   },
    { assunto: 'Onboarding Café do Vale',status: 'Atrasado',  inicio: '28/09 14:00', fim: '29/09 18:00', resp: 'Camila Lima',   pillCls: 'pill-pink'   },
  ]);
  const [showNovoTicket, setShowNovoTicket] = useJornState(false);
  const toast = useToast();
  const filterMenuRef = useJornRef(null);

  useJornEffect(() => {
    if (!showFilterMenu) return;
    const handler = (e) => {
      if (filterMenuRef.current && !filterMenuRef.current.contains(e.target)) {
        setShowFilterMenu(false);
      }
    };
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, [showFilterMenu]);

  // handler: criar novo fluxo (coluna)
  const handleNovoFluxo = async (nome, desc, cor) => {
    setShowNovoFluxo(false);
    if (apiMode) {
      try {
        const r = await fetch('/api/jornadas/colunas', { method:'POST', headers: jornHeaders(), body: JSON.stringify({ titulo: nome, cor }) });
        const d = await r.json();
        if (d.ok) {
          setCols(prev => [...prev, { id: d.coluna.id, nome: d.coluna.titulo, color: d.coluna.cor, descritor: desc||'', cards: [] }]);
          toast(`Fluxo "${nome}" criado ✓`);
          return;
        }
      } catch (e) {}
    }
    setCols(prev => [...prev, { id: 'fluxo-'+Date.now(), nome, color: cor, descritor: desc||'Novo fluxo', cards: [] }]);
    toast(`Fluxo "${nome}" criado ✓`);
  };

  // handlers do drawer de card
  const handleOpenCard = (card, colId) => setActiveCard({ card, colId });
  const handleSaveCard = (updated) => {
    setCols(prev => prev.map(col => ({
      ...col,
      cards: col.cards.map(c => c.id === updated.id ? { ...c, ...updated } : c),
    })));
    setActiveCard(prev => prev ? { ...prev, card: { ...prev.card, ...updated } } : null);
  };
  const handleDeleteCard = (cardId, colId) => {
    setCols(prev => prev.map(col =>
      col.id === colId ? { ...col, cards: col.cards.filter(c => c.id !== cardId) } : col
    ));
    if (apiMode) { try { fetch(`/api/jornadas/cards/${cardId}`, { method:'DELETE', headers: jornHeaders() }); } catch (e) {} }
  };

  const handleDragStart = (e, cardId, colId) => {
    setDragInfo({ cardId, fromColId: colId });
    e.dataTransfer.effectAllowed = 'move';
  };
  const handleDragEnd = () => { setDragInfo(null); setDragOverCol(null); };
  const handleDragOver = (e, colId) => {
    e.preventDefault();
    e.dataTransfer.dropEffect = 'move';
    if (dragOverCol !== colId) setDragOverCol(colId);
  };
  const handleDragLeave = (e) => {
    const rel = e.relatedTarget;
    if (!rel || !e.currentTarget.contains(rel)) setDragOverCol(null);
  };
  const handleDrop = (e, toColId, overrideCardId, overrideFromColId) => {
    e.preventDefault();
    const cardId   = overrideCardId   ?? dragInfo?.cardId;
    const fromColId = overrideFromColId ?? dragInfo?.fromColId;
    if (!cardId || fromColId === toColId) { setDragInfo(null); setDragOverCol(null); return; }
    setCols(prev => {
      const card = prev.find(c => c.id === fromColId)?.cards.find(c => c.id === cardId);
      if (!card) return prev;
      return prev.map(col => {
        if (col.id === fromColId) return { ...col, cards: col.cards.filter(c => c.id !== cardId) };
        if (col.id === toColId)   return { ...col, cards: [...col.cards, card] };
        return col;
      });
    });
    if (apiMode) { try { fetch(`/api/jornadas/cards/${cardId}`, { method:'PATCH', headers: jornHeaders(), body: JSON.stringify({ colunaId: toColId }) }); } catch (e) {} }
    setDragInfo(null);
    setDragOverCol(null);
  };

  // cols visíveis (com filtro de status se ativo)
  const colsVisiveis = cols.map(col => ({
    ...col,
    cards: filterStatus
      ? col.cards.filter(c => (c.status || 'pending') === filterStatus)
      : col.cards,
  }));

  const totalAtivos = cols.reduce((s, c) => s + c.cards.length, 0);

  return (
    <>
      {showNovoFluxo && <NovoFluxoModal onClose={() => setShowNovoFluxo(false)} onSave={handleNovoFluxo} />}
      {activeChat && <ConversaDrawer contato={activeChat} onClose={() => setActiveChat(null)} />}
      {!activeChat && activeCard && (
        <JCardDrawer
          card={activeCard.card}
          colId={activeCard.colId}
          allCols={cols}
          onClose={() => setActiveCard(null)}
          onSave={handleSaveCard}
          onDelete={handleDeleteCard}
          onChat={(contato) => { setActiveCard(null); setActiveChat(contato); }}
          onMove={(cardId, fromColId, toColId) => handleDrop({ preventDefault: () => {} }, toColId, cardId, fromColId)}
        />
      )}

      {showNovoConhecimento && (
        <NovoConhecimentoModal
          onClose={() => setShowNovoConhecimento(false)}
          onAdd={(item) => setLocalConhecimento(prev => [...prev, item])}
        />
      )}

      {showNovoTicket && (
        <NovoTicketModal onClose={() => setShowNovoTicket(false)} onCreate={async (titulo, resp) => {
          const col0 = cols[0];
          if (!col0) return;
          if (apiMode) {
            try {
              const r = await fetch('/api/jornadas/cards', { method:'POST', headers: jornHeaders(), body: JSON.stringify({ colunaId: col0.id, titulo, contato: resp }) });
              const d = await r.json();
              if (d.ok) {
                setCols(prev => prev.map(c => c.id === col0.id ? { ...c, cards: [...c.cards, { id: d.card.id, titulo, contato: { nome: resp, avatar: AVATAR_URLS[(d.card.id||0)%12] }, status:'ok', due:'', valor:0 }] } : c));
                return;
              }
            } catch (e) {}
          }
          setCols(prev => prev.map(c => c.id === col0.id ? { ...c, cards: [...c.cards, { id:'card-'+Date.now(), titulo, contato:{nome:resp,avatar:AVATAR_URLS[0]}, status:'ok', due:'' }] } : c));
        }} />
      )}

      <PageHead
        title={<>Jornadas <em>do Cliente</em></>}
        subtitle="Acompanhe o fluxo de cada caso da triagem ao encerramento"
        right={
          <div className="row" style={{position:'relative'}}>
            <div className="pill pill-blue">{cols.length} fluxos ativos</div>
            <div style={{position:'relative'}} ref={filterMenuRef}>
              <ActionBtn
                icon={ICN.filter}
                title="Filtrar por status"
                size="icon"
                onClick={() => setShowFilterMenu(m => !m)}
              />
              {showFilterMenu && (
                <div className="jfilter-menu">
                  <div className="jfilter-title">Filtrar cards por status</div>
                  {[
                    { id: null,      label: 'Todos os cards',  dot: 'var(--ink-faint)' },
                    { id: 'ok',      label: 'Concluídos',      dot: 'var(--ok)'        },
                    { id: 'warn',    label: 'Em atenção',      dot: 'var(--warn)'      },
                    { id: 'pending', label: 'Pendentes',       dot: 'var(--ink-muted)' },
                  ].map(opt => (
                    <button
                      key={String(opt.id)}
                      className={`jfilter-opt ${filterStatus === opt.id ? 'jfilter-opt-sel' : ''}`}
                      onClick={() => { setFilterStatus(opt.id); setShowFilterMenu(false); }}
                    >
                      <span style={{ width:8, height:8, borderRadius:'50%', background:opt.dot, display:'inline-block', flexShrink:0 }} />
                      {opt.label}
                    </button>
                  ))}
                </div>
              )}
            </div>
            <ActionBtn
              icon={ICN.plus}
              title="Novo fluxo"
              size="icon"
              onClick={() => setShowNovoFluxo(true)}
            />
          </div>
        }
      />

      <div className="card jhero">
        <div className="card-head jhero-head">
          <div>
            <div className="jhero-title">Gestão de Novos Casos</div>
            <div className="jhero-sub">
              Atualizado há 4 minutos — {totalAtivos} cards em {cols.length} fluxos
              {filterStatus && <span className="jhero-filter-badge">filtro ativo: {filterStatus === 'ok' ? 'concluídos' : filterStatus === 'warn' ? 'atenção' : 'pendentes'} <button onClick={() => setFilterStatus(null)}>×</button></span>}
            </div>
          </div>

          <div className="jhero-people">
            <div className="row" style={{gap: 5}}>
              {ATENDENTES_FLUXO.map((at, i) => (
                <div
                  key={i}
                  className={`jp-chip ${filterAt === i ? 'jp-chip-active' : ''}`}
                  onClick={() => setFilterAt(filterAt === i ? null : i)}
                  title={`${at.nome} — ${at.casos} casos ativos`}
                >
                  <img src={AVATAR_URLS[at.avatarIdx]} alt={at.nome} />
                  <span className="jp-num">{at.casos}</span>
                  <div className="jp-tooltip">
                    <strong>{at.nome}</strong>
                    <span>{at.casos} casos ativos</span>
                  </div>
                </div>
              ))}
              <div className="jp-more" title="4 outros atendentes">+4</div>
            </div>
            {filterAt !== null && (
              <div className="jp-filter-banner">
                Filtrando por <strong>{ATENDENTES_FLUXO[filterAt].nome}</strong>
                <button onClick={() => setFilterAt(null)}>Limpar filtro ×</button>
              </div>
            )}
          </div>

          <CardActions createLabel="Novo fluxo" onCreate={() => setShowNovoFluxo(true)} onPeriod={() => goto && goto('calendario')} />
        </div>

        <div className="jkanban" style={{gridTemplateColumns: `repeat(${cols.length}, minmax(180px, 1fr))`}}>
          {colsVisiveis.map((col, i) => (
            <JColumn
              key={col.id}
              col={col}
              idx={i}
              onChat={setActiveChat}
              onOpen={(card) => handleOpenCard(card, col.id)}
              isOver={dragOverCol === col.id}
              dragCardId={dragInfo?.cardId}
              onDragStart={(e, cardId) => handleDragStart(e, cardId, col.id)}
              onDragEnd={handleDragEnd}
              onDragOver={(e) => handleDragOver(e, col.id)}
              onDragLeave={handleDragLeave}
              onDrop={(e) => handleDrop(e, col.id)}
            />
          ))}
        </div>
      </div>

      <div className="row" style={{gap: 14, alignItems: 'stretch', marginTop: 14}}>
        <div className="card" style={{flex: 1.4}}>
          <div className="card-head">
            <div className="card-title">Conhecimento Sugerido</div>
            <CardActions createLabel="Novo item" onCreate={() => setShowNovoConhecimento(true)} onPeriod={() => goto && goto('calendario')} />
          </div>
          <table className="tbl">
            <thead><tr>
              <th></th><th>Assunto</th><th>Status</th><th>Início</th><th>Fim</th><th>Responsável</th>
            </tr></thead>
            <tbody>
              {localConhecimento.map((r, i) => (
                <tr key={i}>
                  <td style={{width:24}}>{ICN.star}</td>
                  <td>{r.assunto}</td>
                  <td><span className={`pill ${r.pillCls}`}>{r.status}</span></td>
                  <td>{r.inicio}</td>
                  <td>{r.fim}</td>
                  <td>{r.resp}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>

        <TicketJourneyCard variant={ticketStyle} onCreate={() => setShowNovoTicket(true)} goto={goto} />
      </div>

      <style>{`
        .jhero { padding: 22px 22px 6px; }
        .jhero-head { align-items: flex-start; gap: 24px; }
        .jhero-title { font-size: 17px; font-weight: 600; }
        .jhero-sub { font-size: 12.5px; color: var(--ink-muted); margin-top: 2px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
        .jhero-filter-badge { background: oklch(0.94 0.06 75); color: oklch(0.38 0.14 75); padding: 2px 9px; border-radius: 999px; font-size: 11px; font-weight: 600; display: inline-flex; align-items: center; gap: 5px; }
        .jhero-filter-badge button { background: none; border: none; cursor: default; font-size: 13px; line-height: 1; color: inherit; padding: 0; margin: 0 -2px 0 2px; opacity: 0.7; }
        .jhero-filter-badge button:hover { opacity: 1; }
        .jhero-people { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 8px; }
        .jp-chip { position: relative; cursor: default; transition: transform .15s; }
        .jp-chip:hover { transform: translateY(-3px); z-index: 2; }
        .jp-chip img { width: 36px; height: 36px; border-radius: 50%; border: 2px solid white; box-shadow: 0 0 0 1px oklch(0.88 0.01 255); object-fit: cover; transition: box-shadow .15s; display: block; }
        .jp-chip-active img { box-shadow: 0 0 0 2.5px oklch(0.55 0.16 250); }
        .jp-chip-active .jp-num { background: oklch(0.55 0.16 250); color: white; border-color: white; }
        .jp-num { position: absolute; bottom: -3px; right: -3px; width: 17px; height: 17px; border-radius: 50%; background: oklch(0.82 0.09 18); color: oklch(0.28 0.12 18); font-size: 9px; font-weight: 800; display: grid; place-items: center; border: 1.5px solid white; letter-spacing: -0.02em; }
        .jp-tooltip { position: absolute; bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%); background: var(--ink); color: white; border-radius: 9px; padding: 6px 10px; font-size: 11px; font-weight: 500; white-space: nowrap; pointer-events: none; opacity: 0; transition: opacity .15s; box-shadow: 0 4px 12px rgba(20,30,60,.25); z-index: 10; display: flex; flex-direction: column; gap: 2px; text-align: center; }
        .jp-tooltip::after { content: ''; position: absolute; top: 100%; left: 50%; transform: translateX(-50%); border: 5px solid transparent; border-top-color: var(--ink); }
        .jp-tooltip strong { font-weight: 700; font-size: 12px; }
        .jp-tooltip span { color: oklch(0.75 0.02 250); font-size: 10.5px; }
        .jp-chip:hover .jp-tooltip { opacity: 1; }
        .jp-more { width: 36px; height: 36px; border-radius: 50%; background: oklch(0.94 0.01 255); display: grid; place-items: center; font-size: 11px; font-weight: 600; color: var(--ink-muted); border: 2px solid white; box-shadow: 0 0 0 1px oklch(0.88 0.01 255); cursor: default; }
        .jp-filter-banner { background: oklch(0.95 0.03 250); border: 1px solid oklch(0.85 0.06 250); border-radius: 999px; padding: 4px 10px 4px 12px; font-size: 11.5px; color: oklch(0.35 0.12 250); display: flex; align-items: center; gap: 6px; white-space: nowrap; }
        .jp-filter-banner strong { font-weight: 700; }
        .jp-filter-banner button { background: none; border: none; cursor: default; font-size: 12px; color: inherit; opacity: 0.6; padding: 0; }
        .jp-filter-banner button:hover { opacity: 1; }

        .jfilter-menu { position: absolute; top: calc(100% + 8px); right: 0; background: var(--card-solid); border: 0.5px solid var(--ink-line); border-radius: 14px; box-shadow: 0 8px 24px -8px rgba(20,30,60,.22); padding: 10px; display: flex; flex-direction: column; gap: 4px; z-index: 20; min-width: 190px; animation: conv-in .15s cubic-bezier(.2,.8,.2,1); }
        .jfilter-title { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .07em; color: var(--ink-muted); padding: 4px 8px 6px; }
        .jfilter-opt { font-family: inherit; font-size: 13px; font-weight: 500; color: var(--ink); background: transparent; border: none; padding: 8px 10px; border-radius: 9px; cursor: default; text-align: left; display: flex; align-items: center; gap: 9px; transition: background .12s; }
        .jfilter-opt:hover { background: oklch(0.95 0.01 250); }
        .jfilter-opt-sel { background: oklch(0.93 0.04 250) !important; color: oklch(0.35 0.14 250); font-weight: 700; }

        .jkanban { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; padding-top: 18px; overflow-x: auto; }
        .jcol { background: oklch(1 0 0 / 0.55); border-radius: var(--radius-md); padding: 16px; border: 0.5px solid oklch(1 0 0 / 0.9); min-height: 360px; }
        .jcol-blue   { background: linear-gradient(180deg, oklch(0.97 0.025 245) 0%, oklch(1 0 0 / 0.6) 100%); }
        .jcol-yellow { background: linear-gradient(180deg, oklch(0.98 0.04 95) 0%, oklch(1 0 0 / 0.6) 100%); }
        .jcol-pink   { background: linear-gradient(180deg, oklch(0.97 0.025 18) 0%, oklch(1 0 0 / 0.6) 100%); }
        .jcol-lav    { background: linear-gradient(180deg, oklch(0.97 0.025 295) 0%, oklch(1 0 0 / 0.6) 100%); }
        .jcol-mint   { background: linear-gradient(180deg, oklch(0.97 0.025 155) 0%, oklch(1 0 0 / 0.6) 100%); }
        .jcol-head { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 12px; }
        .jcol-name { font-weight: 600; font-size: 13.5px; }
        .jcol-sub  { font-size: 11.5px; color: var(--ink-muted); margin-top: 2px; }
        .jcol-count { display: flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 600; color: var(--ink-muted); background: oklch(1 0 0 / 0.7); padding: 4px 9px; border-radius: 999px; }
        .jcol-body { display: flex; flex-direction: column; gap: 8px; }

        .jcol { transition: outline .12s, background .12s; }
        .jcol-over { outline: 2px dashed oklch(0.62 0.14 250 / 0.6); outline-offset: -3px; }
        .jcol-blue.jcol-over   { background: linear-gradient(180deg, oklch(0.94 0.04 245) 0%, oklch(0.96 0.02 245 / 0.8) 100%) !important; }
        .jcol-yellow.jcol-over { background: linear-gradient(180deg, oklch(0.95 0.06 95) 0%, oklch(0.96 0.04 95 / 0.8) 100%) !important; }
        .jcol-pink.jcol-over   { background: linear-gradient(180deg, oklch(0.94 0.04 18) 0%, oklch(0.96 0.02 18 / 0.8) 100%) !important; }
        .jcol-lav.jcol-over    { background: linear-gradient(180deg, oklch(0.94 0.04 295) 0%, oklch(0.96 0.02 295 / 0.8) 100%) !important; }

        .jrow { display: flex; align-items: center; gap: 10px; background: white; border-radius: 14px; padding: 10px 12px; box-shadow: 0 1px 2px rgba(20,30,60,.04); cursor: grab; transition: opacity .15s, transform .15s, box-shadow .15s; }
        .jrow:active { cursor: grabbing; }
        .jrow-dragging { opacity: 0.35; transform: scale(0.96); box-shadow: none !important; cursor: grabbing; }
        .jrow-av { width: 30px; height: 30px; border-radius: 50%; object-fit: cover; flex-shrink: 0; display:block; }
        .jrow-av-wrap { position:relative; flex-shrink:0; cursor:default; }
        .jrow-av-wrap:hover .jrow-av { filter:brightness(0.92); }
        .jrow-av-chat {
          position:absolute; bottom:-2px; right:-3px;
          width:16px; height:16px; border-radius:50%;
          background:#25D366; color:white;
          display:grid; place-items:center;
          border:2px solid white;
          box-shadow:0 1px 4px rgba(0,0,0,.18);
          transition:transform .15s, box-shadow .15s;
        }
        .jrow-av-wrap:hover .jrow-av-chat {
          transform:scale(1.18);
          box-shadow:0 2px 8px rgba(37,211,102,.45);
        }
        .jrow-body { flex: 1; min-width: 0; }
        .jrow-title { font-size: 12.5px; font-weight: 500; line-height: 1.25; }
        .jrow-due { font-size: 10.5px; color: var(--ink-muted); margin-top: 2px; }
        .jrow-status { display: flex; align-items: center; color: var(--ok); }
        .jrow-more { color: var(--ink-muted); }

        .jpill { background: white; border-radius: 14px; padding: 14px 16px; font-size: 13px; font-weight: 500; box-shadow: 0 1px 2px rgba(20,30,60,.04); position: relative; cursor: grab; transition: opacity .15s, transform .15s; }
        .jpill:active { cursor: grabbing; }
        .jpill-pinned { background: var(--black); color: white; box-shadow: 0 12px 24px -10px rgba(20,30,60,.35); }
        .jpill-pin { position: absolute; top: 10px; right: 12px; opacity: 0.6; }
        .jpill-dragging { opacity: 0.35; transform: scale(0.96); box-shadow: none !important; cursor: grabbing; }

        .ring-row { display: flex; gap: 20px; justify-content: space-around; padding: 10px 0 4px; }
      `}</style>
    </>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Jornada de Tickets — 3 variantes selecionáveis via Tweaks
// ──────────────────────────────────────────────────────────────────────────

const TICKET_STAGES = [
  { id: 'exec',   label: 'Executado',  n: 5, color: 'blue',   trend: [2,3,2,3,4,4,5], delta: '+2' },
  { id: 'ativo',  label: 'Ativo',      n: 7, color: 'pink',   trend: [4,5,6,5,7,6,7], delta: '+1' },
  { id: 'rev',    label: 'Em revisão', n: 3, color: 'yellow', trend: [2,2,3,3,2,3,3], delta: '0'  },
];

const STAGE_COLOR = {
  blue:   'oklch(0.78 0.10 250)',
  pink:   'oklch(0.82 0.09 18)',
  yellow: 'oklch(0.88 0.13 95)',
};

function TicketJourneyCard({ variant, onCreate, goto }) {
  const total = TICKET_STAGES.reduce((s, x) => s + x.n, 0);

  return (
    <div className="card tj-card" style={{flex: 1}}>
      <div className="card-head">
        <div>
          <div className="card-title">Jornada de Tickets</div>
          <div className="tj-sub">Últimos 7 dias · {total} tickets</div>
        </div>
        <CardActions createLabel="Novo ticket" onCreate={onCreate} onPeriod={() => goto && goto('relatorios')} />
      </div>

      {variant === 'bars'  && <TJBars  total={total} />}
      {variant === 'rows'  && <TJRows  total={total} />}
      {variant === 'donut' && <TJDonut total={total} />}

      <style>{`
        .tj-card { display: flex; flex-direction: column; }
        .tj-sub { font-size: 11.5px; color: var(--ink-muted); margin-top: 3px; font-variant-numeric: tabular-nums; }
      `}</style>
    </div>
  );
}

/* ─── Variant A: stacked bar + legend rows ─────────────────────────────── */
function TJBars({ total }) {
  return (
    <div className="tj-bars">
      <div className="tj-stack">
        {TICKET_STAGES.map((s, i) => (
          <div key={s.id} className="tj-seg" style={{
            flex: s.n,
            background: STAGE_COLOR[s.color],
            borderTopLeftRadius:    i === 0 ? 999 : 0,
            borderBottomLeftRadius: i === 0 ? 999 : 0,
            borderTopRightRadius:    i === TICKET_STAGES.length - 1 ? 999 : 0,
            borderBottomRightRadius: i === TICKET_STAGES.length - 1 ? 999 : 0,
          }}>
            <span className="tj-seg-n">{s.n}</span>
          </div>
        ))}
      </div>
      <div className="tj-legend">
        {TICKET_STAGES.map(s => {
          const pct = Math.round((s.n / total) * 100);
          return (
            <div key={s.id} className="tj-leg-row">
              <span className="tj-dot" style={{ background: STAGE_COLOR[s.color] }} />
              <span className="tj-leg-label">{s.label}</span>
              <span className="tj-leg-pct">{pct}%</span>
              <span className="tj-leg-n">{s.n}</span>
            </div>
          );
        })}
      </div>
      <style>{`
        .tj-bars { display: flex; flex-direction: column; gap: 20px; padding: 14px 4px 6px; flex: 1; justify-content: center; }
        .tj-stack { display: flex; height: 28px; gap: 3px; }
        .tj-seg { display: grid; place-items: center; transition: flex 0.3s; min-width: 30px; }
        .tj-seg-n { font-size: 12.5px; font-weight: 700; color: oklch(0.25 0.04 255); letter-spacing: -0.01em; }
        .tj-legend { display: flex; flex-direction: column; gap: 10px; }
        .tj-leg-row { display: grid; grid-template-columns: 10px 1fr auto auto; align-items: center; gap: 10px; padding: 6px 2px; border-bottom: 0.5px solid var(--ink-line); }
        .tj-leg-row:last-child { border-bottom: none; }
        .tj-dot { width: 8px; height: 8px; border-radius: 50%; }
        .tj-leg-label { font-size: 12.5px; font-weight: 500; color: var(--ink); }
        .tj-leg-pct { font-size: 11px; color: var(--ink-muted); font-variant-numeric: tabular-nums; min-width: 32px; text-align: right; }
        .tj-leg-n { font-size: 14px; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; min-width: 22px; text-align: right; letter-spacing: -0.01em; }
      `}</style>
    </div>
  );
}

/* ─── Variant B: dense rows with sparklines ────────────────────────────── */
function TJRows({ total }) {
  return (
    <div className="tj-rows">
      {TICKET_STAGES.map(s => (
        <div key={s.id} className="tj-row">
          <div className="tj-row-head">
            <span className="tj-dot" style={{ background: STAGE_COLOR[s.color] }} />
            <span className="tj-row-label">{s.label}</span>
            <span className="tj-row-delta" data-pos={s.delta.startsWith('+')} data-flat={s.delta === '0'}>{s.delta}</span>
          </div>
          <div className="tj-row-vis">
            <Sparkline points={s.trend} color={STAGE_COLOR[s.color]} />
            <span className="tj-row-n">{s.n}</span>
          </div>
        </div>
      ))}
      <style>{`
        .tj-rows { display: flex; flex-direction: column; padding: 8px 2px 4px; flex: 1; justify-content: center; gap: 4px; }
        .tj-row { padding: 10px 2px; border-bottom: 0.5px solid var(--ink-line); }
        .tj-row:last-child { border-bottom: none; }
        .tj-row-head { display: flex; align-items: center; gap: 8px; }
        .tj-row-label { font-size: 12px; font-weight: 600; color: var(--ink); flex: 1; letter-spacing: -0.005em; }
        .tj-row-delta { font-size: 10.5px; font-weight: 600; color: var(--ink-muted); font-variant-numeric: tabular-nums; padding: 2px 7px; border-radius: 999px; background: oklch(0.95 0.005 255); }
        .tj-row-delta[data-pos="true"] { color: oklch(0.45 0.13 155); background: oklch(0.95 0.04 155); }
        .tj-row-delta[data-flat="true"] { color: var(--ink-muted); }
        .tj-row-vis { display: flex; align-items: center; gap: 14px; margin-top: 6px; }
        .tj-row-vis svg { flex: 1; height: 28px; }
        .tj-row-n { font-size: 26px; font-weight: 700; letter-spacing: -0.025em; color: var(--ink); font-variant-numeric: tabular-nums; min-width: 32px; text-align: right; line-height: 1; }
      `}</style>
    </div>
  );
}

function Sparkline({ points, color }) {
  const w = 100, h = 28, pad = 2;
  const min = Math.min(...points), max = Math.max(...points);
  const range = max - min || 1;
  const stepX = (w - pad * 2) / (points.length - 1);
  const coords = points.map((p, i) => [pad + i * stepX, h - pad - ((p - min) / range) * (h - pad * 2)]);
  const path = coords.map((c, i) => `${i === 0 ? 'M' : 'L'} ${c[0].toFixed(1)} ${c[1].toFixed(1)}`).join(' ');
  const area = path + ` L ${coords[coords.length-1][0].toFixed(1)} ${h} L ${coords[0][0].toFixed(1)} ${h} Z`;
  const last = coords[coords.length - 1];
  return (
    <svg viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none" style={{ width: '100%' }}>
      <path d={area} fill={color} opacity="0.18" />
      <path d={path} fill="none" stroke={color} strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" vectorEffect="non-scaling-stroke" />
      <circle cx={last[0]} cy={last[1]} r="2.4" fill={color} />
    </svg>
  );
}

/* ─── Variant C: donut with center total + side legend ─────────────────── */
function TJDonut({ total }) {
  const size = 132, stroke = 18, r = (size - stroke) / 2;
  const C = 2 * Math.PI * r;
  let offset = 0;
  const segs = TICKET_STAGES.map(s => {
    const frac = s.n / total;
    const seg = { ...s, dash: frac * C, gap: C - frac * C, rot: (offset / C) * 360 };
    offset += frac * C;
    return seg;
  });

  return (
    <div className="tj-donut">
      <div className="tj-donut-svg">
        <svg viewBox={`0 0 ${size} ${size}`} width={size} height={size}>
          {segs.map((s, i) => (
            <circle key={s.id}
              cx={size/2} cy={size/2} r={r}
              fill="none" stroke={STAGE_COLOR[s.color]} strokeWidth={stroke}
              strokeDasharray={`${s.dash} ${s.gap}`}
              transform={`rotate(${s.rot - 90} ${size/2} ${size/2})`}
              strokeLinecap="butt"
            />
          ))}
        </svg>
        <div className="tj-donut-center">
          <div className="tj-donut-n">{total}</div>
          <div className="tj-donut-label">tickets</div>
        </div>
      </div>
      <div className="tj-donut-legend">
        {TICKET_STAGES.map(s => (
          <div key={s.id} className="tj-leg-row">
            <span className="tj-dot" style={{ background: STAGE_COLOR[s.color] }} />
            <span className="tj-leg-label">{s.label}</span>
            <span className="tj-leg-n">{s.n}</span>
          </div>
        ))}
      </div>
      <style>{`
        .tj-donut { display: flex; align-items: center; gap: 18px; padding: 14px 2px 6px; flex: 1; justify-content: center; }
        .tj-donut-svg { position: relative; flex-shrink: 0; }
        .tj-donut-center { position: absolute; inset: 0; display: grid; place-items: center; text-align: center; }
        .tj-donut-n { font-size: 28px; font-weight: 700; letter-spacing: -0.025em; line-height: 1; }
        .tj-donut-label { font-size: 10.5px; color: var(--ink-muted); font-weight: 500; text-transform: lowercase; margin-top: 3px; }
        .tj-donut-legend { display: flex; flex-direction: column; gap: 6px; flex: 1; min-width: 0; }
        .tj-donut-legend .tj-leg-row { display: grid; grid-template-columns: 10px 1fr auto; align-items: center; gap: 10px; padding: 6px 0; border-bottom: 0.5px solid var(--ink-line); }
        .tj-donut-legend .tj-leg-row:last-child { border-bottom: none; }
        .tj-donut-legend .tj-dot { width: 8px; height: 8px; border-radius: 50%; }
        .tj-donut-legend .tj-leg-label { font-size: 12.5px; font-weight: 500; color: var(--ink); }
        .tj-donut-legend .tj-leg-n { font-size: 14px; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
      `}</style>
    </div>
  );
}

window.Jornadas = Jornadas;
