package handlers

import (
	"Yimaru-Backend/internal/domain"
	"strconv"

	"github.com/gofiber/fiber/v2"
)

// CreateAssessmentQuestion godoc
// @Summary Create assessment question
// @Description Creates a new assessment question using the unified questions system
// @Tags assessment-question
// @Accept json
// @Produce json
// @Param body body createQuestionReq true "Create question payload"
// @Success 201 {object} domain.Response
// @Failure 400 {object} domain.ErrorResponse
// @Failure 500 {object} domain.ErrorResponse
// @Router /api/v1/assessment/questions [post]
func (h *Handler) CreateAssessmentQuestion(c *fiber.Ctx) error {
	var req createQuestionReq
	if err := c.BodyParser(&req); err != nil {
		return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
			Message: "Invalid request body",
			Error:   err.Error(),
		})
	}

	if req.QuestionText == "" {
		return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
			Message: "Validation error",
			Error:   "question_text is required",
		})
	}

	// Build options input
	var options []domain.CreateQuestionOptionInput
	for _, opt := range req.Options {
		options = append(options, domain.CreateQuestionOptionInput{
			OptionText:  opt.OptionText,
			OptionOrder: opt.OptionOrder,
			IsCorrect:   opt.IsCorrect,
		})
	}

	// Build short answers input
	var shortAnswers []domain.CreateShortAnswerInput
	for _, sa := range req.ShortAnswers {
		shortAnswers = append(shortAnswers, domain.CreateShortAnswerInput{
			AcceptableAnswer: sa.AcceptableAnswer,
			MatchType:        sa.MatchType,
		})
	}

	input := domain.CreateQuestionInput{
		QuestionText:            req.QuestionText,
		QuestionType:            req.QuestionType,
		DifficultyLevel:         req.DifficultyLevel,
		Points:                  req.Points,
		Explanation:             req.Explanation,
		Tips:                    req.Tips,
		VoicePrompt:             req.VoicePrompt,
		SampleAnswerVoicePrompt: req.SampleAnswerVoicePrompt,
		Status:                  req.Status,
		Options:                 options,
		ShortAnswers:            shortAnswers,
	}

	question, err := h.assessmentSvc.CreateQuestion(c.Context(), input)
	if err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
			Message: "Failed to create assessment question",
			Error:   err.Error(),
		})
	}

	return c.Status(fiber.StatusCreated).JSON(domain.Response{
		Message:    "Assessment question created successfully",
		StatusCode: fiber.StatusCreated,
		Success:    true,
		Data: questionRes{
			ID:           question.ID,
			QuestionText: question.QuestionText,
			QuestionType: question.QuestionType,
			Status:       question.Status,
			CreatedAt:    question.CreatedAt.String(),
		},
	})
}

// ListAssessmentQuestions godoc
// @Summary List assessment questions
// @Description Returns all active assessment questions from the initial assessment set
// @Tags assessment-question
// @Produce json
// @Success 200 {array} domain.QuestionWithDetails
// @Failure 500 {object} domain.ErrorResponse
// @Router /api/v1/assessment/questions [get]
func (h *Handler) ListAssessmentQuestions(c *fiber.Ctx) error {
	questions, err := h.assessmentSvc.ListQuestions(c.Context())
	if err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
			Message: "Failed to fetch assessment questions",
			Error:   err.Error(),
		})
	}

	var questionResponses []questionRes
	for _, q := range questions {
		var options []optionRes
		for _, opt := range q.Options {
			options = append(options, optionRes{
				ID:          opt.ID,
				OptionText:  opt.OptionText,
				OptionOrder: opt.OptionOrder,
				IsCorrect:   opt.IsCorrect,
			})
		}

		var shortAnswers []shortAnswerRes
		for _, sa := range q.ShortAnswers {
			shortAnswers = append(shortAnswers, shortAnswerRes{
				ID:               sa.ID,
				AcceptableAnswer: sa.AcceptableAnswer,
				MatchType:        sa.MatchType,
			})
		}

		questionResponses = append(questionResponses, questionRes{
			ID:              q.ID,
			QuestionText:    q.QuestionText,
			QuestionType:    q.QuestionType,
			DifficultyLevel: q.DifficultyLevel,
			Points:          q.Points,
			Status:          q.Status,
			CreatedAt:       q.CreatedAt.String(),
			Options:         options,
			ShortAnswers:    shortAnswers,
		})
	}

	return c.Status(fiber.StatusOK).JSON(domain.Response{
		Message:    "Questions fetched successfully",
		Data:       questionResponses,
		Success:    true,
		StatusCode: 200,
	})
}

// GetAssessmentQuestionByID godoc
// @Summary Get assessment question by ID
// @Description Returns a single assessment question with its options or answer
// @Tags assessment-question
// @Produce json
// @Param id path int true "Question ID"
// @Success 200 {object} domain.QuestionWithDetails
// @Failure 400 {object} domain.ErrorResponse
// @Failure 404 {object} domain.ErrorResponse
// @Failure 500 {object} domain.ErrorResponse
// @Router /api/v1/assessment/questions/{id} [get]
func (h *Handler) GetAssessmentQuestionByID(c *fiber.Ctx) error {
	idStr := c.Params("id")
	id, err := strconv.ParseInt(idStr, 10, 64)
	if err != nil || id <= 0 {
		return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
			Message: "Invalid question ID",
			Error:   "question ID must be a positive integer",
		})
	}

	question, err := h.assessmentSvc.GetQuestionByID(c.Context(), id)
	if err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
			Message: "Failed to fetch assessment question",
			Error:   err.Error(),
		})
	}

	var options []optionRes
	for _, opt := range question.Options {
		options = append(options, optionRes{
			ID:          opt.ID,
			OptionText:  opt.OptionText,
			OptionOrder: opt.OptionOrder,
			IsCorrect:   opt.IsCorrect,
		})
	}

	var shortAnswers []shortAnswerRes
	for _, sa := range question.ShortAnswers {
		shortAnswers = append(shortAnswers, shortAnswerRes{
			ID:               sa.ID,
			AcceptableAnswer: sa.AcceptableAnswer,
			MatchType:        sa.MatchType,
		})
	}

	return c.Status(fiber.StatusOK).JSON(domain.Response{
		Message: "Question fetched successfully",
		Data: questionRes{
			ID:              question.ID,
			QuestionText:    question.QuestionText,
			QuestionType:    question.QuestionType,
			DifficultyLevel: question.DifficultyLevel,
			Points:          question.Points,
			Status:          question.Status,
			CreatedAt:       question.CreatedAt.String(),
			Options:         options,
			ShortAnswers:    shortAnswers,
		},
		Success:    true,
		StatusCode: 200,
	})
}
