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

register('GET', endpoints.getTermsList, ({ query }) => {
  let list = filterItems(adminTerms, query, {
    title: 'includes',
    status: (item, v) => String(item.isActive ? 1 : 0) === String(v),
    activeOnly: (item, v) => (String(v) === '1' ? !!item.isActive : true),
  })
  list = filterDateRange(list, query, 'startDate')
  const { data: items, meta } = paginate(list, query)
  return {
    success: true,
    message: 'OK',
    data: { items, meta },
  }
})

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

register('POST', endpoints.addNewTerm, ({ data }) => {
  const coverFromUpload = data.imageId
    ? `https://picsum.photos/seed/term-${data.imageId}/200/200`
    : ''
  const term = makeTerm({
    id: makeId(),
    title: data.title || '',
    description: data.description || '',
    isActive: data.isActive ?? true,
    startsAt: data.startsAt ?? data.startDate ?? '',
    endsAt: data.endsAt ?? data.endDate ?? '',
    coverUrl: data.coverUrl ?? coverFromUpload,
    studentsCount: 0,
    coursesCount: 0,
    createdAt: isoNow(),
  })
  adminTerms.unshift(term)
  return {
    success: true,
    message: 'Term created.',
    data: term,
  }
})

register('PATCH', endpoints.updateTerm, ({ params, data }) => {
  const coverFromUpload = data.imageId
    ? `https://picsum.photos/seed/term-${data.imageId}/200/200`
    : undefined
  const startsAt = data.startsAt ?? data.startDate
  const endsAt = data.endsAt ?? data.endDate
  const coverUrl = data.coverUrl ?? coverFromUpload
  const patch = {}
  if (data.title !== undefined) patch.title = data.title
  if (data.description !== undefined) patch.description = data.description
  if (data.isActive !== undefined) patch.isActive = data.isActive
  if (startsAt !== undefined) {
    patch.startsAt = startsAt
    patch.startDate = startsAt
  }
  if (endsAt !== undefined) {
    patch.endsAt = endsAt
    patch.endDate = endsAt
  }
  if (coverUrl !== undefined) {
    patch.coverUrl = coverUrl
    patch.image = coverUrl
  }
  const updated = updateById(adminTerms, params.id, patch)
  return {
    success: true,
    message: 'Term updated.',
    data: updated,
  }
})

register('DELETE', endpoints.deleteTerm, ({ params }) => {
  removeById(adminTerms, params.id)
  return {
    success: true,
    message: 'Term deleted.',
    data: null,
  }
})

register('POST', endpoints.cloneTerm, ({ params }) => {
  const src = findOrThrow(adminTerms, params.id)
  const clone = { ...src, id: makeId(), title: `${src.title} (کپی)`, createdAt: isoNow() }
  adminTerms.unshift(clone)
  return { data: clone }
})

const studentSnapshot = (link) => {
  const user = adminUsers.find((u) => u.id === link.userId)
  return user ? { ...user, isOnLeave: link.isOnLeave } : null
}

register('GET', endpoints.listUserTerm, ({ params, query }) => {
  const links = termStudentLinks.get(Number(params.termId)) || []
  const list = links.map((element) => studentSnapshot(element)).filter(Boolean)
  return paginate(list, query)
})

register('POST', endpoints.addUserTerm, ({ params, data }) => {
  const termId = Number(params.termId)
  const links = termStudentLinks.get(termId) || []
  const ids = Array.isArray(data.userIds) ? data.userIds : []
  ids.forEach((userId) => {
    if (!links.some((l) => l.userId === Number(userId))) {
      links.push({ userId: Number(userId), isOnLeave: false })
    }
  })
  termStudentLinks.set(termId, links)
  const added = ids
    .map((id) => adminUsers.find((u) => u.id === Number(id)))
    .filter(Boolean)
    .map((u) => ({ ...u, isOnLeave: false }))
  const term = adminTerms.find((t) => t.id === termId)
  if (term) term.studentsCount = links.length
  return { data: added }
})

register('DELETE', endpoints.removeUserTerm, ({ params }) => {
  const termId = Number(params.termId)
  const links = termStudentLinks.get(termId) || []
  const idx = links.findIndex((l) => String(l.userId) === String(params.userId))
  if (idx !== -1) links.splice(idx, 1)
  termStudentLinks.set(termId, links)
  const term = adminTerms.find((t) => t.id === termId)
  if (term) term.studentsCount = links.length
  return { data: { message: 'حذف موفق' } }
})

register('POST', endpoints.changeLeaveStatus, ({ params, data }) => {
  const termId = Number(params.termId)
  const links = termStudentLinks.get(termId) || []
  const link = links.find((l) => String(l.userId) === String(params.userId))
  if (link) link.isOnLeave = !!data.setLeave
  return { data: { isOnLeave: !!data.setLeave } }
})

register('GET', endpoints.listCourseTerm, ({ params, query }) => {
  const termId = Number(params.termId)
  const list = adminCourses.filter((c) => Number(c.termId) === termId)
  return paginate(list, query)
})

register('POST', endpoints.addCourseTerm, ({ params, data }) => {
  const termId = Number(params.termId)
  const ids = Array.isArray(data.courseIds) ? data.courseIds : []
  const linked = []
  ids.forEach((id) => {
    const course = adminCourses.find((c) => Number(c.id) === Number(id))
    if (course) {
      course.termId = termId
      course.term = adminTerms.some((t) => t.id === termId)
        ? { id: termId, title: adminTerms.find((t) => t.id === termId).title }
        : course.term
      linked.push(course)
    }
  })
  return { data: linked }
})

register('DELETE', endpoints.removeCourseTerm, ({ params }) => {
  const courseId = Number(params.courseId)
  const course = adminCourses.find((c) => c.id === courseId)
  if (course) {
    course.termId = null
    course.term = null
  }
  return { data: { message: 'حذف موفق' } }
})
