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,
  }
}
