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

package dbgen

import (
	"context"

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

const AddUserPersonaToQuestionSet = `-- name: AddUserPersonaToQuestionSet :one
INSERT INTO question_set_personas (
    question_set_id,
    user_id,
    display_order
)
VALUES ($1, $2, COALESCE($3, 0))
RETURNING id, question_set_id, user_id, display_order, created_at
`

type AddUserPersonaToQuestionSetParams struct {
	QuestionSetID int64       `json:"question_set_id"`
	UserID        int64       `json:"user_id"`
	Column3       interface{} `json:"column_3"`
}

func (q *Queries) AddUserPersonaToQuestionSet(ctx context.Context, arg AddUserPersonaToQuestionSetParams) (QuestionSetPersona, error) {
	row := q.db.QueryRow(ctx, AddUserPersonaToQuestionSet, arg.QuestionSetID, arg.UserID, arg.Column3)
	var i QuestionSetPersona
	err := row.Scan(
		&i.ID,
		&i.QuestionSetID,
		&i.UserID,
		&i.DisplayOrder,
		&i.CreatedAt,
	)
	return i, err
}

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

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

const CreateQuestionSet = `-- name: CreateQuestionSet :one
INSERT INTO question_sets (
    title,
    description,
    set_type,
    owner_type,
    owner_id,
    banner_image,
    persona,
    time_limit_minutes,
    passing_score,
    shuffle_questions,
    status,
    sub_course_video_id
)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, COALESCE($10, false), COALESCE($11, 'DRAFT'), $12)
RETURNING id, title, description, set_type, owner_type, owner_id, banner_image, persona, time_limit_minutes, passing_score, shuffle_questions, status, created_at, updated_at, sub_course_video_id
`

type CreateQuestionSetParams struct {
	Title            string      `json:"title"`
	Description      pgtype.Text `json:"description"`
	SetType          string      `json:"set_type"`
	OwnerType        pgtype.Text `json:"owner_type"`
	OwnerID          pgtype.Int8 `json:"owner_id"`
	BannerImage      pgtype.Text `json:"banner_image"`
	Persona          pgtype.Text `json:"persona"`
	TimeLimitMinutes pgtype.Int4 `json:"time_limit_minutes"`
	PassingScore     pgtype.Int4 `json:"passing_score"`
	Column10         interface{} `json:"column_10"`
	Column11         interface{} `json:"column_11"`
	SubCourseVideoID pgtype.Int8 `json:"sub_course_video_id"`
}

func (q *Queries) CreateQuestionSet(ctx context.Context, arg CreateQuestionSetParams) (QuestionSet, error) {
	row := q.db.QueryRow(ctx, CreateQuestionSet,
		arg.Title,
		arg.Description,
		arg.SetType,
		arg.OwnerType,
		arg.OwnerID,
		arg.BannerImage,
		arg.Persona,
		arg.TimeLimitMinutes,
		arg.PassingScore,
		arg.Column10,
		arg.Column11,
		arg.SubCourseVideoID,
	)
	var i QuestionSet
	err := row.Scan(
		&i.ID,
		&i.Title,
		&i.Description,
		&i.SetType,
		&i.OwnerType,
		&i.OwnerID,
		&i.BannerImage,
		&i.Persona,
		&i.TimeLimitMinutes,
		&i.PassingScore,
		&i.ShuffleQuestions,
		&i.Status,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.SubCourseVideoID,
	)
	return i, err
}

const DeleteQuestionSet = `-- name: DeleteQuestionSet :exec
DELETE FROM question_sets
WHERE id = $1
`

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

const GetInitialAssessmentSet = `-- name: GetInitialAssessmentSet :one
SELECT id, title, description, set_type, owner_type, owner_id, banner_image, persona, time_limit_minutes, passing_score, shuffle_questions, status, created_at, updated_at, sub_course_video_id
FROM question_sets
WHERE set_type = 'INITIAL_ASSESSMENT'
  AND status = 'PUBLISHED'
ORDER BY created_at DESC
LIMIT 1
`

func (q *Queries) GetInitialAssessmentSet(ctx context.Context) (QuestionSet, error) {
	row := q.db.QueryRow(ctx, GetInitialAssessmentSet)
	var i QuestionSet
	err := row.Scan(
		&i.ID,
		&i.Title,
		&i.Description,
		&i.SetType,
		&i.OwnerType,
		&i.OwnerID,
		&i.BannerImage,
		&i.Persona,
		&i.TimeLimitMinutes,
		&i.PassingScore,
		&i.ShuffleQuestions,
		&i.Status,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.SubCourseVideoID,
	)
	return i, err
}

const GetPublishedQuestionSetsByOwner = `-- name: GetPublishedQuestionSetsByOwner :many
SELECT id, title, description, set_type, owner_type, owner_id, banner_image, persona, time_limit_minutes, passing_score, shuffle_questions, status, created_at, updated_at, sub_course_video_id
FROM question_sets
WHERE owner_type = $1
  AND owner_id = $2
  AND status = 'PUBLISHED'
ORDER BY created_at DESC
`

type GetPublishedQuestionSetsByOwnerParams struct {
	OwnerType pgtype.Text `json:"owner_type"`
	OwnerID   pgtype.Int8 `json:"owner_id"`
}

func (q *Queries) GetPublishedQuestionSetsByOwner(ctx context.Context, arg GetPublishedQuestionSetsByOwnerParams) ([]QuestionSet, error) {
	rows, err := q.db.Query(ctx, GetPublishedQuestionSetsByOwner, arg.OwnerType, arg.OwnerID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []QuestionSet
	for rows.Next() {
		var i QuestionSet
		if err := rows.Scan(
			&i.ID,
			&i.Title,
			&i.Description,
			&i.SetType,
			&i.OwnerType,
			&i.OwnerID,
			&i.BannerImage,
			&i.Persona,
			&i.TimeLimitMinutes,
			&i.PassingScore,
			&i.ShuffleQuestions,
			&i.Status,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.SubCourseVideoID,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const GetQuestionSetByID = `-- name: GetQuestionSetByID :one
SELECT id, title, description, set_type, owner_type, owner_id, banner_image, persona, time_limit_minutes, passing_score, shuffle_questions, status, created_at, updated_at, sub_course_video_id
FROM question_sets
WHERE id = $1
`

func (q *Queries) GetQuestionSetByID(ctx context.Context, id int64) (QuestionSet, error) {
	row := q.db.QueryRow(ctx, GetQuestionSetByID, id)
	var i QuestionSet
	err := row.Scan(
		&i.ID,
		&i.Title,
		&i.Description,
		&i.SetType,
		&i.OwnerType,
		&i.OwnerID,
		&i.BannerImage,
		&i.Persona,
		&i.TimeLimitMinutes,
		&i.PassingScore,
		&i.ShuffleQuestions,
		&i.Status,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.SubCourseVideoID,
	)
	return i, err
}

const GetQuestionSetsByOwner = `-- name: GetQuestionSetsByOwner :many
SELECT id, title, description, set_type, owner_type, owner_id, banner_image, persona, time_limit_minutes, passing_score, shuffle_questions, status, created_at, updated_at, sub_course_video_id
FROM question_sets
WHERE owner_type = $1
  AND owner_id = $2
  AND status != 'ARCHIVED'
ORDER BY created_at DESC
`

type GetQuestionSetsByOwnerParams struct {
	OwnerType pgtype.Text `json:"owner_type"`
	OwnerID   pgtype.Int8 `json:"owner_id"`
}

func (q *Queries) GetQuestionSetsByOwner(ctx context.Context, arg GetQuestionSetsByOwnerParams) ([]QuestionSet, error) {
	rows, err := q.db.Query(ctx, GetQuestionSetsByOwner, arg.OwnerType, arg.OwnerID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []QuestionSet
	for rows.Next() {
		var i QuestionSet
		if err := rows.Scan(
			&i.ID,
			&i.Title,
			&i.Description,
			&i.SetType,
			&i.OwnerType,
			&i.OwnerID,
			&i.BannerImage,
			&i.Persona,
			&i.TimeLimitMinutes,
			&i.PassingScore,
			&i.ShuffleQuestions,
			&i.Status,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.SubCourseVideoID,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const GetQuestionSetsByType = `-- name: GetQuestionSetsByType :many
SELECT
    COUNT(*) OVER () AS total_count,
    qs.id, qs.title, qs.description, qs.set_type, qs.owner_type, qs.owner_id, qs.banner_image, qs.persona, qs.time_limit_minutes, qs.passing_score, qs.shuffle_questions, qs.status, qs.created_at, qs.updated_at, qs.sub_course_video_id
FROM question_sets qs
WHERE set_type = $1
  AND status != 'ARCHIVED'
ORDER BY created_at DESC
LIMIT $3::INT
OFFSET $2::INT
`

type GetQuestionSetsByTypeParams struct {
	SetType string      `json:"set_type"`
	Offset  pgtype.Int4 `json:"offset"`
	Limit   pgtype.Int4 `json:"limit"`
}

type GetQuestionSetsByTypeRow struct {
	TotalCount       int64              `json:"total_count"`
	ID               int64              `json:"id"`
	Title            string             `json:"title"`
	Description      pgtype.Text        `json:"description"`
	SetType          string             `json:"set_type"`
	OwnerType        pgtype.Text        `json:"owner_type"`
	OwnerID          pgtype.Int8        `json:"owner_id"`
	BannerImage      pgtype.Text        `json:"banner_image"`
	Persona          pgtype.Text        `json:"persona"`
	TimeLimitMinutes pgtype.Int4        `json:"time_limit_minutes"`
	PassingScore     pgtype.Int4        `json:"passing_score"`
	ShuffleQuestions bool               `json:"shuffle_questions"`
	Status           string             `json:"status"`
	CreatedAt        pgtype.Timestamptz `json:"created_at"`
	UpdatedAt        pgtype.Timestamptz `json:"updated_at"`
	SubCourseVideoID pgtype.Int8        `json:"sub_course_video_id"`
}

func (q *Queries) GetQuestionSetsByType(ctx context.Context, arg GetQuestionSetsByTypeParams) ([]GetQuestionSetsByTypeRow, error) {
	rows, err := q.db.Query(ctx, GetQuestionSetsByType, arg.SetType, arg.Offset, arg.Limit)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []GetQuestionSetsByTypeRow
	for rows.Next() {
		var i GetQuestionSetsByTypeRow
		if err := rows.Scan(
			&i.TotalCount,
			&i.ID,
			&i.Title,
			&i.Description,
			&i.SetType,
			&i.OwnerType,
			&i.OwnerID,
			&i.BannerImage,
			&i.Persona,
			&i.TimeLimitMinutes,
			&i.PassingScore,
			&i.ShuffleQuestions,
			&i.Status,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.SubCourseVideoID,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const GetUserPersonasByQuestionSetID = `-- name: GetUserPersonasByQuestionSetID :many
SELECT
    u.id,
    u.first_name,
    u.last_name,
    u.nick_name,
    u.profile_picture_url,
    u.role,
    qsp.display_order
FROM users u
INNER JOIN question_set_personas qsp ON qsp.user_id = u.id
WHERE qsp.question_set_id = $1
ORDER BY qsp.display_order ASC
`

type GetUserPersonasByQuestionSetIDRow struct {
	ID                int64       `json:"id"`
	FirstName         pgtype.Text `json:"first_name"`
	LastName          pgtype.Text `json:"last_name"`
	NickName          pgtype.Text `json:"nick_name"`
	ProfilePictureUrl pgtype.Text `json:"profile_picture_url"`
	Role              string      `json:"role"`
	DisplayOrder      pgtype.Int4 `json:"display_order"`
}

func (q *Queries) GetUserPersonasByQuestionSetID(ctx context.Context, questionSetID int64) ([]GetUserPersonasByQuestionSetIDRow, error) {
	rows, err := q.db.Query(ctx, GetUserPersonasByQuestionSetID, questionSetID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []GetUserPersonasByQuestionSetIDRow
	for rows.Next() {
		var i GetUserPersonasByQuestionSetIDRow
		if err := rows.Scan(
			&i.ID,
			&i.FirstName,
			&i.LastName,
			&i.NickName,
			&i.ProfilePictureUrl,
			&i.Role,
			&i.DisplayOrder,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const RemoveUserPersonaFromQuestionSet = `-- name: RemoveUserPersonaFromQuestionSet :exec
DELETE FROM question_set_personas
WHERE question_set_id = $1
  AND user_id = $2
`

type RemoveUserPersonaFromQuestionSetParams struct {
	QuestionSetID int64 `json:"question_set_id"`
	UserID        int64 `json:"user_id"`
}

func (q *Queries) RemoveUserPersonaFromQuestionSet(ctx context.Context, arg RemoveUserPersonaFromQuestionSetParams) error {
	_, err := q.db.Exec(ctx, RemoveUserPersonaFromQuestionSet, arg.QuestionSetID, arg.UserID)
	return err
}

const UpdateQuestionSet = `-- name: UpdateQuestionSet :exec
UPDATE question_sets
SET
    title = COALESCE($1, title),
    description = COALESCE($2, description),
    banner_image = COALESCE($3, banner_image),
    persona = COALESCE($4, persona),
    time_limit_minutes = COALESCE($5, time_limit_minutes),
    passing_score = COALESCE($6, passing_score),
    shuffle_questions = COALESCE($7, shuffle_questions),
    status = COALESCE($8, status),
    sub_course_video_id = COALESCE($9, sub_course_video_id),
    updated_at = CURRENT_TIMESTAMP
WHERE id = $10
`

type UpdateQuestionSetParams struct {
	Title            string      `json:"title"`
	Description      pgtype.Text `json:"description"`
	BannerImage      pgtype.Text `json:"banner_image"`
	Persona          pgtype.Text `json:"persona"`
	TimeLimitMinutes pgtype.Int4 `json:"time_limit_minutes"`
	PassingScore     pgtype.Int4 `json:"passing_score"`
	ShuffleQuestions bool        `json:"shuffle_questions"`
	Status           string      `json:"status"`
	SubCourseVideoID pgtype.Int8 `json:"sub_course_video_id"`
	ID               int64       `json:"id"`
}

func (q *Queries) UpdateQuestionSet(ctx context.Context, arg UpdateQuestionSetParams) error {
	_, err := q.db.Exec(ctx, UpdateQuestionSet,
		arg.Title,
		arg.Description,
		arg.BannerImage,
		arg.Persona,
		arg.TimeLimitMinutes,
		arg.PassingScore,
		arg.ShuffleQuestions,
		arg.Status,
		arg.SubCourseVideoID,
		arg.ID,
	)
	return err
}

const UpdateQuestionSetVideoLink = `-- name: UpdateQuestionSetVideoLink :exec
UPDATE question_sets
SET
    sub_course_video_id = $1,
    updated_at = CURRENT_TIMESTAMP
WHERE id = $2
`

type UpdateQuestionSetVideoLinkParams struct {
	SubCourseVideoID pgtype.Int8 `json:"sub_course_video_id"`
	ID               int64       `json:"id"`
}

func (q *Queries) UpdateQuestionSetVideoLink(ctx context.Context, arg UpdateQuestionSetVideoLinkParams) error {
	_, err := q.db.Exec(ctx, UpdateQuestionSetVideoLink, arg.SubCourseVideoID, arg.ID)
	return err
}
