import type { IAgentProductPerformance, IAgentIntentSentiment, IAgentChatbotPerformance, IAgentCompetitiveIntel, IAgentEngagementPatterns, } from '../../service/agent-analytics/agent-analytics.interface'; import { RECOMAZE_COLORS, CHART_PALETTE } from './helpers'; export const BAR_CHART_OPTIONS = { plugins: { legend: { display: false } }, scales: { x: { grid: { display: false } }, y: { beginAtZero: true, grid: { color: '#f3f4f6' } }, }, }; export const DOUGHNUT_CHART_OPTIONS = { plugins: { legend: { position: 'right' as const, labels: { boxWidth: 12, font: { size: 11 } }, }, }, cutout: '60%', }; export const LINE_CHART_OPTIONS = { plugins: { legend: { position: 'top' as const, labels: { boxWidth: 12, font: { size: 11 } }, }, }, scales: { x: { grid: { display: false }, ticks: { maxTicksLimit: 10, font: { size: 10 } }, }, y: { beginAtZero: true, grid: { color: '#f3f4f6' } }, }, }; export const LINE_CHART_OPTIONS_NO_LEGEND = { ...LINE_CHART_OPTIONS, plugins: { legend: { display: false } }, }; export const PRODUCT_SORT_KEYS = [ 'times_recommended', 'times_clicked', 'times_carted', 'click_rate', 'cart_rate', ] as const; export const getDefaultProductPerformance = (): IAgentProductPerformance => ({ top_products: [], missing_products: [], category_distribution: {}, }); export const getDefaultIntentSentiment = (): IAgentIntentSentiment => ({ intent_distribution: {}, sentiment_breakdown: { positive: 0, neutral: 0, negative: 0 }, outcome_distribution: {}, sentiment_trend: [], }); export const getDefaultChatbotPerformance = (): IAgentChatbotPerformance => ({ satisfaction_trend: [], common_questions: [], common_pain_points: [], }); export const getDefaultCompetitiveIntel = (): IAgentCompetitiveIntel => ({ total_mentions: 0, competitors: [], }); export const getDefaultEngagementPatterns = (): IAgentEngagementPatterns => ({ daily_conversations: [], peak_hours: {}, language_distribution: {}, avg_user_message_length: 0, avg_ai_response_length: 0, conversations_with_products: 0, product_engagement_rate: 0, }); export const buildCategoryDistributionChartData = ( distribution: Record ) => { const labels = Object.keys(distribution); if (labels.length === 0) return null; return { labels, datasets: [ { data: Object.values(distribution), backgroundColor: CHART_PALETTE.slice(0, labels.length), borderWidth: 0, }, ], }; }; export const buildIntentDistributionChartData = ( distribution: Record ) => { const labels = Object.keys(distribution); if (labels.length === 0) return null; return { labels, datasets: [ { data: Object.values(distribution), backgroundColor: RECOMAZE_COLORS.primary, borderRadius: 6, }, ], }; }; export const buildSentimentBreakdownChartData = (breakdown: { positive: number; neutral: number; negative: number; }) => { if (!breakdown.positive && !breakdown.neutral && !breakdown.negative) return null; return { labels: ['Positive', 'Neutral', 'Negative'], datasets: [ { data: [ breakdown.positive || 0, breakdown.neutral || 0, breakdown.negative || 0, ], backgroundColor: ['#22c55e', '#94a3b8', '#ef4444'], borderWidth: 0, }, ], }; }; export const buildOutcomeDistributionChartData = ( distribution: Record ) => { const labels = Object.keys(distribution); if (labels.length === 0) return null; return { labels, datasets: [ { data: Object.values(distribution), backgroundColor: [ RECOMAZE_COLORS.primary, RECOMAZE_COLORS.dark, RECOMAZE_COLORS.accent1, RECOMAZE_COLORS.accent2, RECOMAZE_COLORS.accent3, ].slice(0, labels.length), borderRadius: 6, }, ], }; }; export const buildSentimentTrendChartData = ( trend: Array<{ date: string; positive: number; neutral: number; negative: number; }> ) => { if (trend.length === 0) return null; return { labels: trend.map(s => s.date), datasets: [ { label: 'Positive', data: trend.map(s => s.positive), borderColor: '#22c55e', backgroundColor: 'rgba(34,197,94,0.1)', fill: true, tension: 0.4, pointRadius: 2, }, { label: 'Neutral', data: trend.map(s => s.neutral), borderColor: '#94a3b8', backgroundColor: 'rgba(148,163,184,0.1)', fill: true, tension: 0.4, pointRadius: 2, }, { label: 'Negative', data: trend.map(s => s.negative), borderColor: '#ef4444', backgroundColor: 'rgba(239,68,68,0.1)', fill: true, tension: 0.4, pointRadius: 2, }, ], }; }; export const buildSatisfactionTrendChartData = ( trend: Array<{ date: string; rate: number }> ) => { if (trend.length === 0) return null; return { labels: trend.map(s => s.date), datasets: [ { label: 'Satisfaction %', data: trend.map(s => s.rate), borderColor: RECOMAZE_COLORS.primary, backgroundColor: 'rgba(183,0,124,0.08)', fill: true, tension: 0.4, pointRadius: 2, }, ], }; }; export const buildPeakHoursChartData = (peakHours: Record) => { const labels = Object.keys(peakHours).sort((a, b) => Number(a) - Number(b)); if (labels.length === 0) return null; return { labels: labels.map(h => `${h}:00`), datasets: [ { data: labels.map(h => peakHours[h]), backgroundColor: RECOMAZE_COLORS.primary, borderRadius: 4, }, ], }; }; export const buildLanguageDistributionChartData = ( distribution: Record ) => { const labels = Object.keys(distribution); if (labels.length === 0) return null; return { labels, datasets: [ { data: Object.values(distribution), backgroundColor: CHART_PALETTE.slice(0, labels.length), borderWidth: 0, }, ], }; };