
// WhatsApp Module — integracao via Z-API
// Layout estilo WhatsApp Web: lista de conversas a esquerda, chat ao centro.
// Mensagens entram/saem em tempo real via Supabase Realtime.

// Templates de resposta rapida (proxima iteracao: cadastrar via tela admin)
const QUICK_REPLIES = [
  { label: 'Saudação', text: 'Olá! Tudo bem? Aqui é a Promoup, em que posso te ajudar?' },
  { label: 'Vou enviar orçamento', text: 'Já estou montando o orçamento e te envio em instantes 🙏' },
  { label: 'Retorno em breve', text: 'Recebido! Vou consultar internamente e te dou um retorno em breve.' },
  { label: 'Confirmar evento', text: 'Oi! Estou passando para confirmar nosso evento. Está tudo certo para seguir?' },
  { label: 'Agradecimento', text: 'Muito obrigada pelo contato! Qualquer coisa estou à disposição. 😊' },
  { label: 'Pedir documentos', text: 'Para seguir com a contratação, você consegue me enviar: CNPJ/CPF, endereço completo e dados para nota fiscal? 📋' },
];

// Normaliza telefone para 13 digitos com codigo do pais (formato Z-API)
function normalizePhoneForZapi(p) {
  let digits = (p || '').replace(/[^0-9]/g, '');
  // Adiciona 9 no celular antigo
  if (digits.length === 10) digits = digits.slice(0, 2) + '9' + digits.slice(2);
  if (digits.length === 11) digits = '55' + digits;
  return digits;
}

function WhatsApp({ currentUser, onNavigate }) {
  const [conversations, setConversations] = React.useState([]);
  const [activeConv, setActiveConv] = React.useState(null);
  const [messages, setMessages] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [search, setSearch] = React.useState('');
  const [statusFilter, setStatusFilter] = React.useState('all');
  const [draft, setDraft] = React.useState('');
  const [sending, setSending] = React.useState(false);
  const [toast, setToast] = React.useState(null);
  const [newConvModal, setNewConvModal] = React.useState(false);
  const [uploading, setUploading] = React.useState(false);
  const [showTemplates, setShowTemplates] = React.useState(false);
  const [appUsers, setAppUsers] = React.useState([]);
  const [showAssignDrop, setShowAssignDrop] = React.useState(false);
  const [showTagsDrop, setShowTagsDrop] = React.useState(false);
  const [showClientPanel, setShowClientPanel] = React.useState(true);
  const [clientInfo, setClientInfo] = React.useState(null);
  const [clientBudgets, setClientBudgets] = React.useState([]);
  const [clientEvents, setClientEvents] = React.useState([]);
  const messagesEndRef = React.useRef(null);
  const fileInputRef = React.useRef(null);

  const showToast = (msg, type = 'success') => {
    setToast({ msg, type });
    setTimeout(() => setToast(null), 3000);
  };

  // ───────── Carga inicial ─────────
  const fetchConversations = React.useCallback(async () => {
    const { data } = await sb.from('whatsapp_conversations')
      .select('id, phone, contact_name, profile_pic_url, client_id, last_message_at, last_message_preview, last_message_from, unread_count, status, assigned_to, tags')
      .order('last_message_at', { ascending: false })
      .limit(200);
    setConversations(data || []);
    setLoading(false);
  }, []);

  React.useEffect(() => { fetchConversations(); }, [fetchConversations]);

  // Carrega usuarios para atribuicao
  React.useEffect(() => {
    sb.from('app_users').select('id, name, email, department').order('name').then(({ data }) => {
      setAppUsers(data || []);
    });
  }, []);

  const TAG_PRESETS = ['Comercial', 'Suporte', 'Produção', 'Financeiro', 'Lead Quente', 'Aguardando'];
  const TAG_COLORS = { 'Comercial': '#10B981', 'Suporte': '#3B82F6', 'Produção': '#F59E0B', 'Financeiro': '#8B5CF6', 'Lead Quente': '#EF4444', 'Aguardando': '#64748B' };

  const assignConversation = async (userId) => {
    if (!activeConv) return;
    await sb.from('whatsapp_conversations').update({ assigned_to: userId }).eq('id', activeConv.id);
    setConversations(prev => prev.map(c => c.id === activeConv.id ? { ...c, assigned_to: userId } : c));
    setActiveConv(prev => ({ ...prev, assigned_to: userId }));
    setShowAssignDrop(false);
    showToast(userId ? `Atribuído a ${appUsers.find(u => u.id === userId)?.name || 'usuário'}` : 'Atribuição removida');
  };

  const toggleTag = async (tag) => {
    if (!activeConv) return;
    const currentTags = activeConv.tags || [];
    const newTags = currentTags.includes(tag) ? currentTags.filter(t => t !== tag) : [...currentTags, tag];
    await sb.from('whatsapp_conversations').update({ tags: newTags }).eq('id', activeConv.id);
    setConversations(prev => prev.map(c => c.id === activeConv.id ? { ...c, tags: newTags } : c));
    setActiveConv(prev => ({ ...prev, tags: newTags }));
  };

  // ───────── Realtime para conversas + mensagens ─────────
  React.useEffect(() => {
    const channel = sb.channel('wpp-realtime')
      .on('postgres_changes', { event: '*', schema: 'public', table: 'whatsapp_conversations' }, payload => {
        if (payload.eventType === 'INSERT' || payload.eventType === 'UPDATE') {
          setConversations(prev => {
            const idx = prev.findIndex(c => c.id === payload.new.id);
            if (idx >= 0) {
              const next = [...prev];
              next[idx] = { ...next[idx], ...payload.new };
              return next.sort((a, b) => new Date(b.last_message_at) - new Date(a.last_message_at));
            }
            return [payload.new, ...prev];
          });
        } else if (payload.eventType === 'DELETE') {
          setConversations(prev => prev.filter(c => c.id !== payload.old.id));
        }
      })
      .on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'whatsapp_messages' }, payload => {
        const msg = payload.new;
        // Se a conversa ativa eh a dele, adiciona na lista
        setActiveConv(curr => {
          if (curr && curr.id === msg.conversation_id) {
            setMessages(prev => {
              if (prev.some(m => m.id === msg.id)) return prev;
              return [...prev, msg];
            });
          }
          return curr;
        });
      })
      .subscribe();
    return () => { sb.removeChannel(channel); };
  }, []);

  // ───────── Carrega dados do cliente vinculado ─────────
  React.useEffect(() => {
    setClientInfo(null);
    setClientBudgets([]);
    setClientEvents([]);
    if (!activeConv?.client_id) return;
    (async () => {
      const [clientRes, budgetsRes, eventsRes] = await Promise.all([
        sb.from('clients').select('*').eq('id', activeConv.client_id).maybeSingle(),
        sb.from('budgets').select('id, code, event_name, value, status, issued_date').eq('client_name', '__none__').order('issued_date', { ascending: false }).limit(5),
        sb.from('events').select('id, name, type, event_date, status').eq('client_name', '__none__').order('event_date', { ascending: false }).limit(5),
      ]);
      const c = clientRes.data;
      setClientInfo(c);
      if (c) {
        const [budByName, evByName] = await Promise.all([
          sb.from('budgets').select('id, code, event_name, value, status, issued_date').eq('client_name', c.name).order('issued_date', { ascending: false }).limit(5),
          sb.from('events').select('id, name, type, event_date, status').eq('client_name', c.name).order('event_date', { ascending: false }).limit(5),
        ]);
        setClientBudgets(budByName.data || []);
        setClientEvents(evByName.data || []);
      }
    })();
  }, [activeConv?.id, activeConv?.client_id]);

  // ───────── Carrega mensagens quando seleciona conversa ─────────
  React.useEffect(() => {
    if (!activeConv) { setMessages([]); return; }
    sb.from('whatsapp_messages')
      .select('id, conversation_id, direction, type, body, media_url, media_mime, sender_user_id, status, created_at')
      .eq('conversation_id', activeConv.id)
      .order('created_at', { ascending: true })
      .limit(500)
      .then(({ data }) => setMessages(data || []));

    // Zera unread
    if (activeConv.unread_count > 0) {
      sb.from('whatsapp_conversations').update({ unread_count: 0 }).eq('id', activeConv.id).then(() => {
        setConversations(prev => prev.map(c => c.id === activeConv.id ? { ...c, unread_count: 0 } : c));
      });
    }
  }, [activeConv]);

  // ───────── Auto-scroll pro final ─────────
  React.useEffect(() => {
    if (messagesEndRef.current) messagesEndRef.current.scrollIntoView({ behavior: 'smooth', block: 'end' });
  }, [messages]);

  // ───────── Enviar mensagem ─────────
  const handleSend = async () => {
    if (!draft.trim() || !activeConv) return;
    const text = draft.trim();
    setSending(true);
    setDraft('');
    try {
      // sb.functions.invoke cuida do apikey + Authorization automaticamente
      const { data, error } = await sb.functions.invoke('whatsapp-send', {
        body: {
          conversation_id: activeConv.id,
          type: 'text',
          body: text,
        },
      });
      if (error) {
        showToast('Erro ao enviar: ' + (error.message || 'tente novamente'), 'error');
        setDraft(text);
      }
    } catch (e) {
      showToast('Erro: ' + e.message, 'error');
      setDraft(text);
    } finally {
      setSending(false);
    }
  };

  // ───────── Anexar e enviar arquivo (foto, audio, PDF) ─────────
  const handleAttachFile = async (e) => {
    const file = e.target.files?.[0];
    e.target.value = ''; // permite re-anexo do mesmo arquivo
    if (!file || !activeConv) return;
    if (file.size > 16 * 1024 * 1024) {
      showToast('Arquivo grande demais (máx 16MB)', 'error');
      return;
    }
    setUploading(true);
    try {
      // 1) Upload pro bucket Supabase
      const ext = file.name.split('.').pop() || 'bin';
      const path = `conv_${activeConv.id}/${Date.now()}_${Math.random().toString(36).slice(2, 8)}.${ext}`;
      const { error: upErr } = await sb.storage.from('whatsapp-media').upload(path, file, {
        contentType: file.type,
        upsert: false,
      });
      if (upErr) throw upErr;
      const { data: { publicUrl } } = sb.storage.from('whatsapp-media').getPublicUrl(path);

      // 2) Determina tipo (image / audio / document)
      let msgType = 'document';
      if (file.type.startsWith('image/')) msgType = 'image';
      else if (file.type.startsWith('audio/')) msgType = 'audio';

      // 3) Chama whatsapp-send com a URL publica
      const { error } = await sb.functions.invoke('whatsapp-send', {
        body: {
          conversation_id: activeConv.id,
          type: msgType,
          media_url: publicUrl,
          media_filename: file.name,
          body: draft.trim() || null, // caption opcional (texto que estiver digitado)
        },
      });
      if (error) {
        showToast('Erro ao enviar: ' + (error.message || 'tente novamente'), 'error');
        return;
      }
      setDraft(''); // limpa caption depois de enviar
      showToast('Enviado!');
    } catch (e) {
      showToast('Erro: ' + e.message, 'error');
    } finally {
      setUploading(false);
    }
  };

  // ───────── Mudar status / fechar conversa ─────────
  const setConvStatus = async (id, newStatus) => {
    await sb.from('whatsapp_conversations').update({ status: newStatus }).eq('id', id);
    setConversations(prev => prev.map(c => c.id === id ? { ...c, status: newStatus } : c));
    if (activeConv?.id === id) setActiveConv(prev => ({ ...prev, status: newStatus }));
    showToast(newStatus === 'resolved' ? 'Conversa marcada como resolvida' : 'Conversa reaberta');
  };

  // ───────── Permissoes: Comercial ve so as conversas atribuidas a ele ─────────
  const visibleConvs = React.useMemo(() => {
    if (!currentUser) return conversations;
    // Admin (role) ve tudo. Setores admin/financeiro/sdr/atendimento veem tudo.
    if (currentUser.role === 'admin') return conversations;
    if (['admin','financeiro','sdr','atendimento'].includes(currentUser.department)) return conversations;
    // Comercial ve so as conversas atribuidas a ele OU sem atribuicao
    if (currentUser.department === 'comercial') {
      return conversations.filter(c => c.assigned_to === currentUser.id || !c.assigned_to);
    }
    // Producao: ve tudo (eles tambem podem precisar acompanhar)
    return conversations;
  }, [conversations, currentUser]);

  // ───────── Filtros e busca (inclui busca em conteudo de mensagens) ─────────
  const [searchedInMsgs, setSearchedInMsgs] = React.useState(new Set());
  React.useEffect(() => {
    const q = search.trim();
    if (q.length < 3) { setSearchedInMsgs(new Set()); return; }
    const t = setTimeout(async () => {
      const { data } = await sb.from('whatsapp_messages').select('conversation_id').ilike('body', `%${q}%`).limit(200);
      setSearchedInMsgs(new Set((data || []).map(m => m.conversation_id)));
    }, 350);
    return () => clearTimeout(t);
  }, [search]);

  const filteredConvs = React.useMemo(() => {
    const q = search.trim().toLowerCase();
    return visibleConvs.filter(c => {
      if (statusFilter !== 'all' && c.status !== statusFilter) return false;
      if (!q) return true;
      const matchHeader = (c.contact_name || '').toLowerCase().includes(q) || (c.phone || '').includes(q);
      const matchBody = searchedInMsgs.has(c.id);
      return matchHeader || matchBody;
    });
  }, [visibleConvs, search, statusFilter, searchedInMsgs]);

  // ───────── Helpers de visual ─────────
  const fmtTime = (iso) => {
    if (!iso) return '';
    const d = new Date(iso);
    const today = new Date();
    if (d.toDateString() === today.toDateString()) {
      return d.toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit' });
    }
    const yesterday = new Date(today); yesterday.setDate(today.getDate() - 1);
    if (d.toDateString() === yesterday.toDateString()) return 'Ontem';
    return d.toLocaleDateString('pt-BR', { day: '2-digit', month: '2-digit' });
  };
  const fmtPhone = (p) => {
    if (!p) return '';
    const clean = p.replace(/\D/g, '');
    if (clean.length === 13) return `+${clean.slice(0, 2)} (${clean.slice(2, 4)}) ${clean.slice(4, 9)}-${clean.slice(9)}`;
    if (clean.length === 12) return `+${clean.slice(0, 2)} (${clean.slice(2, 4)}) ${clean.slice(4, 8)}-${clean.slice(8)}`;
    return p;
  };

  // ───────── Estilos ─────────
  const wppBg = '#E5DDD5'; // mesmo bg do WhatsApp
  const ogColor = '#EA6B00';
  const navyColor = '#12085C';

  // ─────────────────────────────────
  // RENDER
  // ─────────────────────────────────
  if (loading) {
    return (
      <div>
        <h1 style={{ fontSize: 24, fontWeight: 700, color: DS.colors.text, margin: 0, marginBottom: 16 }}>WhatsApp</h1>
        <Spinner />
      </div>
    );
  }

  const NoConv = () => (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', background: wppBg, color: DS.colors.textMuted }}>
      <div style={{ width: 96, height: 96, borderRadius: '50%', background: 'rgba(18,8,92,0.08)', display: 'flex', alignItems: 'center', justifyContent: 'center', marginBottom: 20 }}>
        <Icon name="message" size={42} color={navyColor} />
      </div>
      <div style={{ fontSize: 18, fontWeight: 700, color: DS.colors.text }}>Selecione uma conversa</div>
      <div style={{ fontSize: 13, color: DS.colors.textSec, marginTop: 6, maxWidth: 320, textAlign: 'center', lineHeight: 1.5 }}>
        Clique em uma conversa à esquerda para abrir o histórico e responder. As mensagens novas aparecem em tempo real.
      </div>
    </div>
  );

  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: 'calc(100vh - 120px)' }}>
      {/* Header */}
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 }}>
        <div>
          <h1 style={{ fontSize: 22, fontWeight: 700, color: DS.colors.text, margin: 0, letterSpacing: '-0.02em' }}>WhatsApp</h1>
          <p style={{ fontSize: 12, color: DS.colors.textSec, margin: '2px 0 0' }}>
            {conversations.length} conversa{conversations.length !== 1 ? 's' : ''} · {conversations.reduce((s, c) => s + (c.unread_count || 0), 0)} não lida{conversations.reduce((s, c) => s + (c.unread_count || 0), 0) !== 1 ? 's' : ''}
          </p>
        </div>
        <Btn icon="plus" onClick={() => setNewConvModal(true)}>Nova conversa</Btn>
      </div>

      {/* Container principal */}
      <div style={{ flex: 1, display: 'flex', borderRadius: DS.radius.md, overflow: 'hidden', border: `1px solid ${DS.colors.border}`, background: '#fff', minHeight: 0 }}>

        {/* ────── COLUNA: LISTA DE CONVERSAS ────── */}
        <div style={{ width: 340, borderRight: `1px solid ${DS.colors.border}`, display: 'flex', flexDirection: 'column', background: '#F8FAFC' }}>

          {/* Busca + filtros */}
          <div style={{ padding: 12, borderBottom: `1px solid ${DS.colors.border}` }}>
            <div style={{ position: 'relative', marginBottom: 8 }}>
              <input
                value={search}
                onChange={e => setSearch(e.target.value)}
                placeholder="Buscar nome, número ou texto da conversa..."
                style={{
                  width: '100%', boxSizing: 'border-box',
                  border: `1px solid ${DS.colors.border}`, borderRadius: DS.radius.sm,
                  padding: '8px 12px 8px 36px', fontSize: 13, outline: 'none',
                  background: '#fff', fontFamily: 'inherit',
                }}
              />
              <div style={{ position: 'absolute', left: 12, top: '50%', transform: 'translateY(-50%)' }}>
                <Icon name="search" size={14} color={DS.colors.textMuted} />
              </div>
            </div>
            <div style={{ display: 'flex', gap: 4 }}>
              {[
                ['all', 'Todas'],
                ['open', 'Aberto'],
                ['pending', 'Pendente'],
                ['resolved', 'Resolvido'],
              ].map(([val, label]) => (
                <button key={val} onClick={() => setStatusFilter(val)}
                  style={{
                    padding: '4px 10px', borderRadius: 999, border: 'none', fontSize: 11, fontWeight: 600, cursor: 'pointer',
                    background: statusFilter === val ? ogColor : '#fff',
                    color: statusFilter === val ? '#fff' : DS.colors.textSec,
                    border: statusFilter === val ? 'none' : `1px solid ${DS.colors.border}`,
                  }}>{label}</button>
              ))}
            </div>
          </div>

          {/* Lista */}
          <div style={{ flex: 1, overflowY: 'auto' }}>
            {filteredConvs.length === 0 ? (
              <div style={{ padding: '32px 20px', textAlign: 'center', fontSize: 13, color: DS.colors.textMuted }}>
                <Icon name="message" size={28} color={DS.colors.border} />
                <div style={{ marginTop: 10 }}>{search || statusFilter !== 'all' ? 'Nenhuma conversa encontrada' : 'Nenhuma conversa ainda'}</div>
              </div>
            ) : filteredConvs.map(c => {
              const isActive = activeConv?.id === c.id;
              return (
                <div key={c.id} onClick={() => setActiveConv(c)}
                  style={{
                    display: 'flex', alignItems: 'center', gap: 12,
                    padding: '12px 14px', cursor: 'pointer',
                    background: isActive ? '#FFF1E0' : 'transparent',
                    borderLeft: isActive ? `3px solid ${ogColor}` : '3px solid transparent',
                    borderBottom: `1px solid ${DS.colors.border}`,
                    transition: 'background 0.15s',
                  }}
                  onMouseEnter={e => { if (!isActive) e.currentTarget.style.background = '#F1F5F9'; }}
                  onMouseLeave={e => { if (!isActive) e.currentTarget.style.background = 'transparent'; }}>
                  {c.profile_pic_url ? (
                    <img src={c.profile_pic_url} alt="" style={{ width: 42, height: 42, borderRadius: '50%', objectFit: 'cover', flexShrink: 0 }} onError={e => e.target.style.display = 'none'} />
                  ) : (
                    <Avatar name={c.contact_name || c.phone} size={42} color={ogColor} />
                  )}
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', gap: 8 }}>
                      <span style={{ fontSize: 13.5, fontWeight: 700, color: DS.colors.text, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                        {c.contact_name || fmtPhone(c.phone)}
                      </span>
                      <span style={{ fontSize: 10.5, color: c.unread_count > 0 ? ogColor : DS.colors.textMuted, fontWeight: c.unread_count > 0 ? 700 : 500, flexShrink: 0 }}>
                        {fmtTime(c.last_message_at)}
                      </span>
                    </div>
                    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 8, marginTop: 2 }}>
                      <span style={{ fontSize: 12, color: DS.colors.textSec, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', flex: 1 }}>
                        {c.last_message_from === 'us' && <span style={{ color: DS.colors.textMuted, marginRight: 4 }}>↗</span>}
                        {c.last_message_preview || '(sem mensagens)'}
                      </span>
                      {c.unread_count > 0 && (
                        <span style={{ background: ogColor, color: '#fff', fontSize: 10, fontWeight: 700, borderRadius: 999, padding: '1px 7px', minWidth: 18, textAlign: 'center', flexShrink: 0 }}>
                          {c.unread_count}
                        </span>
                      )}
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
        </div>

        {/* ────── COLUNAS: CHAT ATIVO + PAINEL CLIENTE ────── */}
        {!activeConv ? <NoConv /> : (
          <div style={{ flex: 1, display: 'flex', minHeight: 0 }}>
          <div style={{ flex: 1, display: 'flex', flexDirection: 'column', background: wppBg, minHeight: 0 }}>

            {/* Header do chat */}
            <div style={{ padding: '10px 16px', background: '#F8FAFC', borderBottom: `1px solid ${DS.colors.border}` }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
                {activeConv.profile_pic_url ? (
                  <img src={activeConv.profile_pic_url} alt="" style={{ width: 36, height: 36, borderRadius: '50%', objectFit: 'cover' }} />
                ) : (
                  <Avatar name={activeConv.contact_name || activeConv.phone} size={36} color={ogColor} />
                )}
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 14, fontWeight: 700, color: DS.colors.text }}>
                    {activeConv.contact_name || fmtPhone(activeConv.phone)}
                  </div>
                  <div style={{ fontSize: 11, color: DS.colors.textSec }}>{fmtPhone(activeConv.phone)}</div>
                </div>
                <div style={{ display: 'flex', gap: 6 }}>
                  <Btn variant="secondary" size="sm" icon={showClientPanel ? 'x' : 'users'} onClick={() => setShowClientPanel(s => !s)} title={showClientPanel ? 'Ocultar info do cliente' : 'Mostrar info do cliente'}>
                    {showClientPanel ? 'Fechar painel' : 'Cliente'}
                  </Btn>
                  {activeConv.status !== 'resolved' ? (
                    <Btn variant="secondary" size="sm" icon="check" onClick={() => setConvStatus(activeConv.id, 'resolved')}>
                      Marcar resolvido
                    </Btn>
                  ) : (
                    <Btn variant="secondary" size="sm" icon="edit" onClick={() => setConvStatus(activeConv.id, 'open')}>
                      Reabrir
                    </Btn>
                  )}
                </div>
              </div>

              {/* Linha 2: Atribuido + Tags */}
              <div style={{ display: 'flex', alignItems: 'center', gap: 14, marginTop: 8, paddingTop: 8, borderTop: `1px solid ${DS.colors.border}` }}>
                {/* Atribuido */}
                <div style={{ position: 'relative' }}>
                  <button onClick={() => { setShowAssignDrop(s => !s); setShowTagsDrop(false); }}
                    style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '4px 10px', borderRadius: 999, border: `1px solid ${DS.colors.border}`, background: '#fff', cursor: 'pointer', fontSize: 11, fontWeight: 600, color: activeConv.assigned_to ? DS.colors.text : DS.colors.textSec }}>
                    <Icon name="users" size={11} color={ogColor} />
                    {activeConv.assigned_to ? (appUsers.find(u => u.id === activeConv.assigned_to)?.name || '—') : 'Atribuir'}
                    <Icon name="chevronDown" size={10} color={DS.colors.textMuted} />
                  </button>
                  {showAssignDrop && (
                    <div style={{ position: 'absolute', top: '100%', left: 0, marginTop: 4, background: '#fff', border: `1px solid ${DS.colors.border}`, borderRadius: DS.radius.sm, boxShadow: DS.shadow.lg, zIndex: 30, minWidth: 200, maxHeight: 250, overflowY: 'auto' }}>
                      <div onClick={() => assignConversation(null)}
                        style={{ padding: '8px 12px', cursor: 'pointer', fontSize: 12, color: DS.colors.textSec, borderBottom: `1px solid ${DS.colors.border}` }}
                        onMouseEnter={e => e.currentTarget.style.background = '#F8FAFC'}
                        onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
                        Ninguém
                      </div>
                      {appUsers.map(u => (
                        <div key={u.id} onClick={() => assignConversation(u.id)}
                          style={{ padding: '8px 12px', cursor: 'pointer', fontSize: 12, color: DS.colors.text, display: 'flex', alignItems: 'center', gap: 8, background: activeConv.assigned_to === u.id ? '#FFF7ED' : 'transparent' }}
                          onMouseEnter={e => { if (activeConv.assigned_to !== u.id) e.currentTarget.style.background = '#F8FAFC'; }}
                          onMouseLeave={e => { if (activeConv.assigned_to !== u.id) e.currentTarget.style.background = 'transparent'; }}>
                          <Avatar name={u.name} size={22} />
                          <span style={{ fontWeight: 600 }}>{u.name}</span>
                        </div>
                      ))}
                    </div>
                  )}
                </div>

                {/* Tags */}
                <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4, alignItems: 'center', flex: 1, position: 'relative' }}>
                  {(activeConv.tags || []).map(t => (
                    <span key={t} style={{ display: 'inline-flex', alignItems: 'center', gap: 4, padding: '2px 8px', borderRadius: 999, background: (TAG_COLORS[t] || '#64748B') + '20', color: TAG_COLORS[t] || '#475569', fontSize: 10, fontWeight: 700 }}>
                      {t}
                      <span onClick={() => toggleTag(t)} style={{ cursor: 'pointer', opacity: 0.7 }}>×</span>
                    </span>
                  ))}
                  <div style={{ position: 'relative' }}>
                    <button onClick={() => { setShowTagsDrop(s => !s); setShowAssignDrop(false); }}
                      style={{ padding: '2px 8px', borderRadius: 999, border: `1px dashed ${DS.colors.border}`, background: 'transparent', cursor: 'pointer', fontSize: 10, fontWeight: 600, color: DS.colors.textMuted }}>
                      + Etiqueta
                    </button>
                    {showTagsDrop && (
                      <div style={{ position: 'absolute', top: '100%', left: 0, marginTop: 4, background: '#fff', border: `1px solid ${DS.colors.border}`, borderRadius: DS.radius.sm, boxShadow: DS.shadow.lg, zIndex: 30, minWidth: 160, padding: 6 }}>
                        {TAG_PRESETS.map(t => {
                          const active = (activeConv.tags || []).includes(t);
                          return (
                            <div key={t} onClick={() => { toggleTag(t); }}
                              style={{ padding: '6px 10px', cursor: 'pointer', fontSize: 11, fontWeight: 600, color: TAG_COLORS[t] || DS.colors.text, borderRadius: 4, background: active ? (TAG_COLORS[t] + '20') : 'transparent' }}
                              onMouseEnter={e => { if (!active) e.currentTarget.style.background = '#F8FAFC'; }}
                              onMouseLeave={e => { if (!active) e.currentTarget.style.background = 'transparent'; }}>
                              {active ? '✓ ' : ''}{t}
                            </div>
                          );
                        })}
                      </div>
                    )}
                  </div>
                </div>
              </div>
            </div>

            {/* Lista de mensagens */}
            <div style={{ flex: 1, overflowY: 'auto', padding: '20px 24px', background: wppBg, backgroundImage: 'url("data:image/svg+xml;utf8,<svg xmlns=%27http://www.w3.org/2000/svg%27 width=%2740%27 height=%2740%27 viewBox=%270 0 40 40%27><circle cx=%274%27 cy=%274%27 r=%270.5%27 fill=%27%23a99e94%27 opacity=%270.15%27/></svg>")' }}>
              {messages.length === 0 ? (
                <div style={{ textAlign: 'center', padding: 40, color: DS.colors.textMuted, fontSize: 13 }}>
                  Sem mensagens ainda. Envie uma mensagem para começar.
                </div>
              ) : messages.map((m, i) => {
                const isOut = m.direction === 'out';
                const prevSameSide = i > 0 && messages[i - 1].direction === m.direction;
                return (
                  <div key={m.id} style={{
                    display: 'flex',
                    justifyContent: isOut ? 'flex-end' : 'flex-start',
                    marginBottom: 4,
                    marginTop: prevSameSide ? 0 : 8,
                  }}>
                    <div style={{
                      maxWidth: '70%',
                      background: isOut ? '#DCF8C6' : '#fff',
                      padding: '7px 11px 6px',
                      borderRadius: 8,
                      borderTopLeftRadius: !isOut && !prevSameSide ? 0 : 8,
                      borderTopRightRadius: isOut && !prevSameSide ? 0 : 8,
                      boxShadow: '0 1px 1px rgba(0,0,0,0.06)',
                      position: 'relative',
                      fontSize: 13.5,
                      color: '#111',
                      wordBreak: 'break-word',
                    }}>
                      {m.type === 'image' && m.media_url && (
                        <img src={m.media_url} alt="" style={{ maxWidth: '100%', borderRadius: 6, marginBottom: m.body ? 6 : 0 }} />
                      )}
                      {m.type === 'audio' && m.media_url && (
                        <audio src={m.media_url} controls style={{ maxWidth: '100%' }} />
                      )}
                      {m.type === 'document' && m.media_url && (
                        <a href={m.media_url} target="_blank" rel="noopener" style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '8px 10px', background: '#0001', borderRadius: 6, marginBottom: m.body ? 6 : 0, color: '#111', textDecoration: 'none', fontSize: 12, fontWeight: 600 }}>
                          <Icon name="briefcase" size={16} color="#075E54" />
                          <span>Documento — abrir</span>
                        </a>
                      )}
                      {m.body && <div style={{ whiteSpace: 'pre-wrap', lineHeight: 1.4 }}>{m.body}</div>}
                      <div style={{ fontSize: 10, color: '#667781', textAlign: 'right', marginTop: 3, display: 'flex', justifyContent: 'flex-end', alignItems: 'center', gap: 4 }}>
                        {new Date(m.created_at).toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit' })}
                        {isOut && (
                          <span style={{ color: m.status === 'read' ? '#34B7F1' : '#667781', fontSize: 11 }}>
                            {m.status === 'read' ? '✓✓' : m.status === 'delivered' ? '✓✓' : m.status === 'failed' ? '✕' : '✓'}
                          </span>
                        )}
                      </div>
                    </div>
                  </div>
                );
              })}
              <div ref={messagesEndRef} />
            </div>

            {/* Input de envio */}
            <div style={{ padding: '10px 14px', background: '#F8FAFC', borderTop: `1px solid ${DS.colors.border}`, display: 'flex', gap: 8, alignItems: 'flex-end', position: 'relative' }}>
              <input ref={fileInputRef} type="file" accept="image/*,audio/*,video/*,application/pdf,.doc,.docx,.xls,.xlsx" style={{ display: 'none' }} onChange={handleAttachFile} />

              {/* Dropdown de templates rapidos */}
              {showTemplates && (
                <div style={{ position: 'absolute', bottom: '100%', left: 14, marginBottom: 6, background: '#fff', border: `1px solid ${DS.colors.border}`, borderRadius: DS.radius.md, boxShadow: DS.shadow.lg, width: 360, maxWidth: '90%', zIndex: 50, overflow: 'hidden' }}>
                  <div style={{ padding: '10px 14px', borderBottom: `1px solid ${DS.colors.border}`, fontSize: 12, fontWeight: 700, color: DS.colors.textMuted, textTransform: 'uppercase', letterSpacing: '0.06em' }}>
                    Modelos de resposta
                  </div>
                  {QUICK_REPLIES.map(t => (
                    <div key={t.label} onClick={() => { setDraft(d => (d ? d + ' ' : '') + t.text); setShowTemplates(false); }}
                      style={{ padding: '10px 14px', cursor: 'pointer', borderBottom: `1px solid ${DS.colors.border}` }}
                      onMouseEnter={e => e.currentTarget.style.background = '#FFF7ED'}
                      onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
                      <div style={{ fontSize: 12, fontWeight: 700, color: ogColor, marginBottom: 2 }}>{t.label}</div>
                      <div style={{ fontSize: 12, color: DS.colors.textSec, lineHeight: 1.4 }}>{t.text}</div>
                    </div>
                  ))}
                </div>
              )}

              <button
                onClick={() => setShowTemplates(s => !s)}
                title="Modelos de resposta rápida"
                style={{ width: 38, height: 38, borderRadius: '50%', border: `1px solid ${DS.colors.border}`, background: showTemplates ? ogColor + '20' : '#fff', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0, color: showTemplates ? ogColor : DS.colors.textSec, fontSize: 18 }}>
                ⚡
              </button>
              <button
                onClick={() => fileInputRef.current?.click()}
                disabled={uploading || sending}
                title="Anexar foto, áudio ou PDF"
                style={{ width: 38, height: 38, borderRadius: '50%', border: `1px solid ${DS.colors.border}`, background: '#fff', cursor: uploading ? 'not-allowed' : 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0, color: DS.colors.textSec }}
                onMouseEnter={e => { if (!uploading) e.currentTarget.style.color = ogColor; }}
                onMouseLeave={e => e.currentTarget.style.color = DS.colors.textSec}>
                {uploading ? '⏳' : '📎'}
              </button>
              <textarea
                value={draft}
                onChange={e => setDraft(e.target.value)}
                onKeyDown={e => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSend(); } }}
                placeholder={uploading ? 'Enviando arquivo...' : 'Digite uma mensagem...'}
                rows={1}
                style={{
                  flex: 1, resize: 'none', border: `1px solid ${DS.colors.border}`, borderRadius: 20,
                  padding: '8px 16px', fontSize: 14, outline: 'none', fontFamily: 'inherit',
                  background: '#fff', color: DS.colors.text, maxHeight: 120, lineHeight: 1.4,
                }}
                disabled={sending || uploading}
              />
              <Btn icon="arrow" onClick={handleSend} disabled={!draft.trim() || sending || uploading}>
                {sending ? '...' : 'Enviar'}
              </Btn>
            </div>
          </div>

          {/* ────── PAINEL DIREITO: INFO DO CLIENTE ────── */}
          {showClientPanel && (
            <div style={{ width: 300, background: '#F8FAFC', borderLeft: `1px solid ${DS.colors.border}`, overflowY: 'auto', flexShrink: 0 }}>
              {!activeConv.client_id ? (
                <div style={{ padding: 24, textAlign: 'center', color: DS.colors.textMuted, fontSize: 13 }}>
                  <Icon name="users" size={32} color={DS.colors.border} />
                  <div style={{ marginTop: 12, fontWeight: 600, color: DS.colors.textSec }}>Contato não vinculado</div>
                  <div style={{ marginTop: 6, fontSize: 12 }}>
                    Esse número não está cadastrado no CRM. Quando você criar um cliente com esse telefone, o vínculo será automático.
                  </div>
                </div>
              ) : !clientInfo ? (
                <div style={{ padding: 24 }}><Spinner /></div>
              ) : (
                <>
                  {/* Cabeçalho do cliente */}
                  <div style={{ padding: '20px 18px', borderBottom: `1px solid ${DS.colors.border}`, textAlign: 'center', background: '#fff' }}>
                    <Avatar name={clientInfo.name} size={64} color={ogColor} />
                    <div style={{ fontSize: 15, fontWeight: 800, color: DS.colors.text, marginTop: 10 }}>{clientInfo.name}</div>
                    {clientInfo.contact && <div style={{ fontSize: 11, color: DS.colors.textSec, marginTop: 2 }}>{clientInfo.contact}</div>}
                    <div style={{ display: 'flex', gap: 6, justifyContent: 'center', marginTop: 8, flexWrap: 'wrap' }}>
                      {clientInfo.segment && <Badge variant="default">{clientInfo.segment}</Badge>}
                      {clientInfo.status && <Badge variant={clientInfo.status === 'Ativo' ? 'success' : 'warning'}>{clientInfo.status}</Badge>}
                    </div>
                  </div>

                  {/* Dados de contato */}
                  <div style={{ padding: '14px 18px', borderBottom: `1px solid ${DS.colors.border}` }}>
                    <div style={{ fontSize: 10, fontWeight: 700, color: DS.colors.textMuted, textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: 8 }}>Contato</div>
                    {clientInfo.email && <div style={{ fontSize: 12, color: DS.colors.text, marginBottom: 4, wordBreak: 'break-all' }}>📧 {clientInfo.email}</div>}
                    {clientInfo.phone && <div style={{ fontSize: 12, color: DS.colors.text, marginBottom: 4 }}>📱 {clientInfo.phone}</div>}
                    {clientInfo.city && <div style={{ fontSize: 12, color: DS.colors.text, marginBottom: 4 }}>📍 {clientInfo.city}</div>}
                    {clientInfo.cnpj && <div style={{ fontSize: 12, color: DS.colors.text }}>🏢 {clientInfo.cnpj}</div>}
                  </div>

                  {/* Eventos */}
                  <div style={{ padding: '14px 18px', borderBottom: `1px solid ${DS.colors.border}` }}>
                    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 8 }}>
                      <div style={{ fontSize: 10, fontWeight: 700, color: DS.colors.textMuted, textTransform: 'uppercase', letterSpacing: '0.06em' }}>
                        Eventos ({clientEvents.length})
                      </div>
                      {onNavigate && <span onClick={() => onNavigate('events')} style={{ fontSize: 10, color: ogColor, cursor: 'pointer', fontWeight: 700 }}>VER TODOS</span>}
                    </div>
                    {clientEvents.length === 0 ? (
                      <div style={{ fontSize: 11, color: DS.colors.textMuted }}>Sem eventos</div>
                    ) : clientEvents.map(e => (
                      <div key={e.id} style={{ padding: '8px 0', borderBottom: `1px solid ${DS.colors.border}` }}>
                        <div style={{ fontSize: 12, fontWeight: 600, color: DS.colors.text }}>{e.name}</div>
                        <div style={{ fontSize: 10, color: DS.colors.textSec, marginTop: 2 }}>
                          {e.event_date && new Date(e.event_date + 'T00:00:00').toLocaleDateString('pt-BR')} · {e.type} · {e.status}
                        </div>
                      </div>
                    ))}
                  </div>

                  {/* Orçamentos */}
                  <div style={{ padding: '14px 18px' }}>
                    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 8 }}>
                      <div style={{ fontSize: 10, fontWeight: 700, color: DS.colors.textMuted, textTransform: 'uppercase', letterSpacing: '0.06em' }}>
                        Orçamentos ({clientBudgets.length})
                      </div>
                      {onNavigate && <span onClick={() => onNavigate('budgets')} style={{ fontSize: 10, color: ogColor, cursor: 'pointer', fontWeight: 700 }}>VER TODOS</span>}
                    </div>
                    {clientBudgets.length === 0 ? (
                      <div style={{ fontSize: 11, color: DS.colors.textMuted }}>Sem orçamentos</div>
                    ) : clientBudgets.map(b => (
                      <div key={b.id} style={{ padding: '8px 0', borderBottom: `1px solid ${DS.colors.border}` }}>
                        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
                          <div style={{ fontSize: 12, fontWeight: 700, color: DS.colors.primary }}>{b.code}</div>
                          {canSeeFinancials && canSeeFinancials(currentUser) && b.value > 0 && (
                            <div style={{ fontSize: 11, fontWeight: 700, color: DS.colors.text }}>R$ {(b.value || 0).toLocaleString('pt-BR')}</div>
                          )}
                        </div>
                        <div style={{ fontSize: 11, color: DS.colors.textSec, marginTop: 2 }}>{b.event_name}</div>
                        <div style={{ fontSize: 10, color: DS.colors.textMuted, marginTop: 2 }}>{b.issued_date} · {b.status}</div>
                      </div>
                    ))}
                  </div>
                </>
              )}
            </div>
          )}
          </div>
        )}
      </div>

      {newConvModal && (
        <NewConversationModal
          onClose={() => setNewConvModal(false)}
          onCreated={conv => {
            setConversations(prev => prev.some(c => c.id === conv.id) ? prev : [conv, ...prev]);
            setActiveConv(conv);
            setNewConvModal(false);
          }}
          showToast={showToast}
        />
      )}

      {toast && <Toast message={toast.msg} type={toast.type} onClose={() => setToast(null)} />}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Modal "Nova conversa" — busca cliente do CRM ou digita numero
// ─────────────────────────────────────────────────────────────
function NewConversationModal({ onClose, onCreated, showToast }) {
  const [tab, setTab] = React.useState('crm'); // 'crm' | 'manual'
  const [clients, setClients] = React.useState([]);
  const [search, setSearch] = React.useState('');
  const [phone, setPhone] = React.useState('');
  const [name, setName] = React.useState('');
  const [creating, setCreating] = React.useState(false);

  React.useEffect(() => {
    sb.from('clients').select('id, name, phone, contact').not('phone', 'is', null).order('name').limit(200).then(({ data }) => {
      setClients(data || []);
    });
  }, []);

  const filteredClients = React.useMemo(() => {
    const q = search.trim().toLowerCase();
    if (!q) return clients;
    return clients.filter(c =>
      (c.name || '').toLowerCase().includes(q) ||
      (c.contact || '').toLowerCase().includes(q) ||
      (c.phone || '').includes(q)
    );
  }, [clients, search]);

  const openOrCreate = async (clientPhone, clientName, clientId = null) => {
    const phoneNorm = normalizePhoneForZapi(clientPhone);
    if (phoneNorm.length < 12) {
      showToast('Telefone inválido. Use DDD + número.', 'error');
      return;
    }
    setCreating(true);
    // Se ja existe conversa, abre ela
    const { data: existing } = await sb.from('whatsapp_conversations').select('*').eq('phone', phoneNorm).maybeSingle();
    if (existing) {
      onCreated(existing);
      setCreating(false);
      return;
    }
    // Cria nova
    const { data: created, error } = await sb.from('whatsapp_conversations').insert({
      phone: phoneNorm,
      contact_name: clientName || phoneNorm,
      client_id: clientId,
      last_message_at: new Date().toISOString(),
      last_message_preview: '(conversa iniciada)',
      status: 'open',
    }).select().single();
    setCreating(false);
    if (error) {
      showToast('Erro ao criar conversa: ' + error.message, 'error');
      return;
    }
    showToast('Conversa criada — pode enviar a primeira mensagem!');
    onCreated(created);
  };

  return (
    <Modal open={true} onClose={onClose} title="Nova conversa" width={520}>
      <div style={{ display: 'flex', gap: 4, marginBottom: 16, background: '#F1F5F9', padding: 4, borderRadius: DS.radius.sm }}>
        {[['crm', '🔍 Buscar no CRM'], ['manual', '📞 Digitar número']].map(([v, l]) => (
          <button key={v} onClick={() => setTab(v)} style={{
            flex: 1, padding: '8px 14px', borderRadius: 6, border: 'none', fontSize: 13, fontWeight: 600, cursor: 'pointer',
            background: tab === v ? '#fff' : 'transparent',
            color: tab === v ? DS.colors.text : DS.colors.textSec,
            boxShadow: tab === v ? DS.shadow.sm : 'none',
          }}>{l}</button>
        ))}
      </div>

      {tab === 'crm' ? (
        <div>
          <input
            value={search}
            onChange={e => setSearch(e.target.value)}
            placeholder="Buscar por nome, contato ou telefone..."
            autoFocus
            style={{ width: '100%', boxSizing: 'border-box', padding: '10px 14px', fontSize: 13, border: `1px solid ${DS.colors.border}`, borderRadius: DS.radius.sm, outline: 'none', marginBottom: 12, fontFamily: 'inherit' }}
          />
          <div style={{ maxHeight: 320, overflowY: 'auto', border: `1px solid ${DS.colors.border}`, borderRadius: DS.radius.sm }}>
            {filteredClients.length === 0 ? (
              <div style={{ padding: 24, textAlign: 'center', color: DS.colors.textMuted, fontSize: 13 }}>
                Nenhum cliente encontrado
              </div>
            ) : filteredClients.map(c => (
              <div key={c.id} onClick={() => !creating && openOrCreate(c.phone, c.name, c.id)}
                style={{ padding: '10px 14px', borderBottom: `1px solid ${DS.colors.border}`, cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 10 }}
                onMouseEnter={e => e.currentTarget.style.background = '#F8FAFC'}
                onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
                <Avatar name={c.name} size={32} />
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 13, fontWeight: 600, color: DS.colors.text, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{c.name}</div>
                  <div style={{ fontSize: 11, color: DS.colors.textSec }}>{c.contact || c.phone}</div>
                </div>
                <Icon name="arrow" size={14} color={DS.colors.textMuted} />
              </div>
            ))}
          </div>
        </div>
      ) : (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
          <Input label="Telefone (com DDD)" value={phone} onChange={setPhone} placeholder="(85) 99998-0363" autoFocus />
          <Input label="Nome do contato (opcional)" value={name} onChange={setName} placeholder="Ex: João Silva" />
          <div style={{ fontSize: 11, color: DS.colors.textMuted, lineHeight: 1.5 }}>
            Use o formato (DDD) número. O sistema adiciona o código do país automaticamente.
          </div>
          <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end', marginTop: 4 }}>
            <Btn variant="secondary" onClick={onClose}>Cancelar</Btn>
            <Btn onClick={() => openOrCreate(phone, name)} disabled={creating || !phone.trim()}>
              {creating ? 'Criando…' : 'Iniciar conversa'}
            </Btn>
          </div>
        </div>
      )}
    </Modal>
  );
}

Object.assign(window, { WhatsApp });
