import { sentimentDashboardMockSource } from '../data/sentiment-dashboard.mock.js'; const summaryCardsConfig = [ { key: 'atRiskClients', label: 'Clientes em risco' }, { key: 'opportunities', label: 'Oportunidades' }, { key: 'recentInteractions', label: 'Interacoes recentes' }, { key: 'netTrend', label: 'Tendencia liquida' } ]; const priorityLabel = { high: 'Alta prioridade', medium: 'Media prioridade', low: 'Baixa prioridade' }; export function getSentimentDashboardViewModel() { return { summaryCards: mapSummaryCards(sentimentDashboardMockSource.summary), alerts: mapAlerts(sentimentDashboardMockSource.alerts), timeline: sentimentDashboardMockSource.timeline, aspects: mapAspects(sentimentDashboardMockSource.aspects) }; } export function getSummaryInsight(cardId, viewModel) { const card = viewModel.summaryCards.find((item) => item.id === cardId); if (!card) return createFallbackInsight(); const insightByCard = { atRiskClients: { title: 'Clientes em risco em destaque', context: `${card.value} clientes apresentam sinais de queda de engajamento ou resposta tardia.`, actions: [ 'Priorizar contato em ate 24h para os casos com maior ticket.', 'Acionar playbook de retencao com oferta de recuperacao.', 'Distribuir os casos criticos para vendedores com melhor conversao.' ] }, opportunities: { title: 'Oportunidades comerciais ativas', context: `${card.value} clientes estao com indicios de compra em aberto.`, actions: [ 'Executar abordagem consultiva nos clientes com intencao alta.', 'Enviar proposta com prazo curto para acelerar fechamento.', 'Marcar follow-up com dono da conta ainda hoje.' ] }, recentInteractions: { title: 'Volume recente de interacoes', context: `${card.value} interacoes recentes exigem triagem por impacto no resultado.`, actions: [ 'Separar interacoes por risco, oportunidade e neutras.', 'Garantir SLA para mensagens sem retorno.', 'Acompanhar taxa de resolucao no primeiro contato.' ] }, netTrend: { title: 'Tendencia liquida de resultado', context: `Tendencia atual de ${card.value}, indicando saldo positivo entre ganhos e perdas.`, actions: [ 'Escalar abordagem que gerou maior crescimento nas ultimas semanas.', 'Manter monitoramento de contas em risco para evitar reversao.', 'Transformar casos de sucesso em rotina para todo o time.' ] } }; return insightByCard[cardId] ?? createFallbackInsight(); } export function getAlertInsight(alertId, viewModel) { const alert = viewModel.alerts.find((item) => item.id === alertId); if (!alert) return createFallbackInsight(); const categoryGuidance = { churn_risk: [ 'Fazer contato humano com proposta de recuperacao em ate 24h.', 'Identificar causa raiz da perda de interesse no ultimo ciclo.', 'Negociar condicoes para reativar a conta com menor atrito.' ], frustration: [ 'Responder com empatia e reconhecer o problema sem delay.', 'Resolver o ponto de frustracao com responsavel e prazo claro.', 'Fazer retorno ativo confirmando que o problema foi resolvido.' ], buying_intent: [ 'Acionar vendedor responsavel para proposta objetiva imediata.', 'Remover bloqueios de compra (prazo, condicao, produto).', 'Registrar proximo passo com data de fechamento prevista.' ] }; return { title: alert.title, context: alert.description, actions: categoryGuidance[alert.category] ?? createFallbackInsight().actions }; } export function getTimelineInsight(period, viewModel) { const timelinePoint = viewModel.timeline.find((item) => item.period === period); if (!timelinePoint) return createFallbackInsight(); const balance = timelinePoint.gains - timelinePoint.losses; const trendText = balance >= 0 ? `saldo positivo de ${balance} pontos entre ganhos e perdas` : `saldo negativo de ${Math.abs(balance)} pontos entre ganhos e perdas`; return { title: `Leitura da ${timelinePoint.period}`, context: `Na ${timelinePoint.period}, houve ${timelinePoint.gains} ganhos e ${timelinePoint.losses} perdas, com ${trendText}.`, actions: [ 'Replicar o comportamento das contas com ganho na semana.', 'Atuar nos principais motivos de perda identificados no periodo.', 'Definir meta da proxima semana com base no saldo atual.' ] }; } function mapSummaryCards(summary) { return summaryCardsConfig.map((config) => ({ id: config.key, label: config.label, value: summary[config.key]?.value ?? summary[config.key], image: summary[config.key]?.image ?? null })); } function mapAlerts(alerts) { return alerts.map((alert) => ({ ...alert, priorityLabel: priorityLabel[alert.priority] ?? priorityLabel.low })); } function mapAspects(aspects) { return aspects.map((aspect) => ({ ...aspect, volume: aspect.positive.length + aspect.neutral.length + aspect.negative.length })); } function createFallbackInsight() { return { title: 'Detalhes da analise', context: 'Selecione um item para visualizar diagnostico e recomendacoes.', actions: ['Priorizar casos de alto impacto.', 'Executar proximo passo comercial.', 'Monitorar resultado diariamente.'] }; }