// Code generated by sqlc. DO NOT EDIT.
// versions:
//   sqlc v1.30.0
// source: student_answers.sql

package sqlc

import (
	"context"

	"github.com/jackc/pgx/v5/pgtype"
)

const listAnswersForAssignment = `-- name: ListAnswersForAssignment :many
SELECT id, assignment_id, question_id, student_id, answer_text, ai_feedback, teacher_feedback, status, submitted_at, reviewed_at, created_at, updated_at, solve_mode, working_steps, is_correct, review_needs_attention, review_issue_reason, review_correctness_score, review_understanding_score, review_question_score, review_confidence, review_tags
FROM student_answers
WHERE assignment_id = $1
ORDER BY created_at ASC
`

func (q *Queries) ListAnswersForAssignment(ctx context.Context, assignmentID int64) ([]StudentAnswer, error) {
	rows, err := q.db.Query(ctx, listAnswersForAssignment, assignmentID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []StudentAnswer{}
	for rows.Next() {
		var i StudentAnswer
		if err := rows.Scan(
			&i.ID,
			&i.AssignmentID,
			&i.QuestionID,
			&i.StudentID,
			&i.AnswerText,
			&i.AiFeedback,
			&i.TeacherFeedback,
			&i.Status,
			&i.SubmittedAt,
			&i.ReviewedAt,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.SolveMode,
			&i.WorkingSteps,
			&i.IsCorrect,
			&i.ReviewNeedsAttention,
			&i.ReviewIssueReason,
			&i.ReviewCorrectnessScore,
			&i.ReviewUnderstandingScore,
			&i.ReviewQuestionScore,
			&i.ReviewConfidence,
			&i.ReviewTags,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listAnswersForStudent = `-- name: ListAnswersForStudent :many
SELECT id, assignment_id, question_id, student_id, answer_text, ai_feedback, teacher_feedback, status, submitted_at, reviewed_at, created_at, updated_at, solve_mode, working_steps, is_correct, review_needs_attention, review_issue_reason, review_correctness_score, review_understanding_score, review_question_score, review_confidence, review_tags
FROM student_answers
WHERE student_id = $1
ORDER BY created_at DESC
`

func (q *Queries) ListAnswersForStudent(ctx context.Context, studentID int64) ([]StudentAnswer, error) {
	rows, err := q.db.Query(ctx, listAnswersForStudent, studentID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []StudentAnswer{}
	for rows.Next() {
		var i StudentAnswer
		if err := rows.Scan(
			&i.ID,
			&i.AssignmentID,
			&i.QuestionID,
			&i.StudentID,
			&i.AnswerText,
			&i.AiFeedback,
			&i.TeacherFeedback,
			&i.Status,
			&i.SubmittedAt,
			&i.ReviewedAt,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.SolveMode,
			&i.WorkingSteps,
			&i.IsCorrect,
			&i.ReviewNeedsAttention,
			&i.ReviewIssueReason,
			&i.ReviewCorrectnessScore,
			&i.ReviewUnderstandingScore,
			&i.ReviewQuestionScore,
			&i.ReviewConfidence,
			&i.ReviewTags,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listQuestionDetailsForAssignmentStudent = `-- name: ListQuestionDetailsForAssignmentStudent :many
WITH student_question_set AS (
    SELECT
        asq.assignment_id,
        asq.question_id,
        asq.position
    FROM assignment_student_questions asq
    WHERE asq.assignment_id = $1
      AND asq.student_id = $2
),
selected_questions AS (
    SELECT
        sq.assignment_id,
        sq.question_id,
        sq.position
    FROM student_question_set sq
    UNION ALL
    SELECT
        aq.assignment_id,
        aq.question_id,
        aq.position
    FROM assignment_questions aq
    WHERE aq.assignment_id = $1
      AND NOT EXISTS (SELECT 1 FROM student_question_set)
)
SELECT
    aq.assignment_id,
    aq.question_id,
    aq.position,
    q.title,
    q.prompt,
    q.subject,
    q.source,
    COALESCE(
        ARRAY(
            SELECT t.name
            FROM question_tags qt
            JOIN tags t ON t.id = qt.tag_id
            WHERE qt.question_id = aq.question_id
            ORDER BY t.name ASC
        ),
        ARRAY[]::TEXT[]
    )::TEXT[] AS question_tags,
    q.status AS question_status,
    q.correct_answer,
    aa.ai_feedback AS assignment_ai_feedback,
    aa.teacher_feedback AS assignment_teacher_feedback,
    review_summary.overall_score,
    a.pass_threshold,
    aa.next_step_outcome,
    aa.pass_status_override,
    COALESCE(
        aa.pass_status_override,
        CASE
            WHEN review_summary.overall_score IS NULL THEN 'pending'::assignment_pass_status
            WHEN review_summary.overall_score >= a.pass_threshold THEN 'pass'::assignment_pass_status
            ELSE 'no_pass'::assignment_pass_status
        END
    ) AS pass_status,
    sa.id AS answer_id,
    sa.student_id,
    sa.answer_text,
    sa.solve_mode,
    sa.working_steps,
    sa.is_correct,
    sa.ai_feedback,
    sa.teacher_feedback,
    sa.status AS answer_status,
    sa.review_needs_attention,
    sa.review_issue_reason,
    sa.review_correctness_score,
    sa.review_understanding_score,
    sa.review_question_score,
    sa.review_confidence,
    sa.review_tags,
    sa.submitted_at,
    sa.reviewed_at,
    sa.created_at AS answer_created_at,
    sa.updated_at AS answer_updated_at
 FROM selected_questions aq
 JOIN assignments a ON a.id = aq.assignment_id
 JOIN questions q ON q.id = aq.question_id
 LEFT JOIN assignment_assignees aa
    ON aa.assignment_id = aq.assignment_id
    AND aa.student_id = $2
 LEFT JOIN LATERAL (
     SELECT CASE
             WHEN COUNT(sa2.id) = 0 THEN NULL::NUMERIC(5,2)
             ELSE ROUND((AVG(
                CASE
                    WHEN sa2.is_correct IS NULL THEN COALESCE(sa2.review_understanding_score, 0)::NUMERIC
                    ELSE (
                        ((CASE WHEN sa2.is_correct THEN 1 ELSE 0 END)::NUMERIC) + COALESCE(sa2.review_understanding_score, 0)::NUMERIC
                    ) / 2
                END
             ) * 10)::NUMERIC, 2)::NUMERIC(5,2)
         END AS overall_score
    FROM selected_questions aq2
    LEFT JOIN student_answers sa2
        ON sa2.assignment_id = aq2.assignment_id
       AND sa2.question_id = aq2.question_id
       AND sa2.student_id = $2
    WHERE aq2.assignment_id = aq.assignment_id
) review_summary ON TRUE
LEFT JOIN student_answers sa
    ON sa.assignment_id = aq.assignment_id
   AND sa.question_id = aq.question_id
   AND sa.student_id = $2
WHERE aq.assignment_id = $1
ORDER BY aq.position ASC, aq.question_id ASC
`

type ListQuestionDetailsForAssignmentStudentParams struct {
	AssignmentID int64 `json:"assignment_id"`
	StudentID    int64 `json:"student_id"`
}

type ListQuestionDetailsForAssignmentStudentRow struct {
	AssignmentID              int64                         `json:"assignment_id"`
	QuestionID                int64                         `json:"question_id"`
	Position                  int32                         `json:"position"`
	Title                     string                        `json:"title"`
	Prompt                    string                        `json:"prompt"`
	Subject                   pgtype.Text                   `json:"subject"`
	Source                    pgtype.Text                   `json:"source"`
	QuestionTags              []string                      `json:"question_tags"`
	QuestionStatus            QuestionStatus                `json:"question_status"`
	CorrectAnswer             pgtype.Text                   `json:"correct_answer"`
	AssignmentAiFeedback      pgtype.Text                   `json:"assignment_ai_feedback"`
	AssignmentTeacherFeedback pgtype.Text                   `json:"assignment_teacher_feedback"`
	OverallScore              pgtype.Numeric                `json:"overall_score"`
	PassThreshold             pgtype.Numeric                `json:"pass_threshold"`
	NextStepOutcome           NullAssignmentNextStepOutcome `json:"next_step_outcome"`
	PassStatusOverride        NullAssignmentPassStatus      `json:"pass_status_override"`
	PassStatus                NullAssignmentPassStatus      `json:"pass_status"`
	AnswerID                  pgtype.Int8                   `json:"answer_id"`
	StudentID                 pgtype.Int8                   `json:"student_id"`
	AnswerText                pgtype.Text                   `json:"answer_text"`
	SolveMode                 pgtype.Text                   `json:"solve_mode"`
	WorkingSteps              pgtype.Text                   `json:"working_steps"`
	IsCorrect                 pgtype.Bool                   `json:"is_correct"`
	AiFeedback                pgtype.Text                   `json:"ai_feedback"`
	TeacherFeedback           pgtype.Text                   `json:"teacher_feedback"`
	AnswerStatus              NullAnswerStatus              `json:"answer_status"`
	ReviewNeedsAttention      pgtype.Bool                   `json:"review_needs_attention"`
	ReviewIssueReason         pgtype.Text                   `json:"review_issue_reason"`
	ReviewCorrectnessScore    pgtype.Numeric                `json:"review_correctness_score"`
	ReviewUnderstandingScore  pgtype.Numeric                `json:"review_understanding_score"`
	ReviewQuestionScore       pgtype.Numeric                `json:"review_question_score"`
	ReviewConfidence          pgtype.Numeric                `json:"review_confidence"`
	ReviewTags                []string                      `json:"review_tags"`
	SubmittedAt               pgtype.Timestamptz            `json:"submitted_at"`
	ReviewedAt                pgtype.Timestamptz            `json:"reviewed_at"`
	AnswerCreatedAt           pgtype.Timestamptz            `json:"answer_created_at"`
	AnswerUpdatedAt           pgtype.Timestamptz            `json:"answer_updated_at"`
}

func (q *Queries) ListQuestionDetailsForAssignmentStudent(ctx context.Context, arg ListQuestionDetailsForAssignmentStudentParams) ([]ListQuestionDetailsForAssignmentStudentRow, error) {
	rows, err := q.db.Query(ctx, listQuestionDetailsForAssignmentStudent, arg.AssignmentID, arg.StudentID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []ListQuestionDetailsForAssignmentStudentRow{}
	for rows.Next() {
		var i ListQuestionDetailsForAssignmentStudentRow
		if err := rows.Scan(
			&i.AssignmentID,
			&i.QuestionID,
			&i.Position,
			&i.Title,
			&i.Prompt,
			&i.Subject,
			&i.Source,
			&i.QuestionTags,
			&i.QuestionStatus,
			&i.CorrectAnswer,
			&i.AssignmentAiFeedback,
			&i.AssignmentTeacherFeedback,
			&i.OverallScore,
			&i.PassThreshold,
			&i.NextStepOutcome,
			&i.PassStatusOverride,
			&i.PassStatus,
			&i.AnswerID,
			&i.StudentID,
			&i.AnswerText,
			&i.SolveMode,
			&i.WorkingSteps,
			&i.IsCorrect,
			&i.AiFeedback,
			&i.TeacherFeedback,
			&i.AnswerStatus,
			&i.ReviewNeedsAttention,
			&i.ReviewIssueReason,
			&i.ReviewCorrectnessScore,
			&i.ReviewUnderstandingScore,
			&i.ReviewQuestionScore,
			&i.ReviewConfidence,
			&i.ReviewTags,
			&i.SubmittedAt,
			&i.ReviewedAt,
			&i.AnswerCreatedAt,
			&i.AnswerUpdatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listStudentPlanningPerformance = `-- name: ListStudentPlanningPerformance :many
SELECT
    sa.assignment_id,
    sa.question_id,
    q.topic,
    q.subject,
    q.difficulty,
    COALESCE(
        ARRAY(
            SELECT t.name
            FROM question_tags qt
            JOIN tags t ON t.id = qt.tag_id
            WHERE qt.question_id = sa.question_id
            ORDER BY t.name ASC
        ),
        ARRAY[]::TEXT[]
    )::TEXT[] AS question_tags,
    sa.is_correct,
    sa.review_understanding_score,
    sa.review_needs_attention,
    sa.review_issue_reason,
    sa.status,
    sa.submitted_at,
    sa.reviewed_at,
    sa.updated_at
FROM student_answers sa
JOIN questions q ON q.id = sa.question_id
WHERE sa.student_id = $1
  AND sa.status IN ('submitted'::answer_status, 'reviewed'::answer_status)
ORDER BY COALESCE(sa.reviewed_at, sa.submitted_at, sa.updated_at) DESC, sa.id DESC
`

type ListStudentPlanningPerformanceRow struct {
	AssignmentID             int64                  `json:"assignment_id"`
	QuestionID               int64                  `json:"question_id"`
	Topic                    NullQuestionTopic      `json:"topic"`
	Subject                  pgtype.Text            `json:"subject"`
	Difficulty               NullQuestionDifficulty `json:"difficulty"`
	QuestionTags             []string               `json:"question_tags"`
	IsCorrect                pgtype.Bool            `json:"is_correct"`
	ReviewUnderstandingScore pgtype.Numeric         `json:"review_understanding_score"`
	ReviewNeedsAttention     bool                   `json:"review_needs_attention"`
	ReviewIssueReason        pgtype.Text            `json:"review_issue_reason"`
	Status                   AnswerStatus           `json:"status"`
	SubmittedAt              pgtype.Timestamptz     `json:"submitted_at"`
	ReviewedAt               pgtype.Timestamptz     `json:"reviewed_at"`
	UpdatedAt                pgtype.Timestamptz     `json:"updated_at"`
}

func (q *Queries) ListStudentPlanningPerformance(ctx context.Context, studentID int64) ([]ListStudentPlanningPerformanceRow, error) {
	rows, err := q.db.Query(ctx, listStudentPlanningPerformance, studentID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []ListStudentPlanningPerformanceRow{}
	for rows.Next() {
		var i ListStudentPlanningPerformanceRow
		if err := rows.Scan(
			&i.AssignmentID,
			&i.QuestionID,
			&i.Topic,
			&i.Subject,
			&i.Difficulty,
			&i.QuestionTags,
			&i.IsCorrect,
			&i.ReviewUnderstandingScore,
			&i.ReviewNeedsAttention,
			&i.ReviewIssueReason,
			&i.Status,
			&i.SubmittedAt,
			&i.ReviewedAt,
			&i.UpdatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const updateAnswerAIReview = `-- name: UpdateAnswerAIReview :one
UPDATE student_answers
SET
    ai_feedback = $2,
    review_needs_attention = $3,
    review_issue_reason = $4,
    review_correctness_score = $5,
    review_understanding_score = $6,
    review_question_score = $7,
    review_confidence = $8,
    updated_at = NOW()
WHERE id = $1
RETURNING id, assignment_id, question_id, student_id, answer_text, ai_feedback, teacher_feedback, status, submitted_at, reviewed_at, created_at, updated_at, solve_mode, working_steps, is_correct, review_needs_attention, review_issue_reason, review_correctness_score, review_understanding_score, review_question_score, review_confidence, review_tags
`

type UpdateAnswerAIReviewParams struct {
	ID                       int64          `json:"id"`
	AiFeedback               pgtype.Text    `json:"ai_feedback"`
	ReviewNeedsAttention     bool           `json:"review_needs_attention"`
	ReviewIssueReason        pgtype.Text    `json:"review_issue_reason"`
	ReviewCorrectnessScore   pgtype.Numeric `json:"review_correctness_score"`
	ReviewUnderstandingScore pgtype.Numeric `json:"review_understanding_score"`
	ReviewQuestionScore      pgtype.Numeric `json:"review_question_score"`
	ReviewConfidence         pgtype.Numeric `json:"review_confidence"`
}

func (q *Queries) UpdateAnswerAIReview(ctx context.Context, arg UpdateAnswerAIReviewParams) (StudentAnswer, error) {
	row := q.db.QueryRow(ctx, updateAnswerAIReview,
		arg.ID,
		arg.AiFeedback,
		arg.ReviewNeedsAttention,
		arg.ReviewIssueReason,
		arg.ReviewCorrectnessScore,
		arg.ReviewUnderstandingScore,
		arg.ReviewQuestionScore,
		arg.ReviewConfidence,
	)
	var i StudentAnswer
	err := row.Scan(
		&i.ID,
		&i.AssignmentID,
		&i.QuestionID,
		&i.StudentID,
		&i.AnswerText,
		&i.AiFeedback,
		&i.TeacherFeedback,
		&i.Status,
		&i.SubmittedAt,
		&i.ReviewedAt,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.SolveMode,
		&i.WorkingSteps,
		&i.IsCorrect,
		&i.ReviewNeedsAttention,
		&i.ReviewIssueReason,
		&i.ReviewCorrectnessScore,
		&i.ReviewUnderstandingScore,
		&i.ReviewQuestionScore,
		&i.ReviewConfidence,
		&i.ReviewTags,
	)
	return i, err
}

const updateAnswerReview = `-- name: UpdateAnswerReview :one
UPDATE student_answers
SET
    status = $2,
    review_needs_attention = $3,
    review_issue_reason = $4,
    review_correctness_score = $5,
    review_understanding_score = $6,
    review_question_score = $7,
    review_confidence = $8,
    review_tags = $9,
    reviewed_at = CASE
        WHEN $2::answer_status = 'reviewed' THEN NOW()
        ELSE NULL
    END,
    updated_at = NOW()
WHERE id = $1
RETURNING id, assignment_id, question_id, student_id, answer_text, ai_feedback, teacher_feedback, status, submitted_at, reviewed_at, created_at, updated_at, solve_mode, working_steps, is_correct, review_needs_attention, review_issue_reason, review_correctness_score, review_understanding_score, review_question_score, review_confidence, review_tags
`

type UpdateAnswerReviewParams struct {
	ID                       int64          `json:"id"`
	Status                   AnswerStatus   `json:"status"`
	ReviewNeedsAttention     bool           `json:"review_needs_attention"`
	ReviewIssueReason        pgtype.Text    `json:"review_issue_reason"`
	ReviewCorrectnessScore   pgtype.Numeric `json:"review_correctness_score"`
	ReviewUnderstandingScore pgtype.Numeric `json:"review_understanding_score"`
	ReviewQuestionScore      pgtype.Numeric `json:"review_question_score"`
	ReviewConfidence         pgtype.Numeric `json:"review_confidence"`
	ReviewTags               []string       `json:"review_tags"`
}

func (q *Queries) UpdateAnswerReview(ctx context.Context, arg UpdateAnswerReviewParams) (StudentAnswer, error) {
	row := q.db.QueryRow(ctx, updateAnswerReview,
		arg.ID,
		arg.Status,
		arg.ReviewNeedsAttention,
		arg.ReviewIssueReason,
		arg.ReviewCorrectnessScore,
		arg.ReviewUnderstandingScore,
		arg.ReviewQuestionScore,
		arg.ReviewConfidence,
		arg.ReviewTags,
	)
	var i StudentAnswer
	err := row.Scan(
		&i.ID,
		&i.AssignmentID,
		&i.QuestionID,
		&i.StudentID,
		&i.AnswerText,
		&i.AiFeedback,
		&i.TeacherFeedback,
		&i.Status,
		&i.SubmittedAt,
		&i.ReviewedAt,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.SolveMode,
		&i.WorkingSteps,
		&i.IsCorrect,
		&i.ReviewNeedsAttention,
		&i.ReviewIssueReason,
		&i.ReviewCorrectnessScore,
		&i.ReviewUnderstandingScore,
		&i.ReviewQuestionScore,
		&i.ReviewConfidence,
		&i.ReviewTags,
	)
	return i, err
}

const upsertStudentAnswer = `-- name: UpsertStudentAnswer :one
INSERT INTO student_answers (
    assignment_id,
    question_id,
    student_id,
    answer_text,
    solve_mode,
    working_steps,
    ai_feedback,
    teacher_feedback,
    status,
    submitted_at,
    reviewed_at,
    is_correct
) VALUES (
    $1,
    $2,
    $3,
    $4,
    $5,
    $6,
    $7,
    $8,
    $9,
    $10,
    $11,
    $12
)
ON CONFLICT (assignment_id, question_id, student_id) DO UPDATE
SET
    answer_text = EXCLUDED.answer_text,
    solve_mode = EXCLUDED.solve_mode,
    working_steps = EXCLUDED.working_steps,
    ai_feedback = EXCLUDED.ai_feedback,
    teacher_feedback = EXCLUDED.teacher_feedback,
    status = EXCLUDED.status,
    submitted_at = EXCLUDED.submitted_at,
    reviewed_at = EXCLUDED.reviewed_at,
    is_correct = EXCLUDED.is_correct,
    updated_at = NOW()
RETURNING id, assignment_id, question_id, student_id, answer_text, ai_feedback, teacher_feedback, status, submitted_at, reviewed_at, created_at, updated_at, solve_mode, working_steps, is_correct, review_needs_attention, review_issue_reason, review_correctness_score, review_understanding_score, review_question_score, review_confidence, review_tags
`

type UpsertStudentAnswerParams struct {
	AssignmentID    int64              `json:"assignment_id"`
	QuestionID      int64              `json:"question_id"`
	StudentID       int64              `json:"student_id"`
	AnswerText      pgtype.Text        `json:"answer_text"`
	SolveMode       string             `json:"solve_mode"`
	WorkingSteps    pgtype.Text        `json:"working_steps"`
	AiFeedback      pgtype.Text        `json:"ai_feedback"`
	TeacherFeedback pgtype.Text        `json:"teacher_feedback"`
	Status          AnswerStatus       `json:"status"`
	SubmittedAt     pgtype.Timestamptz `json:"submitted_at"`
	ReviewedAt      pgtype.Timestamptz `json:"reviewed_at"`
	IsCorrect       pgtype.Bool        `json:"is_correct"`
}

func (q *Queries) UpsertStudentAnswer(ctx context.Context, arg UpsertStudentAnswerParams) (StudentAnswer, error) {
	row := q.db.QueryRow(ctx, upsertStudentAnswer,
		arg.AssignmentID,
		arg.QuestionID,
		arg.StudentID,
		arg.AnswerText,
		arg.SolveMode,
		arg.WorkingSteps,
		arg.AiFeedback,
		arg.TeacherFeedback,
		arg.Status,
		arg.SubmittedAt,
		arg.ReviewedAt,
		arg.IsCorrect,
	)
	var i StudentAnswer
	err := row.Scan(
		&i.ID,
		&i.AssignmentID,
		&i.QuestionID,
		&i.StudentID,
		&i.AnswerText,
		&i.AiFeedback,
		&i.TeacherFeedback,
		&i.Status,
		&i.SubmittedAt,
		&i.ReviewedAt,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.SolveMode,
		&i.WorkingSteps,
		&i.IsCorrect,
		&i.ReviewNeedsAttention,
		&i.ReviewIssueReason,
		&i.ReviewCorrectnessScore,
		&i.ReviewUnderstandingScore,
		&i.ReviewQuestionScore,
		&i.ReviewConfidence,
		&i.ReviewTags,
	)
	return i, err
}
