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

package sqlc

import (
	"context"

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

const AddTaskTag = `-- name: AddTaskTag :exec
INSERT INTO task_tags (task_id, tag_id) VALUES ($1, $2) ON CONFLICT DO NOTHING
`

type AddTaskTagParams struct {
	TaskID pgtype.UUID `json:"taskId"`
	TagID  pgtype.UUID `json:"tagId"`
}

func (q *Queries) AddTaskTag(ctx context.Context, arg AddTaskTagParams) error {
	_, err := q.db.Exec(ctx, AddTaskTag, arg.TaskID, arg.TagID)
	return err
}

const CreateTask = `-- name: CreateTask :one
INSERT INTO tasks (title, description, status, priority, due_date, user_id)
VALUES ($1, $2, $3, $4, $5, $6)
RETURNING id, title, description, status, priority, due_date, user_id, created_at, updated_at
`

type CreateTaskParams struct {
	Title       string           `json:"title"`
	Description *string          `json:"description"`
	Status      *string          `json:"status"`
	Priority    *string          `json:"priority"`
	DueDate     pgtype.Timestamp `json:"dueDate"`
	UserID      pgtype.UUID      `json:"userId"`
}

func (q *Queries) CreateTask(ctx context.Context, arg CreateTaskParams) (Task, error) {
	row := q.db.QueryRow(ctx, CreateTask,
		arg.Title,
		arg.Description,
		arg.Status,
		arg.Priority,
		arg.DueDate,
		arg.UserID,
	)
	var i Task
	err := row.Scan(
		&i.ID,
		&i.Title,
		&i.Description,
		&i.Status,
		&i.Priority,
		&i.DueDate,
		&i.UserID,
		&i.CreatedAt,
		&i.UpdatedAt,
	)
	return i, err
}

const DeleteTask = `-- name: DeleteTask :exec
DELETE FROM tasks WHERE id = $1 AND user_id = $2
`

type DeleteTaskParams struct {
	ID     pgtype.UUID `json:"id"`
	UserID pgtype.UUID `json:"userId"`
}

func (q *Queries) DeleteTask(ctx context.Context, arg DeleteTaskParams) error {
	_, err := q.db.Exec(ctx, DeleteTask, arg.ID, arg.UserID)
	return err
}

const GetTaskByID = `-- name: GetTaskByID :one
SELECT id, title, description, status, priority, due_date, user_id, created_at, updated_at
FROM tasks
WHERE id = $1 AND user_id = $2 LIMIT 1
`

type GetTaskByIDParams struct {
	ID     pgtype.UUID `json:"id"`
	UserID pgtype.UUID `json:"userId"`
}

func (q *Queries) GetTaskByID(ctx context.Context, arg GetTaskByIDParams) (Task, error) {
	row := q.db.QueryRow(ctx, GetTaskByID, arg.ID, arg.UserID)
	var i Task
	err := row.Scan(
		&i.ID,
		&i.Title,
		&i.Description,
		&i.Status,
		&i.Priority,
		&i.DueDate,
		&i.UserID,
		&i.CreatedAt,
		&i.UpdatedAt,
	)
	return i, err
}

const GetTasksByStatus = `-- name: GetTasksByStatus :many
SELECT id, title, description, status, priority, due_date, user_id, created_at, updated_at
FROM tasks
WHERE user_id = $1 AND status = $2
ORDER BY 
    CASE priority 
        WHEN 'high' THEN 1 
        WHEN 'medium' THEN 2 
        WHEN 'low' THEN 3 
    END,
    due_date ASC NULLS LAST,
    created_at DESC
LIMIT $3 OFFSET $4
`

type GetTasksByStatusParams struct {
	UserID pgtype.UUID `json:"userId"`
	Status *string     `json:"status"`
	Limit  int32       `json:"limit"`
	Offset int32       `json:"offset"`
}

func (q *Queries) GetTasksByStatus(ctx context.Context, arg GetTasksByStatusParams) ([]Task, error) {
	rows, err := q.db.Query(ctx, GetTasksByStatus,
		arg.UserID,
		arg.Status,
		arg.Limit,
		arg.Offset,
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []Task{}
	for rows.Next() {
		var i Task
		if err := rows.Scan(
			&i.ID,
			&i.Title,
			&i.Description,
			&i.Status,
			&i.Priority,
			&i.DueDate,
			&i.UserID,
			&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 GetTasksByTag = `-- name: GetTasksByTag :many
SELECT t.id, t.title, t.description, t.status, t.priority, t.due_date, t.user_id, t.created_at, t.updated_at
FROM tasks t
INNER JOIN task_tags tt ON t.id = tt.task_id
INNER JOIN tags tg ON tt.tag_id = tg.id
WHERE tg.id = $1 AND t.user_id = $2
ORDER BY 
    CASE t.priority 
        WHEN 'high' THEN 1 
        WHEN 'medium' THEN 2 
        WHEN 'low' THEN 3 
    END,
    t.due_date ASC NULLS LAST,
    t.created_at DESC
LIMIT $3 OFFSET $4
`

type GetTasksByTagParams struct {
	ID     pgtype.UUID `json:"id"`
	UserID pgtype.UUID `json:"userId"`
	Limit  int32       `json:"limit"`
	Offset int32       `json:"offset"`
}

func (q *Queries) GetTasksByTag(ctx context.Context, arg GetTasksByTagParams) ([]Task, error) {
	rows, err := q.db.Query(ctx, GetTasksByTag,
		arg.ID,
		arg.UserID,
		arg.Limit,
		arg.Offset,
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []Task{}
	for rows.Next() {
		var i Task
		if err := rows.Scan(
			&i.ID,
			&i.Title,
			&i.Description,
			&i.Status,
			&i.Priority,
			&i.DueDate,
			&i.UserID,
			&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 GetTasksByUser = `-- name: GetTasksByUser :many
SELECT id, title, description, status, priority, due_date, user_id, created_at, updated_at
FROM tasks
WHERE user_id = $1
ORDER BY 
    CASE priority 
        WHEN 'high' THEN 1 
        WHEN 'medium' THEN 2 
        WHEN 'low' THEN 3 
    END,
    due_date ASC NULLS LAST,
    created_at DESC
LIMIT $2 OFFSET $3
`

type GetTasksByUserParams struct {
	UserID pgtype.UUID `json:"userId"`
	Limit  int32       `json:"limit"`
	Offset int32       `json:"offset"`
}

func (q *Queries) GetTasksByUser(ctx context.Context, arg GetTasksByUserParams) ([]Task, error) {
	rows, err := q.db.Query(ctx, GetTasksByUser, arg.UserID, arg.Limit, arg.Offset)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []Task{}
	for rows.Next() {
		var i Task
		if err := rows.Scan(
			&i.ID,
			&i.Title,
			&i.Description,
			&i.Status,
			&i.Priority,
			&i.DueDate,
			&i.UserID,
			&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 RemoveTaskTag = `-- name: RemoveTaskTag :exec
DELETE FROM task_tags WHERE task_id = $1 AND tag_id = $2
`

type RemoveTaskTagParams struct {
	TaskID pgtype.UUID `json:"taskId"`
	TagID  pgtype.UUID `json:"tagId"`
}

func (q *Queries) RemoveTaskTag(ctx context.Context, arg RemoveTaskTagParams) error {
	_, err := q.db.Exec(ctx, RemoveTaskTag, arg.TaskID, arg.TagID)
	return err
}

const SearchTasks = `-- name: SearchTasks :many
SELECT id, title, description, status, priority, due_date, user_id, created_at, updated_at
FROM tasks
WHERE user_id = $1 AND (
    title ILIKE $2 OR 
    description ILIKE $2
)
ORDER BY 
    CASE priority 
        WHEN 'high' THEN 1 
        WHEN 'medium' THEN 2 
        WHEN 'low' THEN 3 
    END,
    due_date ASC NULLS LAST,
    created_at DESC
LIMIT $3 OFFSET $4
`

type SearchTasksParams struct {
	UserID pgtype.UUID `json:"userId"`
	Title  string      `json:"title"`
	Limit  int32       `json:"limit"`
	Offset int32       `json:"offset"`
}

func (q *Queries) SearchTasks(ctx context.Context, arg SearchTasksParams) ([]Task, error) {
	rows, err := q.db.Query(ctx, SearchTasks,
		arg.UserID,
		arg.Title,
		arg.Limit,
		arg.Offset,
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []Task{}
	for rows.Next() {
		var i Task
		if err := rows.Scan(
			&i.ID,
			&i.Title,
			&i.Description,
			&i.Status,
			&i.Priority,
			&i.DueDate,
			&i.UserID,
			&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 UpdateTask = `-- name: UpdateTask :one
UPDATE tasks
SET title = $2,
    description = $3,
    status = $4,
    priority = $5,
    due_date = $6,
    updated_at = CURRENT_TIMESTAMP
WHERE id = $1 AND user_id = $7
RETURNING id, title, description, status, priority, due_date, user_id, created_at, updated_at
`

type UpdateTaskParams struct {
	ID          pgtype.UUID      `json:"id"`
	Title       string           `json:"title"`
	Description *string          `json:"description"`
	Status      *string          `json:"status"`
	Priority    *string          `json:"priority"`
	DueDate     pgtype.Timestamp `json:"dueDate"`
	UserID      pgtype.UUID      `json:"userId"`
}

func (q *Queries) UpdateTask(ctx context.Context, arg UpdateTaskParams) (Task, error) {
	row := q.db.QueryRow(ctx, UpdateTask,
		arg.ID,
		arg.Title,
		arg.Description,
		arg.Status,
		arg.Priority,
		arg.DueDate,
		arg.UserID,
	)
	var i Task
	err := row.Scan(
		&i.ID,
		&i.Title,
		&i.Description,
		&i.Status,
		&i.Priority,
		&i.DueDate,
		&i.UserID,
		&i.CreatedAt,
		&i.UpdatedAt,
	)
	return i, err
}
