/* CRM — caixa de entrada operacional. */

const {
  crmInboxAppointmentDate,
  crmInboxPhone,
  crmInboxContactName,
  crmInboxInitials,
  crmInboxStatusLabels,
  crmInboxRoleLabels,
  crmInboxArrangeMessages,
  crmInboxReplyPreview,
  CrmConversationItem,
  CrmKanbanCard,
  CrmMessageBubble,
  CrmNewConversationModal,
} = window.CrmInboxParts;

function crmInboxFriendlyError(error, fallback) {
  const status = Number(error && error.status);
  const raw = String((error && error.message) || '');
  if (status === 403) {
    return 'Você não tem permissão para realizar esta ação.';
  }
  if (/24 horas|modelo aprovado/i.test(raw)) {
    return 'Para enviar uma mensagem livre, o cliente precisa ter iniciado a conversa nas últimas 24 horas. Fora desse período, use uma mensagem previamente aprovada.';
  }
  if (/Aguarde um minuto/i.test(raw)) {
    return 'Aguarde um minuto antes de enviar novas mensagens.';
  }
  if (/telefone|número/i.test(raw) && /DDD|país|válid|inválid/i.test(raw)) {
    return 'Confira o número do WhatsApp, incluindo país e DDD.';
  }
  if (/Áudios não aceitam legenda|nome do atendente|Digite uma mensagem/i.test(raw)) {
    return raw;
  }
  if (/Meta|modelo|arquivo|mídia|cabeçalho|destinatário|autorização do canal/i.test(raw)) {
    return raw;
  }
  return fallback;
}

function CrmInboxScreen({ user }) {
  const [payload, setPayload] = React.useState(null);
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState('');
  const [notice, setNotice] = React.useState('');
  const [channelBusy, setChannelBusy] = React.useState('');
  const [settingsOpen, setSettingsOpen] = React.useState(false);
  const [accessOpen, setAccessOpen] = React.useState(false);
  const [settingsView, setSettingsView] = React.useState(false);
  const [busyUserId, setBusyUserId] = React.useState(0);
  const [savedUserId, setSavedUserId] = React.useState(0);

  const [conversations, setConversations] = React.useState([]);
  const [counts, setCounts] = React.useState({ all: 0, open: 0, pending: 0, resolved: 0, unread: 0, awaiting: 0 });
  const [conversationLoading, setConversationLoading] = React.useState(false);
  const [filter, setFilter] = React.useState('all');
  const [assignedFilter, setAssignedFilter] = React.useState('all');
  const [search, setSearch] = React.useState('');
  const [selectedId, setSelectedId] = React.useState(0);
  const [selectedConversation, setSelectedConversation] = React.useState(null);
  const [messages, setMessages] = React.useState([]);
  const [threadLoading, setThreadLoading] = React.useState(false);
  const [conversationBusy, setConversationBusy] = React.useState(false);
  const [messageBody, setMessageBody] = React.useState('');
  const [messageBusy, setMessageBusy] = React.useState(false);
  const [attachment, setAttachment] = React.useState(null);
  const [replyingTo, setReplyingTo] = React.useState(null);
  const [senderEditorOpen, setSenderEditorOpen] = React.useState(false);
  const [senderNameDraft, setSenderNameDraft] = React.useState('');
  const [senderIdentityBusy, setSenderIdentityBusy] = React.useState(false);
  const [contextOpen, setContextOpen] = React.useState(false);
  const [inboxView, setInboxView] = React.useState(() => window.localStorage.getItem('crmInboxView') === 'board' ? 'board' : 'list');
  const [boardBusyId, setBoardBusyId] = React.useState(0);
  const [boardDragId, setBoardDragId] = React.useState(0);
  const [boardDropStatus, setBoardDropStatus] = React.useState('');
  const messageViewportRef = React.useRef(null);
  const attachmentInputRef = React.useRef(null);
  const messageSendingRef = React.useRef(false);

  const [newConversationOpen, setNewConversationOpen] = React.useState(false);
  const [contactQuery, setContactQuery] = React.useState('');
  const [contacts, setContacts] = React.useState([]);
  const [contactsLoading, setContactsLoading] = React.useState(false);
  const [newPhone, setNewPhone] = React.useState('');
  const [newBusy, setNewBusy] = React.useState(false);
  const [newConversationError, setNewConversationError] = React.useState('');
  const [templates, setTemplates] = React.useState([]);
  const [templatesLoading, setTemplatesLoading] = React.useState(false);
  const [templateKey, setTemplateKey] = React.useState('');
  const [templateParameters, setTemplateParameters] = React.useState({});
  const [templateMedia, setTemplateMedia] = React.useState(null);

  React.useEffect(() => {
    const navigate = (event) => {
      const target = String((event.detail && event.detail.target) || 'inbox');
      if (target === 'settings' || target === 'team' || target === 'channel') {
        setSettingsView(true);
        setSettingsOpen(target === 'settings' || target === 'channel');
        setAccessOpen(target === 'settings' || target === 'team');
        const selector = target === 'team' ? '.crm-access-collapsible' : '.crm-channel-settings';
        window.setTimeout(() => document.querySelector(selector)?.scrollIntoView({ behavior: 'smooth', block: 'start' }), 0);
        return;
      }
      setSettingsView(false);
      setSettingsOpen(false);
      if (target === 'contacts') {
        setContactQuery('');
        setNewPhone('');
        setNewConversationOpen(true);
        return;
      }
      window.setTimeout(() => document.querySelector('.crm-inbox-shell')?.scrollIntoView({ behavior: 'smooth', block: 'start' }), 0);
    };
    window.addEventListener('crm:navigate', navigate);
    return () => window.removeEventListener('crm:navigate', navigate);
  }, []);

  const crm = (payload && payload.crm) || {};
  const senderIdentity = crm.senderIdentity || {};
  const senderDisplayName = senderIdentity.displayName || user.crmDisplayName || user.name || user.login || 'Atendimento';
  const messageMaxLength = Math.max(1, (attachment ? 1024 : 4096) - String(senderDisplayName).length - 4);
  const access = crm.access || user.crmAccess || {};
  const users = (payload && payload.users) || [];
  const assignees = (payload && payload.assignees) || [];
  const whatsapp = payload && payload.channels && payload.channels.whatsapp;
  const whatsappConnected = !!(whatsapp && whatsapp.status === 'connected');
  const whatsappCoexistence = whatsappConnected && whatsapp.keepsMobileNumber === true;
  const channelSetupReady = !!crm.channelsReady;
  const connectionId = Number(whatsapp ? whatsapp.id : 0);
  const enabledUsersCount = users.filter((item) => item.crmEnabled).length;
  const arrangedMessages = React.useMemo(() => crmInboxArrangeMessages(messages), [messages]);
  const messagesByProviderId = React.useMemo(() => {
    const index = new Map();
    messages.forEach((message) => {
      if (message.providerMessageId) index.set(message.providerMessageId, message);
    });
    return index;
  }, [messages]);
  const boardColumns = React.useMemo(() => {
    const columns = { awaiting: [], open: [], pending: [], resolved: [] };
    conversations.forEach((conversation) => {
      if (conversation.lastMessageDirection === 'inbound') columns.awaiting.push(conversation);
      else if (conversation.status === 'resolved') columns.resolved.push(conversation);
      else if (conversation.status === 'pending') columns.pending.push(conversation);
      else columns.open.push(conversation);
    });
    return columns;
  }, [conversations]);

  const loadStatus = React.useCallback(async () => {
    setLoading(true);
    setError('');
    try {
      setPayload(await window.API.crm.status());
    } catch (err) {
      setError(crmInboxFriendlyError(err, 'Não foi possível carregar o CRM.'));
    } finally {
      setLoading(false);
    }
  }, []);

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

  const loadConversations = React.useCallback(async (silent = false) => {
    if (!connectionId || !whatsappConnected) {
      setConversations([]);
      setCounts({ all: 0, open: 0, pending: 0, resolved: 0, unread: 0, awaiting: 0 });
      return;
    }
    if (!silent) setConversationLoading(true);
    try {
      const result = await window.API.crm.conversations({
        status: inboxView === 'board' || filter === 'unread' ? 'all' : filter,
        q: search.trim(),
        unread: inboxView !== 'board' && filter === 'unread',
        assigned: assignedFilter,
        limit: 150,
      });
      setConversations(result.conversations || []);
      setCounts(result.counts || { all: 0, open: 0, pending: 0, resolved: 0, unread: 0, awaiting: 0 });
    } catch (err) {
      if (!silent) setError(crmInboxFriendlyError(err, 'Não foi possível carregar as conversas.'));
    } finally {
      if (!silent) setConversationLoading(false);
    }
  }, [connectionId, whatsappConnected, filter, search, assignedFilter, inboxView]);

  const loadConversation = React.useCallback(async (conversationId, markRead = false, silent = false) => {
    if (!conversationId) return;
    if (!silent) setThreadLoading(true);
    try {
      const result = await window.API.crm.conversation(conversationId, 250);
      let conversation = result.conversation || null;
      setMessages(result.messages || []);
      if (markRead && conversation && conversation.unreadCount > 0) {
        const updated = await window.API.crm.updateConversation(conversationId, { markRead: true });
        conversation = updated.conversation || conversation;
        setConversations((current) => current.map((item) => item.id === conversationId
          ? { ...item, unreadCount: 0 }
          : item));
        setCounts((current) => ({ ...current, unread: Math.max(0, current.unread - 1) }));
      }
      setSelectedConversation(conversation);
    } catch (err) {
      if (Number(err && err.status) === 404) {
        setSelectedId((current) => current === Number(conversationId) ? 0 : current);
        setSelectedConversation(null);
        setMessages([]);
        setConversations((current) => current.filter((item) => Number(item.id) !== Number(conversationId)));
        return;
      }
      if (!silent) setError(crmInboxFriendlyError(err, 'Não foi possível abrir a conversa.'));
    } finally {
      if (!silent) setThreadLoading(false);
    }
  }, []);

  React.useEffect(() => {
    if (!whatsappConnected) return undefined;
    const timer = window.setTimeout(() => loadConversations(), search.trim() ? 260 : 0);
    return () => window.clearTimeout(timer);
  }, [whatsappConnected, loadConversations]);

  React.useEffect(() => {
    if (inboxView === 'board' || selectedId || conversations.length === 0) return;
    if (!window.matchMedia || window.matchMedia('(min-width: 721px)').matches) {
      const firstId = Number(conversations[0].id);
      setSelectedId(firstId);
      loadConversation(firstId, true);
    }
  }, [conversations, selectedId, loadConversation, inboxView]);

  React.useEffect(() => {
    if (!whatsappConnected) return undefined;
    const timer = window.setInterval(() => {
      loadConversations(true);
      if (selectedId) loadConversation(selectedId, true, true);
    }, 5000);
    return () => window.clearInterval(timer);
  }, [whatsappConnected, selectedId, loadConversations, loadConversation]);

  React.useEffect(() => {
    const viewport = messageViewportRef.current;
    if (viewport) {
      viewport.scrollTop = viewport.scrollHeight;
    }
  }, [messages.length, selectedId]);

  React.useEffect(() => {
    if (!newConversationOpen) return undefined;
    const timer = window.setTimeout(async () => {
      setContactsLoading(true);
      try {
        const result = await window.API.crm.contacts(contactQuery, 30);
        setContacts(result.contacts || []);
      } catch (err) {
        setError(crmInboxFriendlyError(err, 'Não foi possível buscar os clientes.'));
      } finally {
        setContactsLoading(false);
      }
    }, contactQuery.trim() ? 240 : 0);
    return () => window.clearTimeout(timer);
  }, [newConversationOpen, contactQuery]);

  React.useEffect(() => {
    if (!newConversationOpen) return undefined;
    let active = true;
    setTemplatesLoading(true);
    window.API.crm.messageTemplates()
      .then((result) => { if (active) setTemplates(result.templates || []); })
      .catch((err) => {
        if (active) setError(crmInboxFriendlyError(err, 'Não foi possível carregar os modelos aprovados da Meta.'));
      })
      .finally(() => { if (active) setTemplatesLoading(false); });
    return () => { active = false; };
  }, [newConversationOpen]);

  const chooseConversation = (conversationId) => {
    setReplyingTo(null);
    setSelectedId(conversationId);
    setSelectedConversation(null);
    setMessages([]);
    loadConversation(conversationId, true);
  };

  const changeInboxView = (view) => {
    const nextView = view === 'board' ? 'board' : 'list';
    setInboxView(nextView);
    window.localStorage.setItem('crmInboxView', nextView);
    if (nextView === 'board') {
      setReplyingTo(null);
      setSelectedId(0);
      setSelectedConversation(null);
      setMessages([]);
      setContextOpen(false);
    }
  };

  const openBoardConversation = (conversationId) => {
    changeInboxView('list');
    chooseConversation(conversationId);
  };

  const moveBoardConversation = async (conversationId, status) => {
    if (!['open', 'pending', 'resolved'].includes(status) || boardBusyId) return;
    const previous = conversations;
    setBoardBusyId(conversationId);
    setError('');
    setConversations((current) => current.map((item) => Number(item.id) === Number(conversationId)
      ? { ...item, status, unreadCount: status === 'open' ? 0 : item.unreadCount }
      : item));
    try {
      await window.API.crm.updateConversation(conversationId, {
        status,
        markRead: status === 'open',
      });
      setNotice(status === 'resolved'
        ? 'Conversa concluída.'
        : status === 'pending' ? 'Conversa movida para pendentes.' : 'Conversa em atendimento.');
      await loadConversations(true);
    } catch (err) {
      setConversations(previous);
      setError(crmInboxFriendlyError(err, 'Não foi possível mover a conversa.'));
    } finally {
      setBoardBusyId(0);
      setBoardDragId(0);
      setBoardDropStatus('');
    }
  };

  const updateConversation = async (data, successMessage = '') => {
    if (!selectedId) return;
    setConversationBusy(true);
    setError('');
    try {
      const result = await window.API.crm.updateConversation(selectedId, data);
      const updated = result.conversation;
      setSelectedConversation(updated);
      setConversations((current) => current.map((item) => item.id === selectedId
        ? { ...item, ...updated }
        : item));
      if (successMessage) setNotice(successMessage);
      loadConversations(true);
    } catch (err) {
      setError(crmInboxFriendlyError(err, 'Não foi possível atualizar a conversa.'));
    } finally {
      setConversationBusy(false);
    }
  };

  const sendMessage = async (event) => {
    event.preventDefault();
    if (messageSendingRef.current || !selectedId || (!messageBody.trim() && !attachment)) return;
    const submittedBody = messageBody;
    const submittedAttachment = attachment;
    const submittedReply = replyingTo;
    messageSendingRef.current = true;
    setMessageBusy(true);
    setMessageBody('');
    setAttachment(null);
    setReplyingTo(null);
    if (attachmentInputRef.current) attachmentInputRef.current.value = '';
    setError('');
    setNotice('');
    try {
      const result = submittedAttachment
        ? await window.API.crm.sendMedia(
          selectedId,
          submittedAttachment,
          submittedBody,
          submittedReply ? submittedReply.providerMessageId : ''
        )
        : await window.API.crm.sendMessage(
          '',
          submittedBody,
          selectedId,
          submittedReply ? submittedReply.providerMessageId : ''
        );
      if (result.message) {
        setMessages((current) => [
          ...current.filter((item) => item.id !== result.message.id),
          result.message,
        ]);
      }
      if (result.conversation) setSelectedConversation(result.conversation);
      loadConversations(true);
      window.setTimeout(() => loadConversation(selectedId, true, true), 1200);
    } catch (err) {
      const rejectedBeforeSend = Number(err && err.status) >= 400 && Number(err && err.status) < 500;
      if (rejectedBeforeSend) {
        setMessageBody((current) => current || submittedBody);
        setAttachment((current) => current || submittedAttachment);
        setReplyingTo((current) => current || submittedReply);
        setError(crmInboxFriendlyError(err, 'Não foi possível enviar a mensagem.'));
      } else {
        // Em timeout/erro 5xx a Meta pode já ter aceitado a mensagem. O campo
        // permanece vazio para impedir um segundo envio acidental.
        setMessageBody('');
        setAttachment(null);
        setReplyingTo(null);
        setError('Não foi possível confirmar a atualização da tela. Verifique o histórico antes de tentar novamente.');
        window.setTimeout(() => loadConversation(selectedId, true, true), 900);
      }
    } finally {
      messageSendingRef.current = false;
      setMessageBusy(false);
    }
  };

  const saveSenderIdentity = async () => {
    if (senderIdentityBusy) return;
    setSenderIdentityBusy(true);
    setError('');
    try {
      const result = await window.API.crm.setSenderIdentity(senderNameDraft);
      setPayload((current) => ({
        ...(current || {}),
        crm: {
          ...((current && current.crm) || {}),
          senderIdentity: result.senderIdentity,
        },
      }));
      setSenderEditorOpen(false);
      setNotice(`As mensagens serão identificadas como ${result.senderIdentity.displayName}.`);
    } catch (err) {
      setError(crmInboxFriendlyError(err, 'Não foi possível alterar o nome do atendimento.'));
    } finally {
      setSenderIdentityBusy(false);
    }
  };

  const sendNewConversation = async () => {
    if (!newPhone.trim() || !templateKey) return;
    setNewBusy(true);
    setError('');
    setNewConversationError('');
    try {
      const separator = templateKey.lastIndexOf('|');
      const result = await window.API.crm.sendTemplate(
        newPhone,
        templateKey.slice(0, separator),
        templateKey.slice(separator + 1),
        templateParameters,
        templateMedia
      );
      const conversationId = Number(
        (result.conversation && result.conversation.id)
        || (result.message && result.message.conversationId)
        || 0
      );
      setNewConversationOpen(false);
      setContactQuery('');
      setContacts([]);
      setNewPhone('');
      setTemplateKey('');
      setTemplateParameters({});
      setTemplateMedia(null);
      await loadConversations(true);
      if (conversationId) {
        setSelectedId(conversationId);
        await loadConversation(conversationId, true);
      }
    } catch (err) {
      const friendlyError = crmInboxFriendlyError(err, 'Não foi possível iniciar a conversa.');
      setNewConversationError(friendlyError);
    } finally {
      setNewBusy(false);
    }
  };

  const connectWhatsApp = async () => {
    let signupWaiter = null;
    setChannelBusy('connect');
    setError('');
    setNotice('');
    try {
      const start = await window.API.crm.startOnboarding('whatsapp');
      const publicMeta = start.meta || {};
      const onboarding = start.onboarding || {};
      const featureType = String(publicMeta.embeddedSignupFeatureType || '');
      if (
        publicMeta.keepsMobileNumber !== true
        || onboarding.keepsMobileNumber !== true
        || onboarding.featureType !== featureType
        || featureType !== 'whatsapp_business_app_onboarding'
      ) {
        throw new Error('Não foi possível iniciar a conexão.');
      }
      const FB = await window.loadCrmMetaSdk(publicMeta.appId, publicMeta.graphVersion);
      signupWaiter = window.createEmbeddedSignupWaiter();
      const code = await new Promise((resolve, reject) => {
        FB.login((response) => {
          const authCode = response && response.authResponse && response.authResponse.code;
          if (authCode) resolve(String(authCode));
          else reject(new Error('Não foi possível autorizar a conexão.'));
        }, {
          config_id: String(publicMeta.configId),
          response_type: 'code',
          override_default_response_type: true,
          extras: {
            setup: {},
            featureType,
            sessionInfoVersion: '3',
          },
        });
      });
      const session = await signupWaiter.promise;
      if (!session) throw new Error('A conexão foi interrompida.');
      const result = await window.API.crm.completeOnboarding({
        state: onboarding.state || '',
        code,
        ...session,
      });
      setPayload((current) => ({
        ...(current || {}),
        channels: { ...((current && current.channels) || {}), whatsapp: result.connection },
      }));
      setNotice('WhatsApp conectado. O número continua disponível no celular e também pode ser atendido pelo CRM.');
      setSettingsOpen(false);
    } catch (err) {
      if (signupWaiter) signupWaiter.cancel();
      setError(crmInboxFriendlyError(err, 'Não foi possível conectar o WhatsApp. Tente novamente ou entre em contato com o suporte.'));
    } finally {
      setChannelBusy('');
    }
  };

  const verifyWhatsApp = async () => {
    setChannelBusy('verify');
    setError('');
    setNotice('');
    try {
      const result = await window.API.crm.verifyChannel();
      setPayload((current) => ({
        ...(current || {}),
        channels: { ...((current && current.channels) || {}), whatsapp: result.connection },
      }));
      setNotice('Conexão verificada com sucesso.');
    } catch (err) {
      setError(crmInboxFriendlyError(err, 'Não foi possível verificar a conexão. Tente novamente.'));
    } finally {
      setChannelBusy('');
    }
  };

  const disconnectWhatsApp = async () => {
    const question = whatsappCoexistence
      ? 'Desconectar este número do CRM? Ele continuará disponível no WhatsApp Business do celular.'
      : 'Desconectar este número do CRM?';
    if (!window.confirm(question)) return;
    setChannelBusy('disconnect');
    setError('');
    try {
      const result = await window.API.crm.disconnectChannel();
      setPayload((current) => ({
        ...(current || {}),
        channels: { ...((current && current.channels) || {}), whatsapp: result.connection },
      }));
      setSelectedId(0);
      setSelectedConversation(null);
      setMessages([]);
      setNotice('Canal desconectado do CRM.');
    } catch (err) {
      setError(crmInboxFriendlyError(err, 'Não foi possível desconectar o WhatsApp. Tente novamente.'));
    } finally {
      setChannelBusy('');
    }
  };

  const updateAccess = async (targetUserId, role) => {
    setBusyUserId(targetUserId);
    setSavedUserId(0);
    setError('');
    try {
      const result = await window.API.crm.setUserAccess(targetUserId, role);
      const nextUsers = result.users || [];
      setPayload((current) => ({
        ...(current || {}),
        users: nextUsers,
        assignees: nextUsers
          .filter((item) => item.crmEnabled && item.status === 'ativo')
          .map((item) => ({
            id: item.id,
            name: item.name || item.login,
            role: item.crmRole,
          })),
      }));
      setSavedUserId(targetUserId);
      window.setTimeout(() => setSavedUserId((current) => current === targetUserId ? 0 : current), 1800);
    } catch (err) {
      setError(crmInboxFriendlyError(err, 'Não foi possível alterar o acesso.'));
    } finally {
      setBusyUserId(0);
    }
  };

  if (loading) {
    return (
      <div className="content-inner fadein">
        <div className="card card-pad"><div className="muted">Carregando caixa de entrada…</div></div>
      </div>
    );
  }

  if (error && !payload) {
    return (
      <div className="content-inner fadein">
        <div className="card card-pad">
          <window.Empty icon="info" title="CRM indisponível" desc={error} />
          <div className="row" style={{ justifyContent: 'center', marginTop: 16 }}>
            <window.Button variant="outline" icon="refresh" onClick={loadStatus}>Tentar novamente</window.Button>
          </div>
        </div>
      </div>
    );
  }

  const currentConversation = selectedConversation
    || conversations.find((item) => item.id === selectedId)
    || null;
  const currentClient = currentConversation && currentConversation.client;
  const currentContactName = crmInboxContactName(currentConversation);
  const roleLabel = crmInboxRoleLabels[access.role] || 'Atendente';
  const moduleStatusLabel = {
    trialing: 'Período de teste',
    active: 'Ativo',
    grace: 'Período de carência',
  }[crm.status] || 'Ativo';
  const filterItems = [
    ['all', 'Todas', counts.all],
    ['awaiting', 'Aguardando resposta', counts.awaiting],
    ['open', 'Em atendimento', counts.open],
    ['unread', 'Não lidas', counts.unread],
    ['pending', 'Pendentes', counts.pending],
    ['resolved', 'Resolvidas', counts.resolved],
  ];

  return (
    <div className="content-inner fadein crm-inbox-page">
      {error && <div className="alert danger" role="alert">{error}</div>}
      {notice && <div className="alert success" role="status">{notice}</div>}

      {settingsView && (
        <section className="crm-settings-view">
          <div className="crm-settings-heading">
            <div>
              <div className="crm-eyebrow">Administração</div>
              <h2>Configurações do CRM</h2>
              <p>Gerencie o canal oficial e quem pode atender conversas.</p>
            </div>
            <window.Button variant="outline" icon="chevLeft" onClick={() => {
              setSettingsView(false);
              setSettingsOpen(false);
              window.dispatchEvent(new CustomEvent('crm:section-changed', { detail: { target: 'inbox' } }));
            }}>Voltar à caixa de entrada</window.Button>
          </div>
        </section>
      )}

      {!settingsView && <section className="crm-channel-summary" aria-label="Situação do canal">
        <div className={`crm-channel-summary-dot${whatsappConnected ? ' connected' : ''}`} aria-hidden="true"></div>
        <div className="crm-channel-summary-copy">
          <strong>{whatsappConnected ? 'WhatsApp oficial conectado' : 'WhatsApp oficial não conectado'}</strong>
          <span>
            {whatsappConnected
              ? `${whatsapp.displayName || 'Conta verificada'} · ${whatsapp.displayPhoneNumber || 'Número conectado'}`
              : 'Conecte um número para receber e responder conversas no CRM.'}
          </span>
        </div>
        <div className="crm-channel-summary-tags">
          {whatsappCoexistence && <span className="pill ok">Celular + CRM</span>}
          <span className="pill plain">{moduleStatusLabel} · {roleLabel}</span>
        </div>
        <div className="crm-channel-summary-actions">
          {whatsappConnected && (
            <window.Button
              variant="outline"
              size="sm"
              icon="refresh"
              onClick={() => {
                loadConversations();
                if (selectedId) loadConversation(selectedId, true);
              }}
              disabled={conversationLoading || threadLoading}
            >
              Atualizar
            </window.Button>
          )}
        </div>
      </section>}

      {settingsView && settingsOpen && access.manageChannels && (
        <section className="card card-pad crm-channel-settings">
          <div className="crm-section-head">
            <div>
              <h3>Canal do WhatsApp</h3>
              <p>Gerencie o número usado para receber e responder conversas.</p>
            </div>
            <span className={`pill ${whatsappConnected ? 'ok' : 'seg'}`}>
              {whatsappConnected ? 'Conectado' : 'Não conectado'}
            </span>
          </div>
          <div className="crm-channel-settings-grid">
            <div>
              <strong>WhatsApp Business</strong>
              <span>
                {whatsappConnected
                  ? `${whatsapp.displayName || 'Conta verificada'} · ${whatsapp.displayPhoneNumber || 'Número conectado'}`
                  : 'Use o mesmo número no aplicativo e no CRM.'}
              </span>
            </div>
            <div className="row wrap">
              {whatsappConnected ? (
                <>
                  <window.Button variant="outline" onClick={verifyWhatsApp} disabled={!!channelBusy}>
                    {channelBusy === 'verify' ? 'Verificando…' : 'Verificar'}
                  </window.Button>
                  <window.Button variant="outline" onClick={disconnectWhatsApp} disabled={!!channelBusy}>
                    {channelBusy === 'disconnect' ? 'Desconectando…' : 'Desconectar'}
                  </window.Button>
                </>
              ) : (
                <window.Button onClick={connectWhatsApp} disabled={!channelSetupReady || !!channelBusy}>
                  {channelBusy === 'connect' ? 'Abrindo conexão…' : 'Conectar WhatsApp'}
                </window.Button>
              )}
            </div>
          </div>
          {!channelSetupReady && (
            <div className="crm-channel-settings-note">
              A conexão do WhatsApp está temporariamente indisponível. Entre em contato com o suporte.
            </div>
          )}
          {whatsapp && whatsapp.status === 'error' && (
            <div className="crm-channel-error">
              Não foi possível manter a conexão. Verifique novamente ou entre em contato com o suporte.
            </div>
          )}
        </section>
      )}

      {!settingsView && (whatsappConnected ? (
        <section className="crm-inbox-shell">
          <header className="crm-inbox-toolbar">
            <div>
              <div className="crm-eyebrow">Atendimento</div>
              <h2>Caixa de entrada</h2>
            </div>
            <window.Button icon="plus" onClick={() => setNewConversationOpen(true)}>
              Nova conversa
            </window.Button>
          </header>

          <div className="crm-inbox-filters" role="tablist" aria-label="Filtrar conversas">
            {filterItems.map(([value, label, count]) => (
              <button
                type="button"
                role="tab"
                aria-selected={filter === value}
                className={filter === value ? 'active' : ''}
                key={value}
                onClick={() => setFilter(value)}
              >
                {label}
                <span>{count}</span>
              </button>
            ))}
          </div>

          {inboxView === 'board' ? (
            <div className="crm-kanban-view">
              <header className="crm-kanban-head">
                <div className="crm-kanban-title">
                  <span className="crm-channel-summary-dot connected" aria-hidden="true"></span>
                  <div><strong>Quadro de atendimentos</strong><small>Arraste os cartões para atualizar a situação</small></div>
                </div>
                <div className="crm-kanban-tools">
                  <div className="crm-kanban-search">
                    <window.Icon name="search" size={15} />
                    <window.Input
                      value={search}
                      placeholder="Buscar atendimento"
                      onChange={(event) => setSearch(event.target.value)}
                      aria-label="Buscar por nome, telefone ou e-mail"
                    />
                  </div>
                  {access.viewAll && (
                    <window.Select
                      value={assignedFilter}
                      aria-label="Filtrar por responsável"
                      onChange={(event) => setAssignedFilter(event.target.value)}
                    >
                      <option value="all">Todos os responsáveis</option>
                      <option value="mine">Minhas conversas</option>
                      <option value="unassigned">Sem responsável</option>
                    </window.Select>
                  )}
                  <div className="crm-inbox-view-switch" aria-label="Modo de visualização">
                    <button type="button" onClick={() => changeInboxView('list')} title="Ver conversas"><window.Icon name="list" size={17} /><span>Conversas</span></button>
                    <button type="button" className="active" aria-current="page" title="Ver quadro"><window.Icon name="grid" size={17} /><span>Quadro</span></button>
                  </div>
                  <button className="crm-kanban-icon-button" type="button" onClick={() => loadConversations()} title="Atualizar quadro" aria-label="Atualizar quadro"><window.Icon name="refresh" size={18} /></button>
                  <button className="crm-kanban-new-button" type="button" onClick={() => setNewConversationOpen(true)}><window.Icon name="plus" size={17} /> Nova conversa</button>
                </div>
              </header>

              <div className={`crm-kanban-board${boardDragId ? ' dragging' : ''}`} aria-live="polite">
                {[
                  ['awaiting', 'Aguardando resposta', 'O cliente enviou a última mensagem', 'bell', ''],
                  ['open', 'Em atendimento', 'Conversas sendo atendidas agora', 'whatsapp', 'open'],
                  ['pending', 'Pendentes', 'Aguardando retorno ou ação', 'clock', 'pending'],
                  ['resolved', 'Concluídas', 'Atendimentos finalizados', 'check', 'resolved'],
                ].map(([key, label, description, icon, dropStatus]) => (
                  <section
                    className={`crm-kanban-column status-${key}${boardDropStatus === dropStatus && dropStatus ? ' drop-active' : ''}`}
                    key={key}
                    onDragOver={(event) => {
                      if (!dropStatus) return;
                      event.preventDefault();
                      event.dataTransfer.dropEffect = 'move';
                      setBoardDropStatus(dropStatus);
                    }}
                    onDragLeave={(event) => {
                      if (!event.currentTarget.contains(event.relatedTarget)) setBoardDropStatus('');
                    }}
                    onDrop={(event) => {
                      if (!dropStatus) return;
                      event.preventDefault();
                      const conversationId = Number(event.dataTransfer.getData('text/plain') || boardDragId);
                      if (conversationId) moveBoardConversation(conversationId, dropStatus);
                    }}
                  >
                    <header className="crm-kanban-column-head">
                      <span className="crm-kanban-column-icon"><window.Icon name={icon} size={15} /></span>
                      <span><strong>{label}</strong><small>{description}</small></span>
                      <b>{boardColumns[key].length}</b>
                    </header>
                    <div className="crm-kanban-column-body">
                      {conversationLoading && conversations.length === 0 ? (
                        <div className="crm-kanban-empty">Carregando atendimentos…</div>
                      ) : boardColumns[key].length === 0 ? (
                        <div className="crm-kanban-empty">Nenhum atendimento nesta etapa</div>
                      ) : boardColumns[key].map((conversation) => (
                        <CrmKanbanCard
                          key={conversation.id}
                          conversation={conversation}
                          busy={Number(boardBusyId) === Number(conversation.id)}
                          onOpen={openBoardConversation}
                          onMove={moveBoardConversation}
                          onDragStart={(event, item) => {
                            setBoardDragId(Number(item.id));
                            event.dataTransfer.effectAllowed = 'move';
                            event.dataTransfer.setData('text/plain', String(item.id));
                          }}
                          onDragEnd={() => { setBoardDragId(0); setBoardDropStatus(''); }}
                        />
                      ))}
                    </div>
                  </section>
                ))}
              </div>
            </div>
          ) : (
          <div className={`crm-inbox-grid${selectedId ? ' has-selection' : ''}${contextOpen ? ' context-open' : ''}`}>
            <aside className="crm-inbox-conversations-pane">
              <div className="crm-inbox-list-head">
                <div className="crm-inbox-list-title">
                  <span className={`crm-channel-summary-dot${whatsappConnected ? ' connected' : ''}`} aria-hidden="true"></span>
                  <div><strong>Conversas</strong><small>{whatsappConnected ? 'WhatsApp conectado' : 'Canal desconectado'}</small></div>
                </div>
                <div className="crm-inbox-list-actions">
                  <div className="crm-inbox-view-switch" aria-label="Modo de visualização">
                    <button type="button" className="active" aria-current="page" title="Ver conversas"><window.Icon name="list" size={17} /></button>
                    <button type="button" onClick={() => changeInboxView('board')} title="Ver quadro"><window.Icon name="grid" size={17} /></button>
                  </div>
                  <button type="button" onClick={() => loadConversations()} title="Atualizar conversas" aria-label="Atualizar conversas">
                    <window.Icon name="refresh" size={19} />
                  </button>
                  <button type="button" onClick={() => setNewConversationOpen(true)} title="Nova conversa" aria-label="Nova conversa">
                    <window.Icon name="plus" size={20} />
                  </button>
                </div>
              </div>
              <div className="crm-inbox-list-tools">
                <div className="crm-inbox-search">
                  <window.Icon name="search" size={16} />
                  <window.Input
                    value={search}
                    placeholder="Buscar conversa"
                    onChange={(event) => setSearch(event.target.value)}
                    aria-label="Buscar por nome, telefone ou e-mail"
                  />
                </div>
                <div className="crm-inbox-list-filters" role="tablist" aria-label="Filtrar conversas">
                  {filterItems.map(([value, label, count]) => (
                    <button
                      type="button"
                      role="tab"
                      aria-selected={filter === value}
                      className={filter === value ? 'active' : ''}
                      key={value}
                      onClick={() => setFilter(value)}
                    >
                      {label}<span>{count}</span>
                    </button>
                  ))}
                </div>
                {access.viewAll && (
                  <window.Select
                    value={assignedFilter}
                    aria-label="Filtrar por responsável"
                    onChange={(event) => setAssignedFilter(event.target.value)}
                  >
                    <option value="all">Todos os responsáveis</option>
                    <option value="mine">Minhas conversas</option>
                    <option value="unassigned">Sem responsável</option>
                  </window.Select>
                )}
              </div>
              <div className="crm-inbox-conversation-list" aria-live="polite">
                {conversationLoading && conversations.length === 0 ? (
                  <div className="crm-inbox-list-empty">Carregando conversas…</div>
                ) : conversations.length === 0 ? (
                  <div className="crm-inbox-list-empty">
                    <strong>Nenhuma conversa encontrada</strong>
                    <span>Novas mensagens aparecerão aqui.</span>
                  </div>
                ) : conversations.map((conversation) => (
                  <CrmConversationItem
                    key={conversation.id}
                    conversation={conversation}
                    active={conversation.id === selectedId}
                    onClick={() => chooseConversation(conversation.id)}
                  />
                ))}
              </div>
            </aside>

            <main className="crm-inbox-thread-pane">
              {!currentConversation ? (
                <div className="crm-inbox-thread-empty">
                  <window.Icon name="whatsapp" size={28} />
                  <strong>Selecione uma conversa</strong>
                  <span>Abra um atendimento para ver o histórico e responder.</span>
                </div>
              ) : (
                <>
                  <header className="crm-inbox-thread-head">
                    <button
                      type="button"
                      className="crm-inbox-mobile-back"
                      aria-label="Voltar para conversas"
                      onClick={() => {
                        setSelectedId(0);
                        setSelectedConversation(null);
                        setMessages([]);
                      }}
                    >
                      <window.Icon name="chevLeft" size={20} />
                    </button>
                    <window.Avatar
                      initials={crmInboxInitials(currentContactName)}
                      src={(currentClient && currentClient.photoUrl) || ''}
                      alt={currentContactName}
                      color="gray"
                      size={38}
                    />
                    <button type="button" className="crm-inbox-thread-contact" onClick={() => setContextOpen(true)} title="Ver dados do contato">
                      <strong>{currentContactName}</strong>
                      <span>{crmInboxPhone(currentConversation.counterpartPhone)}</span>
                      <span className="crm-inbox-thread-owner">
                        {currentConversation.assignedUser
                          ? `Atendido por ${currentConversation.assignedUser.name}`
                          : 'Aguardando responsável'}
                      </span>
                    </button>
                    <div className="crm-inbox-thread-actions">
                      <button type="button" onClick={() => setContextOpen((value) => !value)} title="Dados do contato" aria-label="Dados do contato">
                        <window.Icon name="info" size={17} />
                      </button>
                      {currentConversation.status !== 'pending' && (
                        <button
                          type="button"
                          title="Marcar como pendente"
                          aria-label="Marcar como pendente"
                          onClick={() => updateConversation({ status: 'pending' }, 'Conversa marcada como pendente.')}
                          disabled={conversationBusy}
                        >
                          <window.Icon name="clock" size={16} />
                          Pendente
                        </button>
                      )}
                      {currentConversation.status !== 'resolved' && (
                        <button
                          type="button"
                          title="Resolver conversa"
                          aria-label="Resolver conversa"
                          onClick={() => updateConversation({ status: 'resolved' }, 'Conversa resolvida.')}
                          disabled={conversationBusy}
                        >
                          <window.Icon name="check" size={16} />
                          Resolver
                        </button>
                      )}
                      {currentConversation.status === 'resolved' && (
                        <button
                          type="button"
                          title="Reabrir conversa"
                          aria-label="Reabrir conversa"
                          onClick={() => updateConversation({ status: 'open' }, 'Conversa reaberta.')}
                          disabled={conversationBusy}
                        >
                          <window.Icon name="refresh" size={16} />
                          Reabrir
                        </button>
                      )}
                    </div>
                  </header>

                  <div className="crm-inbox-message-viewport" ref={messageViewportRef} aria-live="polite">
                    {threadLoading && messages.length === 0 ? (
                      <div className="crm-inbox-thread-loading">Carregando histórico…</div>
                    ) : messages.length === 0 ? (
                      <div className="crm-inbox-thread-loading">Nenhuma mensagem nesta conversa.</div>
                    ) : arrangedMessages.map((item) => (
                      <CrmMessageBubble
                        message={item.message}
                        reactions={item.reactions}
                        replyToMessage={item.message.content && item.message.content.replyToMessageId
                          ? messagesByProviderId.get(item.message.content.replyToMessageId) || null
                          : null}
                        contactName={currentContactName}
                        onReply={(message) => {
                          setReplyingTo(message);
                          window.setTimeout(() => document.querySelector('.crm-inbox-composer .textarea')?.focus(), 0);
                        }}
                        key={item.message.id}
                      />
                    ))}
                  </div>

                  <form className="crm-inbox-composer" onSubmit={sendMessage}>
                    {!currentConversation.canSendFreeform && (
                      <div className="crm-composer-window-warning">
                        A janela de 24 horas está fechada. Use Nova conversa para enviar um modelo aprovado e aguarde a resposta do cliente.
                      </div>
                    )}
                    <div className="crm-composer-identity">
                      <span>
                        <b>{user.name || user.login}</b> conectado · cliente verá <strong>{senderDisplayName}</strong> em negrito
                      </span>
                      <button
                        type="button"
                        disabled={messageBusy || senderIdentityBusy}
                        onClick={() => {
                          setSenderNameDraft(senderDisplayName);
                          setSenderEditorOpen((current) => !current);
                        }}
                      >
                        {senderEditorOpen ? 'Fechar' : 'Alterar nome'}
                      </button>
                    </div>
                    {senderEditorOpen && (
                      <div className="crm-composer-identity-editor">
                        <window.Input
                          value={senderNameDraft}
                          maxLength={80}
                          disabled={senderIdentityBusy}
                          placeholder="Ex.: Rafael, Comercial ou Suporte"
                          aria-label="Nome mostrado ao cliente"
                          onChange={(event) => setSenderNameDraft(event.target.value)}
                          onKeyDown={(event) => {
                            if (event.key === 'Enter') {
                              event.preventDefault();
                              saveSenderIdentity();
                            }
                          }}
                        />
                        <window.Button type="button" size="sm" onClick={saveSenderIdentity} disabled={senderIdentityBusy}>
                          {senderIdentityBusy ? 'Salvando…' : 'Salvar nome'}
                        </window.Button>
                        <button
                          type="button"
                          className="crm-composer-identity-reset"
                          disabled={senderIdentityBusy}
                          onClick={() => setSenderNameDraft('')}
                        >
                          Usar nome do usuário
                        </button>
                      </div>
                    )}
                    <div className="crm-quick-replies" aria-label="Respostas rápidas">
                      {['Olá! Como posso ajudar?', 'Vou verificar para você.', 'Posso ajudar com um agendamento?'].map((reply) => (
                        <button
                          type="button"
                          key={reply}
                          disabled={messageBusy || !currentConversation.canSendFreeform}
                          onClick={() => setMessageBody(reply)}
                        >
                          {reply}
                        </button>
                      ))}
                    </div>
                    {attachment && (
                      <div className="crm-composer-attachment">
                        <window.Icon name="file" size={18} />
                        <span><strong>{attachment.name}</strong><small>{(attachment.size / 1024 / 1024).toFixed(1)} MB</small></span>
                        <button type="button" onClick={() => { setAttachment(null); if (attachmentInputRef.current) attachmentInputRef.current.value = ''; }} aria-label="Remover anexo">×</button>
                      </div>
                    )}
                    {replyingTo && (
                      <div className="crm-composer-reply" role="status">
                        <span className="crm-composer-reply-icon"><window.Icon name="reply" size={17} /></span>
                        <span>
                          <strong>Respondendo à mensagem</strong>
                          <small>{crmInboxReplyPreview(replyingTo)}</small>
                        </span>
                        <button type="button" onClick={() => setReplyingTo(null)} aria-label="Cancelar resposta">×</button>
                      </div>
                    )}
                    <window.Textarea
                      value={messageBody}
                      rows={3}
                      maxLength={messageMaxLength}
                      disabled={messageBusy || !currentConversation.canSendFreeform}
                      placeholder={attachment ? 'Adicione uma legenda, se quiser…' : 'Digite uma mensagem de atendimento…'}
                      onChange={(event) => setMessageBody(event.target.value)}
                      onKeyDown={(event) => {
                        if (event.key === 'Enter' && !event.shiftKey) {
                          event.preventDefault();
                          if (!messageBusy && messageBody.trim()) event.currentTarget.form.requestSubmit();
                        }
                      }}
                    />
                    <div className="crm-inbox-composer-foot">
                      <span>Enter envia · Shift + Enter quebra a linha</span>
                      <div>
                        <input
                          ref={attachmentInputRef}
                          className="crm-composer-file-input"
                          type="file"
                          accept="image/jpeg,image/png,image/webp,video/mp4,video/3gpp,audio/mpeg,audio/mp4,audio/ogg,audio/aac,application/pdf,text/plain,.doc,.docx"
                          onChange={(event) => setAttachment(event.target.files && event.target.files[0] ? event.target.files[0] : null)}
                        />
                        <button
                          className="crm-composer-attach-button"
                          type="button"
                          disabled={messageBusy || !currentConversation.canSendFreeform}
                          onClick={() => attachmentInputRef.current && attachmentInputRef.current.click()}
                          title="Enviar imagem, vídeo, áudio ou documento"
                        >
                          <window.Icon name="paperclip" size={18} /> <span>Anexar</span>
                        </button>
                        <span>{messageBody.length}/{messageMaxLength}</span>
                        <window.Button
                          type="submit"
                          icon="send"
                          disabled={messageBusy || (!messageBody.trim() && !attachment) || !currentConversation.canSendFreeform}
                        >
                          {messageBusy ? 'Enviando…' : 'Enviar'}
                        </window.Button>
                      </div>
                    </div>
                  </form>
                </>
              )}
            </main>

            <aside className="crm-inbox-context-pane">
              <div className="crm-inbox-context-head">
                <strong>Dados do contato</strong>
                <button type="button" onClick={() => setContextOpen(false)} title="Fechar painel" aria-label="Fechar painel">
                  <window.Icon name="x" size={19} />
                </button>
              </div>
              {!currentConversation ? (
                <div className="crm-inbox-context-empty">Os dados do contato aparecerão aqui.</div>
              ) : (
                <>
                  <section className="crm-inbox-context-profile">
                    <window.Avatar
                      initials={crmInboxInitials(currentContactName)}
                      src={(currentClient && currentClient.photoUrl) || ''}
                      alt={currentContactName}
                      color="gray"
                      size={54}
                    />
                    <strong>{currentContactName}</strong>
                    <span>{crmInboxPhone(currentConversation.counterpartPhone)}</span>
                    <span className={`crm-inbox-status crm-inbox-status-${currentConversation.lastMessageDirection === 'inbound' ? 'awaiting' : currentConversation.status}`}>
                      {currentConversation.lastMessageDirection === 'inbound'
                        ? 'Aguardando resposta'
                        : (crmInboxStatusLabels[currentConversation.status] || currentConversation.status)}
                    </span>
                  </section>

                  <section className="crm-inbox-context-section">
                    <h3>Responsável</h3>
                    {access.assign ? (
                      <window.Select
                        value={currentConversation.assignedUser ? currentConversation.assignedUser.id : ''}
                        disabled={conversationBusy}
                        onChange={(event) => {
                          const assignedUserId = Number(event.target.value) || 0;
                          const nextAssignee = assignees.find((item) => Number(item.id) === assignedUserId);
                          updateConversation(
                            { assignedUserId },
                            nextAssignee ? `Atendimento transferido para ${nextAssignee.name}.` : 'Atendimento devolvido para a fila.'
                          );
                        }}
                      >
                        <option value="">Sem responsável</option>
                        {assignees.map((assignee) => (
                          <option value={assignee.id} key={assignee.id}>
                            {assignee.name} · {crmInboxRoleLabels[assignee.role] || assignee.role}
                          </option>
                        ))}
                      </window.Select>
                    ) : currentConversation.assignedUser ? (
                      <span>{currentConversation.assignedUser.name}</span>
                    ) : (
                      <window.Button
                        variant="outline"
                        size="sm"
                        onClick={() => updateConversation({ assignedUserId: user.id }, 'Atendimento assumido.')}
                        disabled={conversationBusy}
                      >
                        Assumir atendimento
                      </window.Button>
                    )}
                  </section>

                  <section className="crm-inbox-context-section">
                    <h3>Contato na Agenda</h3>
                    {currentClient ? (
                      <dl className="crm-inbox-contact-data">
                        <div><dt>Telefone</dt><dd>{currentClient.phone || crmInboxPhone(currentConversation.counterpartPhone)}</dd></div>
                        <div><dt>E-mail</dt><dd>{currentClient.email || 'Não informado'}</dd></div>
                        <div><dt>Categoria</dt><dd>{currentClient.tag || 'Sem categoria'}</dd></div>
                        <div><dt>Atendimentos</dt><dd>{currentClient.visits}</dd></div>
                      </dl>
                    ) : (
                      <p>Este número ainda não corresponde a um cliente cadastrado na Agenda.</p>
                    )}
                  </section>

                  <section className="crm-inbox-context-section">
                    <h3>Próximo agendamento</h3>
                    {currentConversation.nextAppointment ? (
                      <div className="crm-inbox-appointment">
                        <strong>
                          {crmInboxAppointmentDate(currentConversation.nextAppointment.date)}
                          {' · '}
                          {currentConversation.nextAppointment.start}
                        </strong>
                        <span>{currentConversation.nextAppointment.serviceName}</span>
                        {currentConversation.nextAppointment.professionalName && (
                          <small>{currentConversation.nextAppointment.professionalName}</small>
                        )}
                      </div>
                    ) : (
                      <p>Nenhum agendamento futuro encontrado.</p>
                    )}
                  </section>
                </>
              )}
            </aside>
          </div>
          )}
        </section>
      ) : (
        <section className="card card-pad crm-inbox-connect-empty">
          <window.Empty
            icon="whatsapp"
            title="Conecte o WhatsApp"
            desc="Depois da conexão, mensagens, contatos, responsáveis e pendências serão organizados nesta caixa de entrada."
          />
          {access.manageChannels && (
            <div className="row" style={{ justifyContent: 'center', marginTop: 16 }}>
              <window.Button
                onClick={connectWhatsApp}
                disabled={!channelSetupReady || !!channelBusy}
              >
                {channelBusy === 'connect' ? 'Abrindo conexão…' : 'Conectar WhatsApp'}
              </window.Button>
            </div>
          )}
        </section>
      ))}

      {settingsView && access.manageUsers && (
        <section className="card crm-access-collapsible">
          <button
            type="button"
            className="crm-access-collapsible-head"
            onClick={() => setAccessOpen((current) => !current)}
            aria-expanded={accessOpen}
          >
            <span>
              <strong>Acessos ao CRM</strong>
              <small>
                {enabledUsersCount} {enabledUsersCount === 1 ? 'usuário com acesso' : 'usuários com acesso'}
              </small>
            </span>
            <window.Icon name={accessOpen ? 'chevDown' : 'chevRight'} size={18} />
          </button>
          {accessOpen && (
            <div className="crm-access-collapsible-body">
              {users.map((item) => (
                <div className="crm-access-row" key={item.id}>
                  <window.Avatar initials={crmInboxInitials(item.name || item.login)} size={34} color="gray" />
                  <div className="crm-access-person">
                    <b>{item.name || item.login}</b>
                    <span>{item.login} · {item.agendaRole === 'admin' ? 'Administrador da Agenda' : 'Usuário da Agenda'}</span>
                  </div>
                  <div className="crm-access-control">
                    <window.Select
                      aria-label={`Acesso de ${item.name || item.login}`}
                      value={item.crmEnabled ? item.crmRole : ''}
                      disabled={item.isPrimaryAdmin || busyUserId === item.id || item.status !== 'ativo'}
                      onChange={(event) => updateAccess(item.id, event.target.value)}
                    >
                      <option value="">Sem acesso</option>
                      <option value="agent">Atendente</option>
                      <option value="manager">Gerente</option>
                      <option value="admin">Administrador</option>
                    </window.Select>
                    {item.isPrimaryAdmin && <span className="crm-access-note">Acesso obrigatório</span>}
                    {busyUserId === item.id && <span className="crm-access-note">Salvando…</span>}
                    {savedUserId === item.id && <span className="crm-access-note success">Salvo</span>}
                  </div>
                </div>
              ))}
            </div>
          )}
        </section>
      )}

      <CrmNewConversationModal
        open={newConversationOpen}
        contacts={contacts}
        contactsLoading={contactsLoading}
        contactQuery={contactQuery}
        setContactQuery={setContactQuery}
        phone={newPhone}
        setPhone={setNewPhone}
        templates={templates}
        templatesLoading={templatesLoading}
        templateKey={templateKey}
        setTemplateKey={(value) => { setTemplateKey(value); setTemplateParameters({}); setTemplateMedia(null); }}
        templateParameters={templateParameters}
        setTemplateParameters={setTemplateParameters}
        templateMedia={templateMedia}
        setTemplateMedia={setTemplateMedia}
        error={newConversationError}
        busy={newBusy}
        onClose={() => {
          if (newBusy) return;
          setNewConversationOpen(false);
          setContactQuery('');
          setContacts([]);
          setNewPhone('');
          setTemplateKey('');
          setTemplateParameters({});
          setTemplateMedia(null);
          setNewConversationError('');
        }}
        onSubmit={sendNewConversation}
      />
    </div>
  );
}

// A empresa de demonstração mantém a tela usada na análise da Meta.
// Os demais tenants recebem a caixa de entrada operacional atual.
function CrmInboxRouteScreen(props) {
  return props.user && props.user.hasCrm
    ? <CrmInboxScreen {...props} />
    : <window.CrmInactiveScreen {...props} />;
}

if (window.TENANT_SLUG !== 'empresa-demonstracao') {
  window.CrmScreen = CrmInboxRouteScreen;
}
