import type { Achievement, CoinTransaction, Lecture, Notification, Review, User, UserRole, } from '@/types' import type { AchievementDto, CoinTransactionDto, LectureDto, ReviewDto, CurrentUserDto, UserAuthDto, UserDto, UserStatsDto, UserAchievementDto, UserNotificationDto, } from './types' export function mapApiRole(role: string | undefined): UserRole { if (role === 'Teacher') return 'teacher' if (role === 'Admin') return 'admin' return 'student' } function mapApiRoles(roles: string[] | undefined): UserRole[] { if (!roles?.length) return ['student'] return Array.from(new Set(roles.map(mapApiRole))) } function getDefaultActiveRole(roles: UserRole[]): UserRole { if (roles.includes('admin')) return 'admin' if (roles.includes('teacher')) return 'teacher' if (roles.includes('student')) return 'student' return 'student' } export function mapApiUser( user: UserAuthDto | UserDto | CurrentUserDto, stats?: UserStatsDto, ): User { const roles = mapApiRoles(user.roles) return { id: user.id, name: user.displayName || user.email || 'Пользователь UniVerse', email: user.email || '', roles, activeRole: getDefaultActiveRole(roles), avatar: 'avatarUrl' in user ? (user.avatarUrl ?? undefined) : undefined, institute: 'ЮФУ', department: '', year: 0, direction: '', coins: stats?.coins ?? ('coins' in user ? user.coins : 0), level: stats?.level ?? ('level' in user ? user.level : 1), xp: stats?.xp ?? ('xp' in user ? user.xp : 0), currentLevelXp: stats?.currentLevelXp ?? 0, nextLevelXp: stats?.nextLevelXp, lecturesAttended: stats?.attendedLectures ?? 0, hoursLearned: stats ? Math.round(stats.attendedLectures * 1.5 * 10) / 10 : 0, achievements: stats ? Array.from({ length: stats.achievementsCount }, (_, index) => String(index + 1)) : [], activeEnrollments: stats?.activeEnrollments, enrollmentSlotLimit: stats?.enrollmentSlotLimit, enrollmentSlotRules: stats?.enrollmentSlotRules, } } export function mapApiLecture(lecture: LectureDto): Lecture { const startsAt = new Date(lecture.startsAt) const endsAt = new Date(lecture.endsAt) const durationMs = endsAt.getTime() - startsAt.getTime() const duration = Number.isFinite(durationMs) && durationMs > 0 ? Math.round(durationMs / 60000) : 90 const totalSeats = lecture.maxEnrollments || 0 const enrolled = lecture.enrollmentsCount || 0 const freeSeats = Math.max(totalSeats - enrolled, 0) const locationName = lecture.locationName || (lecture.format === 'Online' ? 'Онлайн' : 'Аудитория уточняется') return { id: String(lecture.id), teacherId: lecture.teacherId, title: lecture.title || lecture.courseName || 'Лекция без названия', description: lecture.description || 'Описание появится позже.', teacher: lecture.teacherName || 'Преподаватель уточняется', teacherTitle: '', department: '', institute: lecture.courseName || 'ЮФУ', date: startsAt.toISOString().slice(0, 10), time: startsAt.toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' }), duration, building: lecture.format === 'Online' ? 'Онлайн' : locationName, room: undefined, format: lecture.format === 'Online' ? 'online' : 'offline', totalSeats, enrolledSeats: enrolled, freeSeats, registrationClosed: !lecture.isOpen, tags: lecture.courseName ? [`#${lecture.courseName}`] : [], rating: 0, reviewCount: 0, status: startsAt.getTime() > Date.now() ? 'upcoming' : 'completed', registered: lecture.isEnrolled, } } export function mapApiReview(review: ReviewDto): Review { const sentiment = review.sentiment === 'Positive' ? 'positive' : review.sentiment === 'Negative' ? 'negative' : 'neutral' const status = review.llmStatus === 'Rejected' ? 'rejected' : review.llmStatus === 'Analyzed' ? 'done' : 'pending' return { id: String(review.id), lectureId: String(review.lectureId), userId: String(review.userId), userName: review.userName || 'Анонимный отзыв', text: review.text || '', sentiment, createdAt: review.createdAt, status, quality: review.qualityScore ?? undefined, } } export function mapApiAchievement(input: AchievementDto | UserAchievementDto): Achievement { const dto = 'achievement' in input ? input.achievement : input const awardedAt = 'achievement' in input ? input.awardedAt : undefined return { id: String(dto.id), title: dto.name || 'Достижение', description: dto.description || dto.condition || '', icon: dto.iconUrl || '⭐', unlocked: Boolean(awardedAt), unlockedAt: awardedAt, coins: dto.coinReward, } } export function mapApiCoinTransaction(transaction: CoinTransactionDto): CoinTransaction { return { id: String(transaction.id), date: transaction.createdAt.slice(0, 10), description: transaction.description || transaction.type, amount: transaction.amount, type: transaction.amount >= 0 ? 'earned' : 'spent', } } export function mapApiNotification(notification: UserNotificationDto): Notification { return { id: String(notification.id), type: notification.type, title: notification.title, body: notification.body, read: notification.isRead, createdAt: notification.createdAt, } }