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

package database

import (
	"context"

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

const AssignRoleToUser = `-- name: AssignRoleToUser :one
INSERT INTO user_roles (user_id, role_id, assigned_by)
VALUES ($1, $2, $3)
ON CONFLICT (user_id, role_id) DO NOTHING
RETURNING id, user_id, role_id, assigned_at, assigned_by
`

type AssignRoleToUserParams struct {
	UserID     int64       `json:"user_id"`
	RoleID     int64       `json:"role_id"`
	AssignedBy pgtype.Int8 `json:"assigned_by"`
}

func (q *Queries) AssignRoleToUser(ctx context.Context, arg AssignRoleToUserParams) (UserRole, error) {
	row := q.db.QueryRow(ctx, AssignRoleToUser, arg.UserID, arg.RoleID, arg.AssignedBy)
	var i UserRole
	err := row.Scan(
		&i.ID,
		&i.UserID,
		&i.RoleID,
		&i.AssignedAt,
		&i.AssignedBy,
	)
	return i, err
}

const GetPermissionByName = `-- name: GetPermissionByName :one
SELECT id, name, resource, action, description, created_at FROM permissions
WHERE name = $1
`

func (q *Queries) GetPermissionByName(ctx context.Context, name string) (Permission, error) {
	row := q.db.QueryRow(ctx, GetPermissionByName, name)
	var i Permission
	err := row.Scan(
		&i.ID,
		&i.Name,
		&i.Resource,
		&i.Action,
		&i.Description,
		&i.CreatedAt,
	)
	return i, err
}

const GetRoleByID = `-- name: GetRoleByID :one
SELECT id, name, description, created_at FROM roles
WHERE id = $1
`

func (q *Queries) GetRoleByID(ctx context.Context, id int64) (Role, error) {
	row := q.db.QueryRow(ctx, GetRoleByID, id)
	var i Role
	err := row.Scan(
		&i.ID,
		&i.Name,
		&i.Description,
		&i.CreatedAt,
	)
	return i, err
}

const GetRoleByName = `-- name: GetRoleByName :one


SELECT id, name, description, created_at FROM roles
WHERE name = $1
`

// Фаза 1B: RBAC (Role-Based Access Control) (КРИТИЧНО)
// Запросы для управления ролями и правами доступа
// ============================================================================
// Роли
// ============================================================================
func (q *Queries) GetRoleByName(ctx context.Context, name string) (Role, error) {
	row := q.db.QueryRow(ctx, GetRoleByName, name)
	var i Role
	err := row.Scan(
		&i.ID,
		&i.Name,
		&i.Description,
		&i.CreatedAt,
	)
	return i, err
}

const GetUserPermissions = `-- name: GetUserPermissions :many

SELECT DISTINCT p.name, p.resource, p.action, p.description
FROM users u
JOIN user_roles ur ON ur.user_id = u.id
JOIN role_permissions rp ON rp.role_id = ur.role_id
JOIN permissions p ON p.id = rp.permission_id
WHERE u.id = $1
    AND u.deleted_at IS NULL
    AND u.is_blocked = FALSE
ORDER BY p.resource, p.action
`

type GetUserPermissionsRow struct {
	Name        string      `json:"name"`
	Resource    string      `json:"resource"`
	Action      string      `json:"action"`
	Description pgtype.Text `json:"description"`
}

// ============================================================================
// Права доступа
// ============================================================================
func (q *Queries) GetUserPermissions(ctx context.Context, id int64) ([]GetUserPermissionsRow, error) {
	rows, err := q.db.Query(ctx, GetUserPermissions, id)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []GetUserPermissionsRow{}
	for rows.Next() {
		var i GetUserPermissionsRow
		if err := rows.Scan(
			&i.Name,
			&i.Resource,
			&i.Action,
			&i.Description,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const GetUserRoles = `-- name: GetUserRoles :many

SELECT r.id, r.name, r.description, r.created_at FROM roles r
JOIN user_roles ur ON ur.role_id = r.id
WHERE ur.user_id = $1
ORDER BY r.name
`

// ============================================================================
// Пользовательские роли
// ============================================================================
func (q *Queries) GetUserRoles(ctx context.Context, userID int64) ([]Role, error) {
	rows, err := q.db.Query(ctx, GetUserRoles, userID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []Role{}
	for rows.Next() {
		var i Role
		if err := rows.Scan(
			&i.ID,
			&i.Name,
			&i.Description,
			&i.CreatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const ListAllRoles = `-- name: ListAllRoles :many
SELECT id, name, description, created_at FROM roles
ORDER BY name
`

func (q *Queries) ListAllRoles(ctx context.Context) ([]Role, error) {
	rows, err := q.db.Query(ctx, ListAllRoles)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []Role{}
	for rows.Next() {
		var i Role
		if err := rows.Scan(
			&i.ID,
			&i.Name,
			&i.Description,
			&i.CreatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const ListPermissionsByRole = `-- name: ListPermissionsByRole :many
SELECT p.id, p.name, p.resource, p.action, p.description, p.created_at FROM permissions p
JOIN role_permissions rp ON rp.permission_id = p.id
WHERE rp.role_id = $1
ORDER BY p.resource, p.action
`

func (q *Queries) ListPermissionsByRole(ctx context.Context, roleID int64) ([]Permission, error) {
	rows, err := q.db.Query(ctx, ListPermissionsByRole, roleID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []Permission{}
	for rows.Next() {
		var i Permission
		if err := rows.Scan(
			&i.ID,
			&i.Name,
			&i.Resource,
			&i.Action,
			&i.Description,
			&i.CreatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const RemoveRoleFromUser = `-- name: RemoveRoleFromUser :exec
DELETE FROM user_roles
WHERE user_id = $1 AND role_id = $2
`

type RemoveRoleFromUserParams struct {
	UserID int64 `json:"user_id"`
	RoleID int64 `json:"role_id"`
}

func (q *Queries) RemoveRoleFromUser(ctx context.Context, arg RemoveRoleFromUserParams) error {
	_, err := q.db.Exec(ctx, RemoveRoleFromUser, arg.UserID, arg.RoleID)
	return err
}

const UserHasAnyPermission = `-- name: UserHasAnyPermission :one
SELECT EXISTS(
    SELECT 1
    FROM users u
    JOIN user_roles ur ON ur.user_id = u.id
    JOIN role_permissions rp ON rp.role_id = ur.role_id
    JOIN permissions p ON p.id = rp.permission_id
    WHERE u.id = $1
        AND p.name = ANY($2::varchar[])
        AND u.deleted_at IS NULL
        AND u.is_blocked = FALSE
)
`

type UserHasAnyPermissionParams struct {
	ID      int64    `json:"id"`
	Column2 []string `json:"column_2"`
}

func (q *Queries) UserHasAnyPermission(ctx context.Context, arg UserHasAnyPermissionParams) (bool, error) {
	row := q.db.QueryRow(ctx, UserHasAnyPermission, arg.ID, arg.Column2)
	var exists bool
	err := row.Scan(&exists)
	return exists, err
}

const UserHasPermission = `-- name: UserHasPermission :one
SELECT EXISTS(
    SELECT 1
    FROM users u
    JOIN user_roles ur ON ur.user_id = u.id
    JOIN role_permissions rp ON rp.role_id = ur.role_id
    JOIN permissions p ON p.id = rp.permission_id
    WHERE u.id = $1
        AND p.name = $2
        AND u.deleted_at IS NULL
        AND u.is_blocked = FALSE
)
`

type UserHasPermissionParams struct {
	ID   int64  `json:"id"`
	Name string `json:"name"`
}

func (q *Queries) UserHasPermission(ctx context.Context, arg UserHasPermissionParams) (bool, error) {
	row := q.db.QueryRow(ctx, UserHasPermission, arg.ID, arg.Name)
	var exists bool
	err := row.Scan(&exists)
	return exists, err
}

const UserHasRole = `-- name: UserHasRole :one
SELECT EXISTS(
    SELECT 1 FROM user_roles
    WHERE user_id = $1 AND role_id = $2
)
`

type UserHasRoleParams struct {
	UserID int64 `json:"user_id"`
	RoleID int64 `json:"role_id"`
}

func (q *Queries) UserHasRole(ctx context.Context, arg UserHasRoleParams) (bool, error) {
	row := q.db.QueryRow(ctx, UserHasRole, arg.UserID, arg.RoleID)
	var exists bool
	err := row.Scan(&exists)
	return exists, err
}

const UserHasRoleByName = `-- name: UserHasRoleByName :one
SELECT EXISTS(
    SELECT 1 FROM user_roles ur
    JOIN roles r ON r.id = ur.role_id
    WHERE ur.user_id = $1 AND r.name = $2
)
`

type UserHasRoleByNameParams struct {
	UserID int64  `json:"user_id"`
	Name   string `json:"name"`
}

func (q *Queries) UserHasRoleByName(ctx context.Context, arg UserHasRoleByNameParams) (bool, error) {
	row := q.db.QueryRow(ctx, UserHasRoleByName, arg.UserID, arg.Name)
	var exists bool
	err := row.Scan(&exists)
	return exists, err
}
