-- Фаза 1B: RBAC (Role-Based Access Control) (КРИТИЧНО)
-- Запросы для управления ролями и правами доступа

-- ============================================================================
-- Роли
-- ============================================================================

-- name: GetRoleByName :one
SELECT * FROM roles
WHERE name = $1;

-- name: GetRoleByID :one
SELECT * FROM roles
WHERE id = $1;

-- name: ListAllRoles :many
SELECT * FROM roles
ORDER BY name;

-- ============================================================================
-- Пользовательские роли
-- ============================================================================

-- name: GetUserRoles :many
SELECT r.* FROM roles r
JOIN user_roles ur ON ur.role_id = r.id
WHERE ur.user_id = $1
ORDER BY r.name;

-- 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 *;

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

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

-- 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
);

-- ============================================================================
-- Права доступа
-- ============================================================================

-- 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;

-- name: GetPermissionByName :one
SELECT * FROM permissions
WHERE name = $1;

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

-- 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
);

-- 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
);
