package handlers import ( "log" "sno/internal/models" "sno/internal/service" "strconv" "github.com/gofiber/fiber/v2" ) // QuestionHandler handles HTTP requests for questions. type QuestionHandler struct { questionService service.QuestionService } // NewQuestionHandler creates a new instance of a question handler. func NewQuestionHandler(questionService service.QuestionService) *QuestionHandler { return &QuestionHandler{questionService: questionService} } // CreateQuestion handles the request to add a new question to a quiz. // @Summary Create question // @Description Adds a new question to a quiz (admin/operator only) // @Tags questions // @Accept json // @Produce json // @Param quiz_id path int true "Quiz ID" // @Param question body models.Question true "Question object" // @Success 201 {object} object{success=bool,message=string,data=models.Question} // @Failure 400 {object} object{success=bool,message=string} // @Failure 500 {object} object{success=bool,message=string} // @Router /api/admin/quizzes/{quiz_id}/questions [post] // @Security ApiKeyAuth func (h *QuestionHandler) CreateQuestion(c *fiber.Ctx) error { quizID, err := strconv.Atoi(c.Params("quiz_id")) if err != nil { return c.Status(fiber.StatusBadRequest).JSON(Response{ Success: false, Message: "Invalid quiz ID", }) } var question models.Question if err := c.BodyParser(&question); err != nil { return c.Status(fiber.StatusBadRequest).JSON(Response{ Success: false, Message: "Cannot parse JSON", }) } // Set the QuizID from the URL parameter question.QuizID = quizID createdQuestion, err := h.questionService.CreateQuestion(c.Context(), &question) if err != nil { log.Printf("ERROR: Failed to create question: %v", err) return c.Status(fiber.StatusInternalServerError).JSON(Response{ Success: false, Message: err.Error(), // Return the actual validation error message }) } return c.Status(fiber.StatusCreated).JSON(Response{ Success: true, Message: "Question created successfully", Data: createdQuestion, }) } // UpdateQuestion handles the request to update an existing question. // @Summary Update question // @Description Updates an existing question (admin/operator only) // @Tags questions // @Accept json // @Produce json // @Param quiz_id path int true "Quiz ID" // @Param question_id path int true "Question ID" // @Param question body models.Question true "Updated question object" // @Success 200 {object} object{success=bool,message=string,data=models.Question} // @Failure 400 {object} object{success=bool,message=string} // @Failure 500 {object} object{success=bool,message=string} // @Router /api/admin/quizzes/{quiz_id}/questions/{question_id} [put] // @Security ApiKeyAuth func (h *QuestionHandler) UpdateQuestion(c *fiber.Ctx) error { quizID, err := strconv.Atoi(c.Params("quiz_id")) if err != nil { return c.Status(fiber.StatusBadRequest).JSON(Response{ Success: false, Message: "Invalid quiz ID", }) } questionID, err := strconv.Atoi(c.Params("question_id")) if err != nil { return c.Status(fiber.StatusBadRequest).JSON(Response{ Success: false, Message: "Invalid question ID", }) } var question models.Question if err := c.BodyParser(&question); err != nil { return c.Status(fiber.StatusBadRequest).JSON(Response{ Success: false, Message: "Cannot parse JSON", }) } // Ensure the question belongs to the specified quiz question.QuizID = quizID updatedQuestion, err := h.questionService.UpdateQuestion(c.Context(), questionID, &question) if err != nil { log.Printf("ERROR: Failed to update question: %v", err) return c.Status(fiber.StatusInternalServerError).JSON(Response{ Success: false, Message: err.Error(), }) } return c.Status(fiber.StatusOK).JSON(Response{ Success: true, Message: "Question updated successfully", Data: updatedQuestion, }) } // DeleteQuestion handles the request to delete a question. // @Summary Delete question // @Description Deletes a question (admin/operator only) // @Tags questions // @Accept json // @Produce json // @Param quiz_id path int true "Quiz ID" // @Param question_id path int true "Question ID" // @Success 200 {object} object{success=bool,message=string} // @Failure 400 {object} object{success=bool,message=string} // @Failure 500 {object} object{success=bool,message=string} // @Router /api/admin/quizzes/{quiz_id}/questions/{question_id} [delete] // @Security ApiKeyAuth func (h *QuestionHandler) DeleteQuestion(c *fiber.Ctx) error { questionID, err := strconv.Atoi(c.Params("question_id")) if err != nil { return c.Status(fiber.StatusBadRequest).JSON(Response{ Success: false, Message: "Invalid question ID", }) } err = h.questionService.DeleteQuestion(c.Context(), questionID) if err != nil { log.Printf("ERROR: Failed to delete question: %v", err) return c.Status(fiber.StatusInternalServerError).JSON(Response{ Success: false, Message: "Failed to delete question", }) } return c.Status(fiber.StatusOK).JSON(Response{ Success: true, Message: "Question deleted successfully", }) }