import { api } from "@/lib/api-client"; import { asPaginated, asRecordData } from "@/lib/odoo-api"; import type { User } from "@/types/auth"; import type { Course, Batch, TimetableSession, AttendanceRecord, GradeRecord, CourseCreateRequest, PaginatedResponse, PaginationParams, ApiSuccessResponse, LmsStudentRecord, LmsTeacherRecord, LmsStudentCreateRequest, LmsTeacherCreateRequest, } from "@/types"; function mapCourseRaw(r: Record): Course { const status = (r.status as Course["status"]) || "draft"; const enrolled = Number(r.student_count ?? 0); const maxCap = Number(r.max_capacity ?? 0); return { id: r.id as number, title: (r.title as string) || (r.name as string) || "", code: (r.code as string) || "", subject_id: Array.isArray(r.subject_ids) && (r.subject_ids as number[]).length ? (r.subject_ids as number[])[0] : undefined, subject_name: Array.isArray(r.subject_names) ? String((r.subject_names as string[])[0] || "") : "", instructor_id: 0, instructor_name: "", description: (r.description as string) || "", level: "Beginner", modules: [], enrolled, max_capacity: maxCap, status, start_date: "", end_date: "", }; } function mapBatchRaw(r: Record): Batch { const st = String(r.status || "draft"); const statusMap: Record = { draft: "upcoming", active: "active", completed: "completed", }; return { id: r.id as number, name: String(r.name || ""), course_id: Number(r.course_id || 0), course_name: String(r.course_name || ""), teacher_id: 0, teacher_name: "", student_ids: [], student_count: 0, start_date: String(r.start_date || ""), end_date: String(r.end_date || ""), schedule: "", status: statusMap[st] || "upcoming", capacity: Number(r.max_students ?? 0), }; } /** Map OpenEduCat student for screens that still expect `User` (admin tables). */ export function lmsStudentToUser(s: LmsStudentRecord): User { const active = s.status === "active"; return { id: s.id, name: s.name, email: s.email || "", login: s.email || "", user_type: "student", phone: s.phone || undefined, gender: s.gender || undefined, student_id: String(s.id), is_verified: active, entities: s.batch_id != null ? [{ id: s.batch_id, name: s.batch_name || "Batch" }] : [], classrooms: [], }; } export function lmsTeacherToUser(t: LmsTeacherRecord): User { return { id: t.id, name: t.name, email: t.email || "", login: t.email || "", user_type: "teacher", phone: t.phone || undefined, gender: t.gender || undefined, is_verified: true, entities: t.department_id ? [{ id: t.department_id, name: t.department_name || "Department" }] : [], classrooms: [], }; } export const lmsService = { async listCourses(params?: PaginationParams & { status?: string }): Promise> { const raw = await api.get("/courses", params as Record); const p = asPaginated>(raw); return { ...p, items: p.items.map(mapCourseRaw) }; }, async getCourse(id: number): Promise { const raw = await api.get(`/courses/${id}`); return mapCourseRaw(asRecordData>(raw)); }, async createCourse(data: CourseCreateRequest): Promise { const raw = await api.post("/courses", { name: data.title, code: data.code, description: data.description, max_capacity: data.max_capacity, status: "draft", }); return mapCourseRaw(asRecordData>(raw)); }, async updateCourse(id: number, data: Partial): Promise { const body: Record = {}; if (data.title != null) body.name = data.title; if (data.code != null) body.code = data.code; if (data.description != null) body.description = data.description; if (data.max_capacity != null) body.max_capacity = data.max_capacity; const raw = await api.patch(`/courses/${id}`, body); return mapCourseRaw(asRecordData>(raw)); }, async deleteCourse(id: number): Promise { return api.delete(`/courses/${id}`); }, async aiGenerateCourse(data: { title: string; subject_id?: number; level?: string }): Promise<{ outline: unknown }> { return api.post("/courses/ai-generate", data); }, async listBatches(params?: PaginationParams): Promise> { const raw = await api.get("/batches", params as Record); const p = asPaginated>(raw); return { ...p, items: p.items.map(mapBatchRaw) }; }, async getBatch(id: number): Promise { const raw = await api.get(`/batches/${id}`); return mapBatchRaw(asRecordData>(raw)); }, async createBatch(data: Partial): Promise { const raw = await api.post("/batches", data); return mapBatchRaw(asRecordData>(raw)); }, async updateBatch(id: number, data: Partial): Promise { const raw = await api.patch(`/batches/${id}`, data); return mapBatchRaw(asRecordData>(raw)); }, async deleteBatch(id: number): Promise { return api.delete(`/batches/${id}`); }, async listStudents(params?: PaginationParams & { search?: string; batch_id?: number }): Promise> { const raw = await api.get("/students", params as Record); return asPaginated(raw); }, async getStudent(id: number): Promise { const raw = await api.get(`/students/${id}`); return asRecordData(raw); }, async createStudent(data: LmsStudentCreateRequest): Promise { const raw = await api.post("/students", data); return asRecordData(raw); }, async updateStudent(id: number, data: Partial): Promise { const raw = await api.patch(`/students/${id}`, data); return asRecordData(raw); }, async listTeachers(params?: PaginationParams & { search?: string }): Promise> { const raw = await api.get("/teachers", params as Record); return asPaginated(raw); }, async createTeacher(data: LmsTeacherCreateRequest): Promise { const raw = await api.post("/teachers", data); return asRecordData(raw); }, async getTimetable(params?: { course_id?: number; teacher_id?: number; batch_id?: number }): Promise { const raw = await api.get<{ data: TimetableSession[] } | TimetableSession[]>("/timetable", params as Record); return Array.isArray(raw) ? raw : (raw as { data: TimetableSession[] }).data ?? []; }, async createTimetableSession(data: Partial): Promise { return api.post("/timetable", data); }, async deleteTimetableSession(id: number): Promise { return api.delete(`/timetable/${id}`); }, async getAttendance(params?: { course_id?: number; student_id?: number; date?: string }): Promise { const raw = await api.get<{ data: AttendanceRecord[] } | AttendanceRecord[]>("/attendance", params as Record); return Array.isArray(raw) ? raw : (raw as { data: AttendanceRecord[] }).data ?? []; }, async recordAttendance(data: { course_id: number; date: string; records: { student_id: number; status: string }[] }): Promise { return api.post("/attendance", data); }, async getGrades(params?: { course_id?: number; student_id?: number }): Promise { const raw = await api.get<{ data: GradeRecord[] } | GradeRecord[]>("/grades", params as Record); return Array.isArray(raw) ? raw : (raw as { data: GradeRecord[] }).data ?? []; }, };