package handlers

import (
	"net/http"

	"github.com/breakpilot/ai-compliance-sdk/internal/rbac"
	"github.com/breakpilot/ai-compliance-sdk/internal/training"
	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
)

// ============================================================================
// Quiz Endpoints
// ============================================================================

// GetQuiz returns quiz questions for a module
// GET /sdk/v1/training/quiz/:moduleId
func (h *TrainingHandlers) GetQuiz(c *gin.Context) {
	moduleID, err := uuid.Parse(c.Param("moduleId"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid module ID"})
		return
	}

	questions, err := h.store.ListQuizQuestions(c.Request.Context(), moduleID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	// Strip correct_index for the student-facing response
	type safeQuestion struct {
		ID         uuid.UUID `json:"id"`
		Question   string    `json:"question"`
		Options    []string  `json:"options"`
		Difficulty string    `json:"difficulty"`
	}

	safe := make([]safeQuestion, len(questions))
	for i, q := range questions {
		safe[i] = safeQuestion{
			ID:         q.ID,
			Question:   q.Question,
			Options:    q.Options,
			Difficulty: string(q.Difficulty),
		}
	}

	c.JSON(http.StatusOK, gin.H{
		"questions": safe,
		"total":     len(safe),
	})
}

// SubmitQuiz submits quiz answers and returns the score
// POST /sdk/v1/training/quiz/:moduleId/submit
func (h *TrainingHandlers) SubmitQuiz(c *gin.Context) {
	moduleID, err := uuid.Parse(c.Param("moduleId"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid module ID"})
		return
	}
	tenantID := rbac.GetTenantID(c)

	var req training.SubmitTrainingQuizRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// Get the correct answers
	questions, err := h.store.ListQuizQuestions(c.Request.Context(), moduleID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	// Build answer map
	questionMap := make(map[uuid.UUID]training.QuizQuestion)
	for _, q := range questions {
		questionMap[q.ID] = q
	}

	// Score the answers
	correctCount := 0
	totalCount := len(req.Answers)
	scoredAnswers := make([]training.QuizAnswer, len(req.Answers))

	for i, answer := range req.Answers {
		q, exists := questionMap[answer.QuestionID]
		correct := exists && answer.SelectedIndex == q.CorrectIndex

		scoredAnswers[i] = training.QuizAnswer{
			QuestionID:    answer.QuestionID,
			SelectedIndex: answer.SelectedIndex,
			Correct:       correct,
		}

		if correct {
			correctCount++
		}
	}

	score := float64(0)
	if totalCount > 0 {
		score = float64(correctCount) / float64(totalCount) * 100
	}

	// Get module for pass threshold
	module, _ := h.store.GetModule(c.Request.Context(), moduleID)
	threshold := 70
	if module != nil {
		threshold = module.PassThreshold
	}
	passed := score >= float64(threshold)

	// Record the attempt
	userID := rbac.GetUserID(c)
	attempt := &training.QuizAttempt{
		AssignmentID:    req.AssignmentID,
		UserID:          userID,
		Answers:         scoredAnswers,
		Score:           score,
		Passed:          passed,
		CorrectCount:    correctCount,
		TotalCount:      totalCount,
		DurationSeconds: req.DurationSeconds,
	}

	if err := h.store.CreateQuizAttempt(c.Request.Context(), attempt); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	// Update assignment quiz result
	// Count total attempts
	attempts, _ := h.store.ListQuizAttempts(c.Request.Context(), req.AssignmentID)
	h.store.UpdateAssignmentQuizResult(c.Request.Context(), req.AssignmentID, score, passed, len(attempts))

	// Audit log
	h.store.LogAction(c.Request.Context(), &training.AuditLogEntry{
		TenantID:   tenantID,
		UserID:     &userID,
		Action:     training.AuditActionQuizSubmitted,
		EntityType: training.AuditEntityQuiz,
		EntityID:   &attempt.ID,
		Details: map[string]interface{}{
			"module_id":     moduleID.String(),
			"score":         score,
			"passed":        passed,
			"correct_count": correctCount,
			"total_count":   totalCount,
		},
	})

	c.JSON(http.StatusOK, training.SubmitTrainingQuizResponse{
		AttemptID:    attempt.ID,
		Score:        score,
		Passed:       passed,
		CorrectCount: correctCount,
		TotalCount:   totalCount,
		Threshold:    threshold,
	})
}

// GetQuizAttempts returns quiz attempts for an assignment
// GET /sdk/v1/training/quiz/attempts/:assignmentId
func (h *TrainingHandlers) GetQuizAttempts(c *gin.Context) {
	assignmentID, err := uuid.Parse(c.Param("assignmentId"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid assignment ID"})
		return
	}

	attempts, err := h.store.ListQuizAttempts(c.Request.Context(), assignmentID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"attempts": attempts,
		"total":    len(attempts),
	})
}
