import { register } from '@/services/mock/registry'
import { endpoints } from '@/services/api/endpoints'
import { adminCourses } from '@/services/mock/fixtures/admin-courses'
import { adminSessions } from '@/services/mock/fixtures/admin-sessions'
import { adminAssignments, assignmentSubmissions } from '@/services/mock/fixtures/admin-assignments'
import {
  filterDateRange,
  filterItems,
  findOrThrow,
  isoNow,
  makeId,
  paginate,
  removeById,
  updateById,
} from '@/services/mock/helpers'

const computeDurationDays = (start, end) => {
  if (!start || !end) return null
  const diff = Math.ceil((new Date(end).getTime() - new Date(start).getTime()) / 86_400_000)
  return diff >= 0 ? diff : null
}

const courseTermId = (courseId) => {
  if (courseId == null) return null
  const course = adminCourses.find((c) => c.id === Number(courseId))
  return course?.termId ?? course?.term?.id ?? null
}

register('GET', endpoints.getAssignmentsList, ({ query }) => {
  let list = filterItems(adminAssignments, query, {
    title: 'includes',
    courseId: (item, v) => String(item.course?.id) === String(v),
    sessionId: (item, v) => String(item.session?.id) === String(v),
    termId: (item, v) => String(courseTermId(item.course?.id)) === String(v),
  })
  list = filterDateRange(list, query)
  return paginate(list, query)
})

register('GET', endpoints.showAssignment, ({ params }) => ({
  data: findOrThrow(adminAssignments, params.id),
}))

register('POST', endpoints.addNewAssignment, ({ data }) => {
  const course = adminCourses.find((c) => c.id === Number(data.courseId))
  const sess = adminSessions.find((s) => s.id === Number(data.sessionId))
  const item = {
    id: makeId(),
    title: data.title || '',
    description: data.description || '',
    course: course ? { id: course.id, title: course.title } : null,
    courseTitle: course?.title || '',
    session: sess ? { id: sess.id, title: sess.title } : null,
    sessionTitle: sess?.title || '',
    startDate: data.startDate || '',
    endDate: data.endDate || '',
    durationDays: computeDurationDays(data.startDate, data.endDate),
    priority: data.priority || 'mandatory',
    submissionsCount: 0,
    attachments: data.attachments || [],
    createdAt: isoNow(),
  }
  adminAssignments.unshift(item)
  return { data: item }
})

register('PATCH', endpoints.updateAssignment, ({ params, data }) => {
  const course = adminCourses.find((c) => c.id === Number(data.courseId))
  const sess = adminSessions.find((s) => s.id === Number(data.sessionId))
  return {
    data: updateById(adminAssignments, params.id, {
      title: data.title,
      description: data.description,
      course: course ? { id: course.id, title: course.title } : undefined,
      courseTitle: course?.title,
      session: sess ? { id: sess.id, title: sess.title } : undefined,
      sessionTitle: sess?.title,
      startDate: data.startDate,
      endDate: data.endDate,
      durationDays: computeDurationDays(data.startDate, data.endDate),
      priority: data.priority,
      attachments: data.attachments || [],
    }),
  }
})

register('DELETE', endpoints.deleteAssignment, ({ params }) => {
  removeById(adminAssignments, params.id)
  return { data: { message: 'حذف موفق' } }
})

register('GET', endpoints.getAssignmentSubmissions, ({ params, query }) => {
  const list = assignmentSubmissions.get(Number(params.homeworkId)) || []
  return paginate(list, query)
})

// Backend `/homework-submissions/:submissionId` — submissions live flat, so we
// scan every homework's submission list to find the matching id.
const findSubmission = (submissionId) => {
  for (const list of assignmentSubmissions.values()) {
    const found = list.find((s) => String(s.id) === String(submissionId))
    if (found) return found
  }
  return null
}

register('GET', endpoints.showAssignmentSubmission, ({ params }) => ({
  data: findSubmission(params.submissionId),
}))

register('PATCH', endpoints.reviewAssignmentSubmission, ({ params, data }) => {
  const sub = findSubmission(params.submissionId)
  if (sub) {
    Object.assign(sub, {
      score: data.score ?? sub.score,
      status: data.status ?? sub.status,
      reviewerNote: data.reviewerNote ?? sub.reviewerNote,
    })
  }
  return { data: sub || null }
})
