// Code generated by sqlc. DO NOT EDIT.
// versions:
//   sqlc v1.26.0
// source: category.sql

package category

import (
	"context"
)

const createChildCategoryIfNotExists = `-- name: CreateChildCategoryIfNotExists :one
WITH inserted AS (
    INSERT INTO categories
        (category, handle, parent_id)
    VALUES
        ($1, $2, $3)
    ON CONFLICT (category, parent_id)
        DO NOTHING
    RETURNING id, category, handle, parent_id
)
SELECT id, category, handle, parent_id FROM inserted
UNION ALL
SELECT id, category, handle, parent_id FROM categories
WHERE category = $1 AND parent_id = $3
`

type CreateChildCategoryIfNotExistsRow struct {
	ID       int32
	Category string
	Handle   string
	ParentID *int32
}

func (q *Queries) CreateChildCategoryIfNotExists(ctx context.Context, category string, handle string, parentID *int32) (*CreateChildCategoryIfNotExistsRow, error) {
	row := q.db.QueryRow(ctx, createChildCategoryIfNotExists, category, handle, parentID)
	var i CreateChildCategoryIfNotExistsRow
	err := row.Scan(
		&i.ID,
		&i.Category,
		&i.Handle,
		&i.ParentID,
	)
	return &i, err
}

const createTopCategory = `-- name: CreateTopCategory :one
INSERT INTO categories (
    category, handle
) VALUES (
    $1, $2
) RETURNING id, category, handle, parent_id
`

func (q *Queries) CreateTopCategory(ctx context.Context, category string, handle string) (*Category, error) {
	row := q.db.QueryRow(ctx, createTopCategory, category, handle)
	var i Category
	err := row.Scan(
		&i.ID,
		&i.Category,
		&i.Handle,
		&i.ParentID,
	)
	return &i, err
}

const getCategory = `-- name: GetCategory :one
SELECT
    c.id,
    c.category,
    c.handle,
    c.parent_id,
    CASE
        WHEN EXISTS (SELECT 1 FROM categories WHERE parent_id = c.id) THEN false
        ELSE true
        END AS is_leaf_category
FROM
    categories c
WHERE
    c.id = $1
`

type GetCategoryRow struct {
	ID             int32
	Category       string
	Handle         string
	ParentID       *int32
	IsLeafCategory bool
}

func (q *Queries) GetCategory(ctx context.Context, id int32) (*GetCategoryRow, error) {
	row := q.db.QueryRow(ctx, getCategory, id)
	var i GetCategoryRow
	err := row.Scan(
		&i.ID,
		&i.Category,
		&i.Handle,
		&i.ParentID,
		&i.IsLeafCategory,
	)
	return &i, err
}

const getCategoryByName = `-- name: GetCategoryByName :one
SELECT id, category, handle, parent_id FROM categories
WHERE category = $1
ORDER BY id
LIMIT 1
`

func (q *Queries) GetCategoryByName(ctx context.Context, category string) (*Category, error) {
	row := q.db.QueryRow(ctx, getCategoryByName, category)
	var i Category
	err := row.Scan(
		&i.ID,
		&i.Category,
		&i.Handle,
		&i.ParentID,
	)
	return &i, err
}

const getCategoryWithAncestors = `-- name: GetCategoryWithAncestors :many
WITH RECURSIVE categories_cte AS (
    SELECT c.id, c.category, c.handle, c.parent_id, 1 AS level
    FROM categories c
    WHERE c.id = $1
    UNION
    SELECT c.id, c.category, c.handle, c.parent_id, level + 1
    FROM categories c
             JOIN categories_cte cte ON cte.parent_id = c.id
)
SELECT id, category, handle, parent_id, level
FROM categories_cte
ORDER BY level DESC
`

type GetCategoryWithAncestorsRow struct {
	ID       int32
	Category string
	Handle   string
	ParentID *int32
	Level    int32
}

func (q *Queries) GetCategoryWithAncestors(ctx context.Context, id int32) ([]*GetCategoryWithAncestorsRow, error) {
	rows, err := q.db.Query(ctx, getCategoryWithAncestors, id)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*GetCategoryWithAncestorsRow
	for rows.Next() {
		var i GetCategoryWithAncestorsRow
		if err := rows.Scan(
			&i.ID,
			&i.Category,
			&i.Handle,
			&i.ParentID,
			&i.Level,
		); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getCategoryWithSiblings = `-- name: GetCategoryWithSiblings :many
WITH category_cte AS (
    SELECT parent_id FROM categories c WHERE c.id = $1
)
SELECT id, category, handle, parent_id FROM categories WHERE parent_id = (SELECT parent_id FROM category_cte)
`

func (q *Queries) GetCategoryWithSiblings(ctx context.Context, id int32) ([]*Category, error) {
	rows, err := q.db.Query(ctx, getCategoryWithSiblings, id)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*Category
	for rows.Next() {
		var i Category
		if err := rows.Scan(
			&i.ID,
			&i.Category,
			&i.Handle,
			&i.ParentID,
		); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getChildCategories = `-- name: GetChildCategories :many
SELECT id, category, handle, parent_id FROM categories where parent_id = $1
`

func (q *Queries) GetChildCategories(ctx context.Context, parentID *int32) ([]*Category, error) {
	rows, err := q.db.Query(ctx, getChildCategories, parentID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*Category
	for rows.Next() {
		var i Category
		if err := rows.Scan(
			&i.ID,
			&i.Category,
			&i.Handle,
			&i.ParentID,
		); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getLeafCategoryIDs = `-- name: GetLeafCategoryIDs :many
WITH RECURSIVE categories_cte AS (
    SELECT c.id, c.category, c.handle, c.parent_id
    FROM categories c
    WHERE c.id = $1
    UNION ALL
    SELECT c2.id, c2.category, c2.handle, c2.parent_id
    FROM categories c2
             JOIN categories_cte cte ON cte.id = c2.parent_id
)
SELECT array_agg(id)::INT[] AS leaf_category_ids
FROM categories_cte
WHERE id NOT IN (SELECT parent_id FROM categories WHERE parent_id IS NOT NULL)
`

func (q *Queries) GetLeafCategoryIDs(ctx context.Context, id int32) ([][]int32, error) {
	rows, err := q.db.Query(ctx, getLeafCategoryIDs, id)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items [][]int32
	for rows.Next() {
		var leaf_category_ids []int32
		if err := rows.Scan(&leaf_category_ids); err != nil {
			return nil, err
		}
		items = append(items, leaf_category_ids)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getRootCategories = `-- name: GetRootCategories :many
SELECT id, category, handle, parent_id FROM categories WHERE parent_id IS NULL
`

func (q *Queries) GetRootCategories(ctx context.Context) ([]*Category, error) {
	rows, err := q.db.Query(ctx, getRootCategories)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*Category
	for rows.Next() {
		var i Category
		if err := rows.Scan(
			&i.ID,
			&i.Category,
			&i.Handle,
			&i.ParentID,
		); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}
