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

package dbgen

import (
	"context"

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

const ArchiveQuestion = `-- name: ArchiveQuestion :exec
UPDATE questions
SET status = 'ARCHIVED', updated_at = CURRENT_TIMESTAMP
WHERE id = $1
`

func (q *Queries) ArchiveQuestion(ctx context.Context, id int64) error {
	_, err := q.db.Exec(ctx, ArchiveQuestion, id)
	return err
}

const CreateQuestion = `-- name: CreateQuestion :one
INSERT INTO questions (
    question_text,
    question_type,
    difficulty_level,
    points,
    explanation,
    tips,
    voice_prompt,
    sample_answer_voice_prompt,
    status
)
VALUES ($1, $2, $3, COALESCE($4, 1), $5, $6, $7, $8, COALESCE($9, 'DRAFT'))
RETURNING id, question_text, question_type, difficulty_level, points, explanation, tips, voice_prompt, sample_answer_voice_prompt, status, created_at, updated_at
`

type CreateQuestionParams struct {
	QuestionText            string      `json:"question_text"`
	QuestionType            string      `json:"question_type"`
	DifficultyLevel         pgtype.Text `json:"difficulty_level"`
	Column4                 interface{} `json:"column_4"`
	Explanation             pgtype.Text `json:"explanation"`
	Tips                    pgtype.Text `json:"tips"`
	VoicePrompt             pgtype.Text `json:"voice_prompt"`
	SampleAnswerVoicePrompt pgtype.Text `json:"sample_answer_voice_prompt"`
	Column9                 interface{} `json:"column_9"`
}

func (q *Queries) CreateQuestion(ctx context.Context, arg CreateQuestionParams) (Question, error) {
	row := q.db.QueryRow(ctx, CreateQuestion,
		arg.QuestionText,
		arg.QuestionType,
		arg.DifficultyLevel,
		arg.Column4,
		arg.Explanation,
		arg.Tips,
		arg.VoicePrompt,
		arg.SampleAnswerVoicePrompt,
		arg.Column9,
	)
	var i Question
	err := row.Scan(
		&i.ID,
		&i.QuestionText,
		&i.QuestionType,
		&i.DifficultyLevel,
		&i.Points,
		&i.Explanation,
		&i.Tips,
		&i.VoicePrompt,
		&i.SampleAnswerVoicePrompt,
		&i.Status,
		&i.CreatedAt,
		&i.UpdatedAt,
	)
	return i, err
}

const DeleteQuestion = `-- name: DeleteQuestion :exec
DELETE FROM questions
WHERE id = $1
`

func (q *Queries) DeleteQuestion(ctx context.Context, id int64) error {
	_, err := q.db.Exec(ctx, DeleteQuestion, id)
	return err
}

const GetQuestionByID = `-- name: GetQuestionByID :one
SELECT id, question_text, question_type, difficulty_level, points, explanation, tips, voice_prompt, sample_answer_voice_prompt, status, created_at, updated_at
FROM questions
WHERE id = $1
`

func (q *Queries) GetQuestionByID(ctx context.Context, id int64) (Question, error) {
	row := q.db.QueryRow(ctx, GetQuestionByID, id)
	var i Question
	err := row.Scan(
		&i.ID,
		&i.QuestionText,
		&i.QuestionType,
		&i.DifficultyLevel,
		&i.Points,
		&i.Explanation,
		&i.Tips,
		&i.VoicePrompt,
		&i.SampleAnswerVoicePrompt,
		&i.Status,
		&i.CreatedAt,
		&i.UpdatedAt,
	)
	return i, err
}

const GetQuestionWithOptions = `-- name: GetQuestionWithOptions :many
SELECT 
    q.id as question_id,
    q.question_text,
    q.question_type,
    q.difficulty_level,
    q.points,
    q.explanation,
    q.tips,
    q.voice_prompt,
    q.status,
    qo.id as option_id,
    qo.option_text,
    qo.option_order,
    qo.is_correct
FROM questions q
LEFT JOIN question_options qo ON qo.question_id = q.id
WHERE q.id = $1
ORDER BY qo.option_order
`

type GetQuestionWithOptionsRow struct {
	QuestionID      int64       `json:"question_id"`
	QuestionText    string      `json:"question_text"`
	QuestionType    string      `json:"question_type"`
	DifficultyLevel pgtype.Text `json:"difficulty_level"`
	Points          int32       `json:"points"`
	Explanation     pgtype.Text `json:"explanation"`
	Tips            pgtype.Text `json:"tips"`
	VoicePrompt     pgtype.Text `json:"voice_prompt"`
	Status          string      `json:"status"`
	OptionID        pgtype.Int8 `json:"option_id"`
	OptionText      pgtype.Text `json:"option_text"`
	OptionOrder     pgtype.Int4 `json:"option_order"`
	IsCorrect       pgtype.Bool `json:"is_correct"`
}

func (q *Queries) GetQuestionWithOptions(ctx context.Context, id int64) ([]GetQuestionWithOptionsRow, error) {
	rows, err := q.db.Query(ctx, GetQuestionWithOptions, id)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []GetQuestionWithOptionsRow
	for rows.Next() {
		var i GetQuestionWithOptionsRow
		if err := rows.Scan(
			&i.QuestionID,
			&i.QuestionText,
			&i.QuestionType,
			&i.DifficultyLevel,
			&i.Points,
			&i.Explanation,
			&i.Tips,
			&i.VoicePrompt,
			&i.Status,
			&i.OptionID,
			&i.OptionText,
			&i.OptionOrder,
			&i.IsCorrect,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const GetQuestionsByIDs = `-- name: GetQuestionsByIDs :many
SELECT id, question_text, question_type, difficulty_level, points, explanation, tips, voice_prompt, sample_answer_voice_prompt, status, created_at, updated_at
FROM questions
WHERE id = ANY($1::BIGINT[])
ORDER BY id
`

func (q *Queries) GetQuestionsByIDs(ctx context.Context, dollar_1 []int64) ([]Question, error) {
	rows, err := q.db.Query(ctx, GetQuestionsByIDs, dollar_1)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []Question
	for rows.Next() {
		var i Question
		if err := rows.Scan(
			&i.ID,
			&i.QuestionText,
			&i.QuestionType,
			&i.DifficultyLevel,
			&i.Points,
			&i.Explanation,
			&i.Tips,
			&i.VoicePrompt,
			&i.SampleAnswerVoicePrompt,
			&i.Status,
			&i.CreatedAt,
			&i.UpdatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const ListQuestions = `-- name: ListQuestions :many
SELECT
    COUNT(*) OVER () AS total_count,
    q.id, q.question_text, q.question_type, q.difficulty_level, q.points, q.explanation, q.tips, q.voice_prompt, q.sample_answer_voice_prompt, q.status, q.created_at, q.updated_at
FROM questions q
WHERE status != 'ARCHIVED'
  AND ($1::VARCHAR IS NULL OR $1 = '' OR question_type = $1)
  AND ($2::VARCHAR IS NULL OR $2 = '' OR difficulty_level = $2)
  AND ($3::VARCHAR IS NULL OR $3 = '' OR status = $3)
ORDER BY created_at DESC
LIMIT $5::INT
OFFSET $4::INT
`

type ListQuestionsParams struct {
	Column1 string      `json:"column_1"`
	Column2 string      `json:"column_2"`
	Column3 string      `json:"column_3"`
	Offset  pgtype.Int4 `json:"offset"`
	Limit   pgtype.Int4 `json:"limit"`
}

type ListQuestionsRow struct {
	TotalCount              int64              `json:"total_count"`
	ID                      int64              `json:"id"`
	QuestionText            string             `json:"question_text"`
	QuestionType            string             `json:"question_type"`
	DifficultyLevel         pgtype.Text        `json:"difficulty_level"`
	Points                  int32              `json:"points"`
	Explanation             pgtype.Text        `json:"explanation"`
	Tips                    pgtype.Text        `json:"tips"`
	VoicePrompt             pgtype.Text        `json:"voice_prompt"`
	SampleAnswerVoicePrompt pgtype.Text        `json:"sample_answer_voice_prompt"`
	Status                  string             `json:"status"`
	CreatedAt               pgtype.Timestamptz `json:"created_at"`
	UpdatedAt               pgtype.Timestamptz `json:"updated_at"`
}

func (q *Queries) ListQuestions(ctx context.Context, arg ListQuestionsParams) ([]ListQuestionsRow, error) {
	rows, err := q.db.Query(ctx, ListQuestions,
		arg.Column1,
		arg.Column2,
		arg.Column3,
		arg.Offset,
		arg.Limit,
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []ListQuestionsRow
	for rows.Next() {
		var i ListQuestionsRow
		if err := rows.Scan(
			&i.TotalCount,
			&i.ID,
			&i.QuestionText,
			&i.QuestionType,
			&i.DifficultyLevel,
			&i.Points,
			&i.Explanation,
			&i.Tips,
			&i.VoicePrompt,
			&i.SampleAnswerVoicePrompt,
			&i.Status,
			&i.CreatedAt,
			&i.UpdatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const SearchQuestions = `-- name: SearchQuestions :many
SELECT
    COUNT(*) OVER () AS total_count,
    q.id, q.question_text, q.question_type, q.difficulty_level, q.points, q.explanation, q.tips, q.voice_prompt, q.sample_answer_voice_prompt, q.status, q.created_at, q.updated_at
FROM questions q
WHERE status != 'ARCHIVED'
  AND question_text ILIKE '%' || $1 || '%'
ORDER BY created_at DESC
LIMIT $3::INT
OFFSET $2::INT
`

type SearchQuestionsParams struct {
	Column1 pgtype.Text `json:"column_1"`
	Offset  pgtype.Int4 `json:"offset"`
	Limit   pgtype.Int4 `json:"limit"`
}

type SearchQuestionsRow struct {
	TotalCount              int64              `json:"total_count"`
	ID                      int64              `json:"id"`
	QuestionText            string             `json:"question_text"`
	QuestionType            string             `json:"question_type"`
	DifficultyLevel         pgtype.Text        `json:"difficulty_level"`
	Points                  int32              `json:"points"`
	Explanation             pgtype.Text        `json:"explanation"`
	Tips                    pgtype.Text        `json:"tips"`
	VoicePrompt             pgtype.Text        `json:"voice_prompt"`
	SampleAnswerVoicePrompt pgtype.Text        `json:"sample_answer_voice_prompt"`
	Status                  string             `json:"status"`
	CreatedAt               pgtype.Timestamptz `json:"created_at"`
	UpdatedAt               pgtype.Timestamptz `json:"updated_at"`
}

func (q *Queries) SearchQuestions(ctx context.Context, arg SearchQuestionsParams) ([]SearchQuestionsRow, error) {
	rows, err := q.db.Query(ctx, SearchQuestions, arg.Column1, arg.Offset, arg.Limit)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []SearchQuestionsRow
	for rows.Next() {
		var i SearchQuestionsRow
		if err := rows.Scan(
			&i.TotalCount,
			&i.ID,
			&i.QuestionText,
			&i.QuestionType,
			&i.DifficultyLevel,
			&i.Points,
			&i.Explanation,
			&i.Tips,
			&i.VoicePrompt,
			&i.SampleAnswerVoicePrompt,
			&i.Status,
			&i.CreatedAt,
			&i.UpdatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const UpdateQuestion = `-- name: UpdateQuestion :exec
UPDATE questions
SET
    question_text = COALESCE($1, question_text),
    question_type = COALESCE($2, question_type),
    difficulty_level = COALESCE($3, difficulty_level),
    points = COALESCE($4, points),
    explanation = COALESCE($5, explanation),
    tips = COALESCE($6, tips),
    voice_prompt = COALESCE($7, voice_prompt),
    sample_answer_voice_prompt = COALESCE($8, sample_answer_voice_prompt),
    status = COALESCE($9, status),
    updated_at = CURRENT_TIMESTAMP
WHERE id = $10
`

type UpdateQuestionParams struct {
	QuestionText            string      `json:"question_text"`
	QuestionType            string      `json:"question_type"`
	DifficultyLevel         pgtype.Text `json:"difficulty_level"`
	Points                  int32       `json:"points"`
	Explanation             pgtype.Text `json:"explanation"`
	Tips                    pgtype.Text `json:"tips"`
	VoicePrompt             pgtype.Text `json:"voice_prompt"`
	SampleAnswerVoicePrompt pgtype.Text `json:"sample_answer_voice_prompt"`
	Status                  string      `json:"status"`
	ID                      int64       `json:"id"`
}

func (q *Queries) UpdateQuestion(ctx context.Context, arg UpdateQuestionParams) error {
	_, err := q.db.Exec(ctx, UpdateQuestion,
		arg.QuestionText,
		arg.QuestionType,
		arg.DifficultyLevel,
		arg.Points,
		arg.Explanation,
		arg.Tips,
		arg.VoicePrompt,
		arg.SampleAnswerVoicePrompt,
		arg.Status,
		arg.ID,
	)
	return err
}
