package training

import (
	"context"
	"encoding/json"
	"time"

	"github.com/google/uuid"
)

// CreateQuizQuestion creates a new quiz question
func (s *Store) CreateQuizQuestion(ctx context.Context, q *QuizQuestion) error {
	q.ID = uuid.New()
	q.CreatedAt = time.Now().UTC()
	if !q.IsActive {
		q.IsActive = true
	}

	options, _ := json.Marshal(q.Options)

	_, err := s.pool.Exec(ctx, `
		INSERT INTO training_quiz_questions (
			id, module_id, question, options, correct_index,
			explanation, difficulty, is_active, sort_order, created_at
		) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
	`,
		q.ID, q.ModuleID, q.Question, options, q.CorrectIndex,
		q.Explanation, string(q.Difficulty), q.IsActive, q.SortOrder, q.CreatedAt,
	)

	return err
}

// ListQuizQuestions lists quiz questions for a module
func (s *Store) ListQuizQuestions(ctx context.Context, moduleID uuid.UUID) ([]QuizQuestion, error) {
	rows, err := s.pool.Query(ctx, `
		SELECT
			id, module_id, question, options, correct_index,
			explanation, difficulty, is_active, sort_order, created_at
		FROM training_quiz_questions
		WHERE module_id = $1 AND is_active = true
		ORDER BY sort_order ASC, created_at ASC
	`, moduleID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var questions []QuizQuestion
	for rows.Next() {
		var q QuizQuestion
		var options []byte
		var difficulty string

		err := rows.Scan(
			&q.ID, &q.ModuleID, &q.Question, &options, &q.CorrectIndex,
			&q.Explanation, &difficulty, &q.IsActive, &q.SortOrder, &q.CreatedAt,
		)
		if err != nil {
			return nil, err
		}

		q.Difficulty = Difficulty(difficulty)
		json.Unmarshal(options, &q.Options)
		if q.Options == nil {
			q.Options = []string{}
		}

		questions = append(questions, q)
	}

	if questions == nil {
		questions = []QuizQuestion{}
	}

	return questions, nil
}

// CreateQuizAttempt records a quiz attempt
func (s *Store) CreateQuizAttempt(ctx context.Context, attempt *QuizAttempt) error {
	attempt.ID = uuid.New()
	attempt.AttemptedAt = time.Now().UTC()

	answers, _ := json.Marshal(attempt.Answers)

	_, err := s.pool.Exec(ctx, `
		INSERT INTO training_quiz_attempts (
			id, assignment_id, user_id, answers, score,
			passed, correct_count, total_count, duration_seconds, attempted_at
		) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
	`,
		attempt.ID, attempt.AssignmentID, attempt.UserID, answers, attempt.Score,
		attempt.Passed, attempt.CorrectCount, attempt.TotalCount, attempt.DurationSeconds, attempt.AttemptedAt,
	)

	return err
}

// ListQuizAttempts lists quiz attempts for an assignment
func (s *Store) ListQuizAttempts(ctx context.Context, assignmentID uuid.UUID) ([]QuizAttempt, error) {
	rows, err := s.pool.Query(ctx, `
		SELECT
			id, assignment_id, user_id, answers, score,
			passed, correct_count, total_count, duration_seconds, attempted_at
		FROM training_quiz_attempts
		WHERE assignment_id = $1
		ORDER BY attempted_at DESC
	`, assignmentID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var attempts []QuizAttempt
	for rows.Next() {
		var a QuizAttempt
		var answers []byte

		err := rows.Scan(
			&a.ID, &a.AssignmentID, &a.UserID, &answers, &a.Score,
			&a.Passed, &a.CorrectCount, &a.TotalCount, &a.DurationSeconds, &a.AttemptedAt,
		)
		if err != nil {
			return nil, err
		}

		json.Unmarshal(answers, &a.Answers)
		if a.Answers == nil {
			a.Answers = []QuizAnswer{}
		}

		attempts = append(attempts, a)
	}

	if attempts == nil {
		attempts = []QuizAttempt{}
	}

	return attempts, nil
}
