import { register } from '@/services/mock/registry'
import { endpoints } from '@/services/api/endpoints'
import { adminTerms } from '@/services/mock/fixtures/admin-terms'
import { adminUsers } from '@/services/mock/fixtures/admin-users'
import { adminCourses, makeTeacherSnapshot } from '@/services/mock/fixtures/admin-courses'
import {
  filterDateRange,
  filterItems,
  findOrThrow,
  isoNow,
  makeId,
  paginate,
  removeById,
  updateById,
} from '@/services/mock/helpers'

const resolveTermId = (raw) => {
  if (raw === undefined || raw === null || raw === '') return null
  if (raw === 'null') return null
  const n = Number(raw)
  return Number.isFinite(n) ? n : null
}

const resolveTeacher = (rawId) => {
  const id = Number(rawId)
  const source = adminUsers.find((u) => u.id === id)
  if (!source) return null
  return makeTeacherSnapshot({
    id: source.id,
    firstName: source.firstName,
    lastName: source.lastName,
    name: source.name,
    email: source.email,
    phone: source.phone,
    roles: source.roles,
    avatarUrl: source.avatarUrl,
    avatarDownloadUrl: source.avatarDownloadUrl,
    createdAt: source.createdAt,
  })
}

register('GET', endpoints.getCoursesList, ({ query }) => {
  let list = adminCourses
  if (query?.termId !== undefined && query?.termId !== '') {
    if (String(query.termId) === 'null') {
      list = list.filter((c) => c.termId == null)
    } else {
      const tid = Number(query.termId)
      list = list.filter((c) => c.termId === tid)
    }
  }
  const { termId: _omitted, ...rest } = query || {}
  list = filterItems(list, rest, {
    title: 'includes',
    status: (item, v) => String(item.isActive ? 1 : 0) === String(v),
  })
  list = filterDateRange(list, rest, 'startDate')
  const { data: items, meta } = paginate(list, rest)
  return {
    success: true,
    message: 'OK',
    data: { items, meta },
  }
})

register('GET', endpoints.showCourse, ({ params }) => ({
  success: true,
  message: 'OK',
  data: findOrThrow(adminCourses, params.id),
}))

register('POST', endpoints.addNewCourse, ({ data }) => {
  const termId = resolveTermId(data.termId)
  const term = termId == null ? null : adminTerms.find((t) => t.id === termId)
  const teacher = resolveTeacher(data.teacherId)
  const coverFromUpload = data.imageId
    ? `https://picsum.photos/seed/course-${data.imageId}/200/200`
    : ''
  const coverUrl = data.coverUrl ?? coverFromUpload
  const item = {
    id: makeId(),
    termId: term?.id ?? termId ?? null,
    teacherId: teacher?.id ?? (Number(data.teacherId) || null),
    title: data.title || '',
    description: data.description || '',
    capacity: Number(data.capacity) || 0,
    isActive: data.isActive === undefined ? true : !!data.isActive,
    coverUrl,
    image: coverUrl,
    teacher,
    term: term ? { id: term.id, title: term.title } : null,
    sessionsCount: Number(data.sessionsCount) || 0,
    prerequisitesCount: (data.prerequisites || []).length,
    prerequisites: (data.prerequisites || []).map((id) => ({
      courseId: id,
      course: adminCourses.find((c) => c.id === Number(id)) || { id },
    })),
    startDate: term?.startDate || '',
    endDate: term?.endDate || '',
    createdAt: isoNow(),
  }
  adminCourses.unshift(item)
  return {
    success: true,
    message: 'Course created.',
    data: item,
  }
})

register('PATCH', endpoints.updateCourse, ({ params, data }) => {
  const patch = {}
  if (data.title !== undefined) patch.title = data.title
  if (data.description !== undefined) patch.description = data.description
  if (data.capacity !== undefined) patch.capacity = Number(data.capacity) || 0
  if (data.sessionsCount !== undefined) patch.sessionsCount = Number(data.sessionsCount) || 0
  if (data.isActive !== undefined) patch.isActive = !!data.isActive
  if (data.termId !== undefined) {
    const termId = resolveTermId(data.termId)
    patch.termId = termId
    const term = termId == null ? null : adminTerms.find((t) => t.id === termId)
    patch.term = term ? { id: term.id, title: term.title } : null
  }
  if (data.teacherId !== undefined) {
    const teacher = resolveTeacher(data.teacherId)
    patch.teacherId = teacher?.id ?? null
    patch.teacher = teacher
  }
  if (data.prerequisites !== undefined) {
    patch.prerequisites = (data.prerequisites || []).map((id) => ({
      courseId: id,
      course: adminCourses.find((c) => c.id === Number(id)) || { id },
    }))
    patch.prerequisitesCount = (data.prerequisites || []).length
  }
  if (data.coverUrl !== undefined || data.imageId !== undefined) {
    const url =
      data.coverUrl ??
      (data.imageId ? `https://picsum.photos/seed/course-${data.imageId}/200/200` : '')
    patch.coverUrl = url
    patch.image = url
  }
  const updated = updateById(adminCourses, params.id, patch)
  return {
    success: true,
    message: 'Course updated.',
    data: updated,
  }
})

register('DELETE', endpoints.deleteCourse, ({ params }) => {
  removeById(adminCourses, params.id)
  return {
    success: true,
    message: 'Course deleted.',
    data: null,
  }
})
