package handlers import ( "net/http" "github.com/breakpilot/school-service/internal/models" "github.com/gin-gonic/gin" ) // CreateExam creates a new exam func (h *Handler) CreateExam(c *gin.Context) { teacherID := getUserID(c) if teacherID == "" { respondError(c, http.StatusUnauthorized, "User not authenticated") return } var req models.CreateExamRequest if err := c.ShouldBindJSON(&req); err != nil { respondError(c, http.StatusBadRequest, "Invalid request: "+err.Error()) return } exam, err := h.examService.CreateExam(c.Request.Context(), teacherID, &req) if err != nil { respondError(c, http.StatusInternalServerError, "Failed to create exam: "+err.Error()) return } respondCreated(c, exam) } // GetExams returns all exams for the current teacher func (h *Handler) GetExams(c *gin.Context) { teacherID := getUserID(c) if teacherID == "" { respondError(c, http.StatusUnauthorized, "User not authenticated") return } exams, err := h.examService.GetExams(c.Request.Context(), teacherID) if err != nil { respondError(c, http.StatusInternalServerError, "Failed to get exams: "+err.Error()) return } respondSuccess(c, exams) } // GetExam returns a single exam func (h *Handler) GetExam(c *gin.Context) { teacherID := getUserID(c) examID := c.Param("id") if teacherID == "" { respondError(c, http.StatusUnauthorized, "User not authenticated") return } exam, err := h.examService.GetExam(c.Request.Context(), examID, teacherID) if err != nil { respondError(c, http.StatusNotFound, "Exam not found") return } respondSuccess(c, exam) } // UpdateExam updates an exam func (h *Handler) UpdateExam(c *gin.Context) { teacherID := getUserID(c) examID := c.Param("id") if teacherID == "" { respondError(c, http.StatusUnauthorized, "User not authenticated") return } var req models.CreateExamRequest if err := c.ShouldBindJSON(&req); err != nil { respondError(c, http.StatusBadRequest, "Invalid request: "+err.Error()) return } exam, err := h.examService.UpdateExam(c.Request.Context(), examID, teacherID, &req) if err != nil { respondError(c, http.StatusInternalServerError, "Failed to update exam: "+err.Error()) return } respondSuccess(c, exam) } // DeleteExam deletes an exam func (h *Handler) DeleteExam(c *gin.Context) { teacherID := getUserID(c) examID := c.Param("id") if teacherID == "" { respondError(c, http.StatusUnauthorized, "User not authenticated") return } if err := h.examService.DeleteExam(c.Request.Context(), examID, teacherID); err != nil { respondError(c, http.StatusInternalServerError, "Failed to delete exam: "+err.Error()) return } c.JSON(http.StatusOK, gin.H{"message": "Exam deleted"}) } // GenerateExamVariant generates a variant of an exam using AI func (h *Handler) GenerateExamVariant(c *gin.Context) { teacherID := getUserID(c) examID := c.Param("id") if teacherID == "" { respondError(c, http.StatusUnauthorized, "User not authenticated") return } var req models.GenerateExamVariantRequest if err := c.ShouldBindJSON(&req); err != nil { respondError(c, http.StatusBadRequest, "Invalid request: "+err.Error()) return } // Get the original exam originalExam, err := h.examService.GetExam(c.Request.Context(), examID, teacherID) if err != nil { respondError(c, http.StatusNotFound, "Original exam not found") return } // Generate variant content using AI newContent, err := h.aiService.GenerateExamVariant(c.Request.Context(), originalExam.Content, req.VariationType) if err != nil { respondError(c, http.StatusInternalServerError, "Failed to generate variant: "+err.Error()) return } // Create the variant exam variant, err := h.examService.CreateExamVariant(c.Request.Context(), examID, teacherID, newContent, req.VariationType) if err != nil { respondError(c, http.StatusInternalServerError, "Failed to save variant: "+err.Error()) return } respondCreated(c, variant) } // SaveExamResults saves results for students func (h *Handler) SaveExamResults(c *gin.Context) { examID := c.Param("id") var req models.UpdateExamResultRequest if err := c.ShouldBindJSON(&req); err != nil { respondError(c, http.StatusBadRequest, "Invalid request: "+err.Error()) return } result, err := h.examService.SaveExamResult(c.Request.Context(), examID, &req) if err != nil { respondError(c, http.StatusInternalServerError, "Failed to save result: "+err.Error()) return } respondSuccess(c, result) } // GetExamResults returns all results for an exam func (h *Handler) GetExamResults(c *gin.Context) { examID := c.Param("id") results, err := h.examService.GetExamResults(c.Request.Context(), examID) if err != nil { respondError(c, http.StatusInternalServerError, "Failed to get results: "+err.Error()) return } respondSuccess(c, results) } // ApproveExamResult approves a result for grade transfer func (h *Handler) ApproveExamResult(c *gin.Context) { examID := c.Param("id") studentID := c.Param("studentId") if err := h.examService.ApproveExamResult(c.Request.Context(), examID, studentID); err != nil { respondError(c, http.StatusInternalServerError, "Failed to approve result: "+err.Error()) return } c.JSON(http.StatusOK, gin.H{"message": "Result approved"}) } // GetStudentsNeedingRewrite returns students who need to rewrite func (h *Handler) GetStudentsNeedingRewrite(c *gin.Context) { examID := c.Param("id") students, err := h.examService.GetStudentsNeedingRewrite(c.Request.Context(), examID) if err != nil { respondError(c, http.StatusInternalServerError, "Failed to get students: "+err.Error()) return } respondSuccess(c, students) }