import type { AnySession, SortCol, ResolvedCollaborator, SwotSession, MotivatorSession, YearReviewSession, WeeklyCheckInSession, WeatherSession, GifMoodSession, } from './workshop-session-types'; export function getResolvedCollaborator(session: AnySession): ResolvedCollaborator { if (session.workshopType === 'swot') return (session as SwotSession).resolvedCollaborator; if (session.workshopType === 'year-review') return (session as YearReviewSession).resolvedParticipant; if (session.workshopType === 'weekly-checkin') return (session as WeeklyCheckInSession).resolvedParticipant; if (session.workshopType === 'weather') { const s = session as WeatherSession; return { raw: s.user.name || s.user.email, matchedUser: { id: s.user.id, email: s.user.email, name: s.user.name } }; } if (session.workshopType === 'gif-mood') { const s = session as GifMoodSession; return { raw: s.user.name || s.user.email, matchedUser: { id: s.user.id, email: s.user.email, name: s.user.name } }; } return (session as MotivatorSession).resolvedParticipant; } export function getGroupKey(session: AnySession): string { const r = getResolvedCollaborator(session); return r.matchedUser ? `user:${r.matchedUser.id}` : `raw:${r.raw.trim().toLowerCase()}`; } export function groupByPerson(sessions: AnySession[]): Map { const grouped = new Map(); sessions.forEach((s) => { const key = getGroupKey(s); const existing = grouped.get(key); if (existing) existing.push(s); else grouped.set(key, [s]); }); grouped.forEach((arr) => arr.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime())); return grouped; } export function formatDate(date: Date | string): string { return new Date(date).toLocaleDateString('fr-FR', { day: 'numeric', month: 'short' }); } export function getMonthGroup(date: Date | string): string { return new Date(date).toLocaleDateString('fr-FR', { month: 'long', year: 'numeric' }); } export function getStatsText(session: AnySession): string { const isSwot = session.workshopType === 'swot'; const isYearReview = session.workshopType === 'year-review'; const isWeeklyCheckIn = session.workshopType === 'weekly-checkin'; const isWeather = session.workshopType === 'weather'; const isGifMood = session.workshopType === 'gif-mood'; if (isSwot) return `${(session as SwotSession)._count.items} items · ${(session as SwotSession)._count.actions} actions`; if (isYearReview) return `${(session as YearReviewSession)._count.items} items · ${(session as YearReviewSession).year}`; if (isWeeklyCheckIn) return `${(session as WeeklyCheckInSession)._count.items} items · ${formatDate((session as WeeklyCheckInSession).date)}`; if (isWeather) return `${(session as WeatherSession)._count.entries} membres · ${formatDate((session as WeatherSession).date)}`; if (isGifMood) return `${(session as GifMoodSession)._count.items} GIFs · ${formatDate((session as GifMoodSession).date)}`; return `${(session as MotivatorSession)._count.cards}/10 motivateurs`; } function getStatsSortValue(session: AnySession): number { if (session.workshopType === 'swot') return (session as SwotSession)._count.items; if (session.workshopType === 'year-review') return (session as YearReviewSession)._count.items; if (session.workshopType === 'weekly-checkin') return (session as WeeklyCheckInSession)._count.items; if (session.workshopType === 'weather') return (session as WeatherSession)._count.entries; if (session.workshopType === 'gif-mood') return (session as GifMoodSession)._count.items; return (session as MotivatorSession)._count.cards; } function getParticipantSortName(session: AnySession): string { const r = getResolvedCollaborator(session); return (r.matchedUser?.name || r.matchedUser?.email?.split('@')[0] || r.raw).toLowerCase(); } function getCreatorName(session: AnySession): string { return (session.user.name || session.user.email).toLowerCase(); } export function sortSessions(sessions: AnySession[], col: SortCol, dir: 'asc' | 'desc'): AnySession[] { return [...sessions].sort((a, b) => { let cmp = 0; switch (col) { case 'type': cmp = a.workshopType.localeCompare(b.workshopType); break; case 'titre': cmp = a.title.localeCompare(b.title, 'fr'); break; case 'createur': cmp = getCreatorName(a).localeCompare(getCreatorName(b), 'fr'); break; case 'participant': cmp = getParticipantSortName(a).localeCompare(getParticipantSortName(b), 'fr'); break; case 'stats': cmp = getStatsSortValue(a) - getStatsSortValue(b); break; case 'date': cmp = new Date(a.updatedAt).getTime() - new Date(b.updatedAt).getTime(); break; } return dir === 'asc' ? cmp : -cmp; }); }