-- 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 *;

-- 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 *;

-- name: ListAnswersForAssignment :many
SELECT *
FROM student_answers
WHERE assignment_id = $1
ORDER BY created_at ASC;

-- name: ListAnswersForStudent :many
SELECT *
FROM student_answers
WHERE student_id = $1
ORDER BY created_at DESC;

-- 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;

-- 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 *;

-- 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;
