import type { ChatLogRecord, LeadRecord } from '@/lib/api'; import type { Lead } from '@/types'; import type { LeadBadge, LeadTag, LeadSource, Message, MessageSender, PipelineStage, SentimentLog } from '@/types/crm'; const TAG_MAP: Record = { whale: '#CashBuyer', potential: '#Investor', hot: '#EndUser', }; export function mapLeadRecordToStoreLead(record: LeadRecord): Lead { const qualification = record.qualification.toLowerCase() as Lead['qualification']; const status = record.stage === 'closed' ? 'closed' : record.stage === 'qualified' || record.stage === 'negotiation' ? 'qualified' : record.score >= 75 ? 'hot' : record.stage === 'new' ? 'new' : 'engaged'; const tags = Array.isArray(record.metadata?.tags) ? (record.metadata.tags as string[]) : []; return { id: record.id, name: record.name, phone: record.phone ?? '', source: mapSource(record.source), status, lastMessage: record.notes || 'No conversation summary yet.', lastActive: new Date(record.updated_at ?? record.created_at ?? Date.now()), unreadCount: 0, qualification: qualification === 'tire_kicker' || qualification === 'potential' || qualification === 'whale' ? qualification : 'potential', budget: record.budget, interest: record.unit_interest, quantumDynamicsScore: record.score, tags: tags.length > 0 ? tags : [record.qualification], }; } export function mapLeadRecordToOracleLead(record: LeadRecord, chatLogs: ChatLogRecord[]): import('@/types/crm').Lead { const badge = mapBadge(record.qualification); const tags = mapOracleTags(record.qualification, record.metadata); return { id: record.id, name: record.name, phone: record.phone ?? '', stage: mapPipelineStage(record.stage), oracleScore: record.score, badge, tags, source: mapSource(record.source), budget: record.budget, unitInterest: record.unit_interest, profileImageUrl: `https://api.dicebear.com/9.x/glass/svg?seed=${encodeURIComponent(record.name)}`, visitedShowroom: record.stage === 'site_visit' || record.stage === 'negotiation' || record.stage === 'closed', inShowroomNow: record.stage === 'site_visit', messages: chatLogs.map(mapChatLogToOracleMessage), sentimentLog: buildSentimentLog(record.score, record.stage), }; } function mapSource(source: string): LeadSource { if (source === 'walkin' || source === 'website' || source === 'whatsapp') return source; return 'website'; } function mapPipelineStage(stage: string): PipelineStage { const normalized = stage.toLowerCase(); if (normalized === 'new' || normalized === 'new_inquiries') return 'new_inquiries'; if (normalized === 'qualified' || normalized === 'qualifying') return 'qualified'; if (normalized === 'site_visit') return 'site_visit'; if (normalized === 'negotiation') return 'negotiation'; return 'closed'; } function mapBadge(qualification: string): LeadBadge | undefined { const normalized = qualification.toLowerCase(); if (normalized === 'whale') return 'whale'; if (normalized === 'hot' || normalized === 'potential') return 'hot'; if (normalized === 'tire_kicker') return 'tire_kicker'; return undefined; } function mapOracleTags(qualification: string, metadata: Record): LeadTag[] { const mapped = TAG_MAP[qualification.toLowerCase()]; const rawTags = Array.isArray(metadata?.tags) ? metadata.tags as string[] : []; const canonical = rawTags.includes('#CashBuyer') || mapped === '#CashBuyer' ? '#CashBuyer' : rawTags.includes('#EndUser') || mapped === '#EndUser' ? '#EndUser' : '#Investor'; return [canonical]; } function mapChatLogToOracleMessage(log: ChatLogRecord): Message { return { id: log.id, sender: mapSender(log.sender), content: log.content, createdAt: log.created_at ?? new Date().toISOString(), }; } function mapSender(sender: string): MessageSender { if (sender === 'lead' || sender === 'oracle' || sender === 'system') return sender; return 'system'; } function buildSentimentLog(score: number, stage: string): SentimentLog[] { const base = Math.max(20, score - 18); const labels = stage === 'site_visit' ? ['Entry', 'Showroom peak', 'Pricing review'] : ['Discovery', 'Qualification', 'Follow-up']; return labels.map((label, index) => ({ id: `${stage}-${index}`, at: `${10 + index}:0${index}`, score: Math.min(100, base + index * 9), note: label, })); }