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 { adminExams, examParticipants } from '@/services/mock/fixtures/admin-exams' import { filterDateRange, filterItems, findOrThrow, isoNow, makeId, paginate, removeById, updateById, } from '@/services/mock/helpers' const resolveCourseFromSession = (session) => { const courseId = session?.course?.id ?? session?.courseId if (courseId == null) return null return adminCourses.find((c) => c.id === Number(courseId)) || null } const sessionSnapshot = (session) => (session ? { id: session.id, title: session.title } : null) const courseSnapshot = (course) => (course ? { id: course.id, title: course.title } : null) register('GET', endpoints.getExamsList, ({ query }) => { let list = filterItems(adminExams, query, { title: 'includes', courseId: (item, v) => String(item.course?.id) === String(v), sessionId: (item, v) => String(item.sessionId) === String(v), termId: (item, v) => { const course = adminCourses.find((c) => c.id === Number(item.course?.id)) const termId = course?.termId ?? course?.term?.id ?? null return String(termId) === String(v) }, }) list = filterDateRange(list, query) const { data: items, meta } = paginate(list, query) return { success: true, message: 'OK', data: items, meta, } }) register('GET', endpoints.showExam, ({ params }) => ({ success: true, message: 'OK', data: findOrThrow(adminExams, params.id), })) register('POST', endpoints.addNewExam, ({ data }) => { const session = adminSessions.find((s) => s.id === Number(data.sessionId)) const course = resolveCourseFromSession(session) const item = { id: makeId(), sessionId: session?.id ?? Number(data.sessionId) ?? null, title: data.title || '', description: data.description || '', passScore: Number(data.passingScore ?? data.passScore) || 0, isActive: data.isActive ?? true, questions: [], // UI-only fallbacks for ExamItem / ExamDetailsModal. session: sessionSnapshot(session), sessionTitle: session?.title || '', course: courseSnapshot(course), courseTitle: course?.title || '', questionsCount: 0, createdAt: isoNow(), } adminExams.unshift(item) return { success: true, message: 'Exam created.', data: item, } }) register('PATCH', endpoints.updateExam, ({ params, data }) => { const patch = {} if (data.title !== undefined) patch.title = data.title if (data.description !== undefined) patch.description = data.description if (data.passingScore !== undefined) patch.passScore = Number(data.passingScore) || 0 if (data.passScore !== undefined) patch.passScore = Number(data.passScore) || 0 if (data.isActive !== undefined) patch.isActive = !!data.isActive if (data.sessionId !== undefined) { const session = adminSessions.find((s) => s.id === Number(data.sessionId)) const course = resolveCourseFromSession(session) patch.sessionId = session?.id ?? Number(data.sessionId) ?? null patch.session = sessionSnapshot(session) patch.sessionTitle = session?.title ?? '' patch.course = courseSnapshot(course) patch.courseTitle = course?.title ?? '' } return { success: true, message: 'Exam updated.', data: updateById(adminExams, params.id, patch), } }) register('DELETE', endpoints.deleteExam, ({ params }) => { removeById(adminExams, params.id) return { success: true, message: 'Exam deleted.', data: null } }) // POST /exams/:examId/questions — atomic question + options create. register('POST', endpoints.addExamQuestion, ({ params, data }) => { const exam = findOrThrow(adminExams, params.examId) const questionId = makeId() const options = Array.isArray(data.options) ? data.options : [] const question = { id: questionId, questionText: data.questionText || '', position: data.position ?? (exam.questions?.length ?? 0) + 1, options: options.map((opt, idx) => ({ id: questionId * 100 + idx + 1, optionText: opt.optionText || '', isCorrect: !!opt.isCorrect, })), } exam.questions = [...(exam.questions || []), question] exam.questionsCount = exam.questions.length return { success: true, message: 'Question added.', data: question, } }) // POST /questions/:questionId/options — single option append. register('POST', endpoints.addQuestionOption, ({ params, data }) => { for (const exam of adminExams) { const question = (exam.questions || []).find((q) => String(q.id) === String(params.questionId)) if (question) { const option = { id: makeId(), optionText: data.optionText || '', isCorrect: !!data.isCorrect, } question.options = [...(question.options || []), option] return { success: true, message: 'Option added.', data: option, } } } return { success: false, message: 'Question not found.', data: null } }) // FE-mock-only. register('GET', endpoints.getExamParticipants, ({ params, query }) => { const list = examParticipants.get(Number(params.examId)) || [] return paginate(list, query) }) register('GET', endpoints.showExamParticipant, ({ params }) => { const list = examParticipants.get(Number(params.examId)) || [] const found = list.find((p) => String(p.id) === String(params.participantId)) return { data: found || null } })