import type { ExamDetail, ExamQuestion, ExamResultItem, ExamSubmitResult, ExamSummary, SupervisorExamDraft } from '@/types/api'; import { apiRequest } from './api'; type RawExamQuestion = { id: number; questionType: string; stem: string; options?: string[]; correctAnswers?: string[]; score: number; explanation?: string; sortOrder?: number; }; type RawExamSummary = { id: number; title: string; projectCode?: string; positionCode?: string; status: string; totalScore: number; passScore: number; dueDate?: string | null; questionCount: number; targetCount: number; submissionCount: number; bestScore?: number | null; passed?: boolean | null; }; type RawExamDetail = Omit & { questions: RawExamQuestion[]; targets: ExamDetail['targets']; }; const normalizeSummary = (item: RawExamSummary): ExamSummary => ({ ...item, passingScore: item.passScore }); const normalizeDetail = (item: RawExamDetail): ExamDetail => ({ ...item, passingScore: item.passScore, questionCount: item.questions?.length || 0, targetCount: item.targets?.length || 0, submissionCount: 0, bestScore: null, passed: null, questions: (item.questions || []).map((question) => ({ id: question.id, format: question.questionType, stem: question.stem, options: question.options || [], score: question.score, answer: question.correctAnswers || [], explanation: question.explanation || '' })), targets: item.targets || [] }); const serializeDraft = (draft: SupervisorExamDraft) => ({ title: draft.title, projectCode: draft.projectCode, positionCode: draft.positionCode, passScore: draft.passScore, dueDate: draft.dueDate, targets: draft.targets, questions: draft.questions.map((question, index) => ({ id: question.id > 0 && question.id < 1_000_000_000 ? question.id : null, questionType: question.format, stem: question.stem, options: question.options, correctAnswers: Array.isArray(question.answer) ? question.answer : [String(question.answer || '')], score: question.score, explanation: question.explanation || '', sortOrder: index + 1 })) }); export const listMyExams = async () => (await apiRequest({ url: '/api/aihr/mobile/exams', method: 'GET', timeout: 15000 })).map(normalizeSummary); export const getMyExam = async (id: number) => normalizeDetail(await apiRequest({ url: `/api/aihr/mobile/exams/${id}`, method: 'GET', timeout: 15000 })); export const submitMyExam = (id: number, answers: Record, requestId: string) => apiRequest({ url: `/api/aihr/mobile/exams/${id}/submit`, method: 'POST', data: { requestId, answers: Object.entries(answers).map(([questionId, value]) => ({ questionId: Number(questionId), answers: Array.isArray(value) ? value : [String(value)] })) }, timeout: 30000 }); export const listSupervisorExams = async () => (await apiRequest({ url: '/api/aihr/mobile/exams/supervisor', method: 'GET', timeout: 15000 })).map(normalizeSummary); export const getSupervisorExam = async (id: number) => normalizeDetail(await apiRequest({ url: `/api/aihr/mobile/exams/supervisor/${id}`, method: 'GET', timeout: 15000 })); export const saveSupervisorExam = async (draft: SupervisorExamDraft) => normalizeDetail(await apiRequest({ url: '/api/aihr/mobile/exams/supervisor', method: 'POST', data: serializeDraft(draft), timeout: 30000 })); export const updateSupervisorExam = async (id: number, draft: SupervisorExamDraft) => normalizeDetail(await apiRequest({ url: `/api/aihr/mobile/exams/supervisor/${id}`, method: 'PUT', data: serializeDraft(draft), timeout: 30000 })); export const publishSupervisorExam = async (id: number, requestId: string) => normalizeDetail(await apiRequest({ url: `/api/aihr/mobile/exams/supervisor/${id}/publish`, method: 'POST', data: { requestId }, timeout: 30000 })); export const getSupervisorExamResults = (id: number) => apiRequest({ url: `/api/aihr/mobile/exams/supervisor/${id}/results`, method: 'GET', timeout: 15000 }); type RawAiGenerateResponse = { questions: RawExamQuestion[]; groundedFragments?: number; }; export const generateSupervisorExamQuestions = async (data: { positionCode: string; hints: string; count: number; formats: string[]; }): Promise<{ questions: ExamQuestion[]; groundedFragments: number }> => { const response = await apiRequest({ url: '/api/aihr/mobile/exams/supervisor/ai-generate', method: 'POST', data, timeout: 60000 }); return { groundedFragments: response.groundedFragments || 0, questions: (response.questions || []).map((question, index) => ({ id: Date.now() + index, format: question.questionType, stem: question.stem, options: question.options || [], score: question.score, answer: question.questionType === 'multiple' ? (question.correctAnswers || []) : (question.correctAnswers?.[0] || ''), explanation: question.explanation || '' })) }; };