import { brand, brandSuggestionFa, type MemoryItemDto, type NoteDto, type PersonDto } from '@mento/shared'; export type ProbabilityBand = 'بالا' | 'متوسط' | 'پایین'; export function personInitials(fullName: string | null | undefined): string { const parts = fullName?.trim().split(/\s+/) ?? []; if (!parts.length) return 'م'; return parts .slice(0, 2) .map((p) => p[0]) .join(''); } export function isVipPerson(person: PersonDto | null): boolean { if (!person) return false; const tier = person.loyaltyTier?.name ?? ''; if (/vip|طلا|طلایی|gold|پلاتین|platinum/i.test(tier)) return true; if ((person.loyaltyPoints ?? 0) >= 800) return true; const fields = person.customFields ?? {}; for (const [key, value] of Object.entries(fields)) { if (/vip/i.test(key) && (value === true || value === 'true' || value === 1 || value === '1')) { return true; } if (typeof value === 'string' && /^vip$/i.test(value.trim())) return true; } return false; } export function purchaseProbability(input: { daysSinceContact: number | null; openDealCount: number; quoteCount: number; hasUpcoming: boolean; noteCount: number; }): { score: number; band: ProbabilityBand } { let score = 38; if (input.openDealCount > 0) score += 16 + Math.min(8, input.openDealCount * 2); if (input.quoteCount > 0) score += 8; if (input.noteCount > 0) score += 4; if (input.hasUpcoming) score += 6; if (input.daysSinceContact != null) { if (input.daysSinceContact <= 2) score += 24; else if (input.daysSinceContact <= 7) score += 18; else if (input.daysSinceContact <= 14) score += 8; else if (input.daysSinceContact <= 30) score += 2; else score -= 10; } else { score -= 6; } score = Math.max(8, Math.min(95, Math.round(score))); const band: ProbabilityBand = score >= 70 ? 'بالا' : score >= 45 ? 'متوسط' : 'پایین'; return { score, band }; } export function buildSmartSummary(input: { memories: MemoryItemDto[]; notes: NoteDto[]; lastQuoteLabel: string | null; daysSinceCall: number | null; probabilityBand: ProbabilityBand; }): { text: string; cta: string; ctaKind: 'call' | 'activity' } { const parts: string[] = []; const memoryBits = input.memories .map((m) => m.content.trim()) .filter(Boolean) .slice(0, 2); if (memoryBits.length) { parts.push(memoryBits.join(' ')); } else { const note = input.notes.find((n) => n.body.trim()); if (note?.body) { const snippet = note.body.replace(/\s+/g, ' ').trim(); parts.push(snippet.length > 90 ? `${snippet.slice(0, 90)}…` : snippet); } } if (input.lastQuoteLabel) { parts.push(`آخرین پیشنهاد ${input.lastQuoteLabel} بوده.`); } if (input.daysSinceCall != null) { if (input.daysSinceCall <= 0) parts.push('امروز با مشتری تماس گرفته شده.'); else parts.push(`${input.daysSinceCall} روز از آخرین تماس گذشته`); } parts.push(`و احتمال خرید ${input.probabilityBand} است.`); const hasSignal = memoryBits.length > 0 || input.notes.length > 0 || input.lastQuoteLabel; const text = hasSignal ? parts.join(' ').replace(/\s+/g, ' ').trim() : `هنوز خلاصهٔ پایداری از این مشتری ثبت نشده. با یادداشت یا حافظهٔ ${brand.nameFa}، پیشنهاد هوشمند اینجا ظاهر می‌شود.`; let cta = brandSuggestionFa('امروز با مشتری تماس بگیر'); let ctaKind: 'call' | 'activity' = 'call'; if (input.daysSinceCall != null && input.daysSinceCall <= 1) { cta = brandSuggestionFa('پیگیری بعدی را ثبت کن'); ctaKind = 'activity'; } return { text, cta, ctaKind }; }