-- ============================================================
-- spAdminUsers: User management
-- ============================================================
CREATE OR ALTER PROCEDURE [dbo].[spAdminUsers]
    @action VARCHAR(50),
    @rqst   NVARCHAR(MAX),
    @resp   NVARCHAR(MAX) OUTPUT
AS
BEGIN
    SET NOCOUNT ON;
    
    DECLARE @j NVARCHAR(MAX) = ISNULL(@rqst, N'{}');

    ------------------------------------------------------------------------
    -- ACTION: create
    ------------------------------------------------------------------------
    IF @action = 'create'
    BEGIN
        DECLARE @cEmail NVARCHAR(256) = NULLIF(JSON_VALUE(@j, '$.email'), '');
        DECLARE @cDisplayName NVARCHAR(256) = NULLIF(JSON_VALUE(@j, '$.displayName'), '');
        DECLARE @cClientId UNIQUEIDENTIFIER = TRY_CONVERT(UNIQUEIDENTIFIER, JSON_VALUE(@j, '$.clientId'));
        DECLARE @cRole VARCHAR(30) = ISNULL(NULLIF(JSON_VALUE(@j, '$.role'), ''), 'User');

        IF @cEmail IS NULL
        BEGIN
            SET @resp = N'{"ok":false,"error":"email is required"}';
            RETURN;
        END

        IF EXISTS (SELECT 1 FROM dbo.tbUser WHERE usrEmail = @cEmail)
        BEGIN
            SET @resp = N'{"ok":false,"error":"User with this email already exists"}';
            RETURN;
        END

        IF @cClientId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM dbo.tbClient WHERE cltId = @cClientId)
        BEGIN
            SET @resp = N'{"ok":false,"error":"Client not found"}';
            RETURN;
        END

        DECLARE @cUserId UNIQUEIDENTIFIER = NEWID();
        DECLARE @cEntraSub NVARCHAR(100) = 'pending-' + CAST(@cUserId AS NVARCHAR(50));
        
        INSERT INTO dbo.tbUser (usrId, usrEntraSub, usrProvider, usrSubject, usrEmail, usrDisplayName, usrStatus)
        VALUES (@cUserId, @cEntraSub, 'Pending', @cEntraSub, @cEmail, @cDisplayName, 'Active');

        IF @cClientId IS NOT NULL
        BEGIN
            INSERT INTO dbo.tbUserClientRole (ucrUsrId, ucrCltId, ucrRole)
            VALUES (@cUserId, @cClientId, @cRole);
        END

        SET @resp = (
            SELECT 
                CAST(1 AS BIT) AS ok,
                @cUserId AS userId,
                @cEmail AS email,
                @cDisplayName AS displayName,
                @cClientId AS clientId,
                @cRole AS [role]
            FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
        );
        RETURN;
    END

    ------------------------------------------------------------------------
    -- ACTION: get
    ------------------------------------------------------------------------
    IF @action = 'get'
    BEGIN
        DECLARE @gId UNIQUEIDENTIFIER = TRY_CONVERT(UNIQUEIDENTIFIER, JSON_VALUE(@j, '$.userId'));

        IF @gId IS NULL
        BEGIN
            SET @resp = N'{"ok":false,"error":"userId is required"}';
            RETURN;
        END

        IF NOT EXISTS (SELECT 1 FROM dbo.tbUser WHERE usrId = @gId)
        BEGIN
            SET @resp = N'{"ok":false,"error":"User not found"}';
            RETURN;
        END

        SET @resp = (
            SELECT 
                CAST(1 AS BIT) AS ok,
                u.usrId AS userId,
                u.usrEmail AS email,
                u.usrDisplayName AS displayName,
                u.usrStatus AS status,
                u.usrCreatedUtc AS createdAt,
                (
                    SELECT c.cltId AS clientId, c.cltName AS clientName, r.ucrRole AS [role]
                    FROM dbo.tbUserClientRole r
                    JOIN dbo.tbClient c ON c.cltId = r.ucrCltId
                    WHERE r.ucrUsrId = u.usrId
                    FOR JSON PATH
                ) AS clients
            FROM dbo.tbUser u WHERE u.usrId = @gId
            FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
        );
        RETURN;
    END

    ------------------------------------------------------------------------
    -- ACTION: list
    ------------------------------------------------------------------------
    IF @action = 'list'
    BEGIN
        DECLARE @lStatus VARCHAR(20) = NULLIF(JSON_VALUE(@j, '$.status'), '');
        DECLARE @lClientId UNIQUEIDENTIFIER = TRY_CONVERT(UNIQUEIDENTIFIER, JSON_VALUE(@j, '$.clientId'));
        DECLARE @lPage INT = ISNULL(TRY_CAST(JSON_VALUE(@j, '$.page') AS INT), 1);
        DECLARE @lPageSize INT = ISNULL(TRY_CAST(JSON_VALUE(@j, '$.pageSize') AS INT), 50);

        DECLARE @users NVARCHAR(MAX);
        SELECT @users = (
            SELECT 
                u.usrId AS userId,
                u.usrEmail AS email,
                u.usrDisplayName AS displayName,
                u.usrStatus AS status,
                u.usrCreatedUtc AS createdAt,
                (
                    SELECT c.cltId AS clientId, c.cltName AS clientName, r.ucrRole AS [role]
                    FROM dbo.tbUserClientRole r
                    JOIN dbo.tbClient c ON c.cltId = r.ucrCltId
                    WHERE r.ucrUsrId = u.usrId
                    FOR JSON PATH
                ) AS clients
            FROM dbo.tbUser u
            WHERE (@lStatus IS NULL OR u.usrStatus = @lStatus)
              AND (@lClientId IS NULL OR EXISTS (
                  SELECT 1 FROM dbo.tbUserClientRole WHERE ucrUsrId = u.usrId AND ucrCltId = @lClientId
              ))
            ORDER BY u.usrEmail
            OFFSET (@lPage - 1) * @lPageSize ROWS
            FETCH NEXT @lPageSize ROWS ONLY
            FOR JSON PATH
        );

        DECLARE @lTotal INT;
        SELECT @lTotal = COUNT(*) 
        FROM dbo.tbUser u
        WHERE (@lStatus IS NULL OR u.usrStatus = @lStatus)
          AND (@lClientId IS NULL OR EXISTS (
              SELECT 1 FROM dbo.tbUserClientRole WHERE ucrUsrId = u.usrId AND ucrCltId = @lClientId
          ));

        SET @resp = (
            SELECT 
                CAST(1 AS BIT) AS ok,
                JSON_QUERY(ISNULL(@users, '[]')) AS users,
                @lTotal AS totalCount,
                @lPage AS page,
                @lPageSize AS pageSize
            FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
        );
        RETURN;
    END

    ------------------------------------------------------------------------
    -- ACTION: update
    ------------------------------------------------------------------------
    IF @action = 'update'
    BEGIN
        DECLARE @uId UNIQUEIDENTIFIER = TRY_CONVERT(UNIQUEIDENTIFIER, JSON_VALUE(@j, '$.userId'));
        DECLARE @uDisplayName NVARCHAR(256) = NULLIF(JSON_VALUE(@j, '$.displayName'), '');
        DECLARE @uStatus VARCHAR(20) = NULLIF(JSON_VALUE(@j, '$.status'), '');

        IF @uId IS NULL
        BEGIN
            SET @resp = N'{"ok":false,"error":"userId is required"}';
            RETURN;
        END

        IF NOT EXISTS (SELECT 1 FROM dbo.tbUser WHERE usrId = @uId)
        BEGIN
            SET @resp = N'{"ok":false,"error":"User not found"}';
            RETURN;
        END

        UPDATE dbo.tbUser
        SET usrDisplayName = ISNULL(@uDisplayName, usrDisplayName),
            usrStatus = ISNULL(@uStatus, usrStatus)
        WHERE usrId = @uId;

        SET @resp = (
            SELECT 
                CAST(1 AS BIT) AS ok,
                usrId AS userId,
                usrEmail AS email,
                usrDisplayName AS displayName,
                usrStatus AS status
            FROM dbo.tbUser WHERE usrId = @uId
            FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
        );
        RETURN;
    END

    ------------------------------------------------------------------------
    -- ACTION: delete (soft delete)
    ------------------------------------------------------------------------
    IF @action = 'delete'
    BEGIN
        DECLARE @dId UNIQUEIDENTIFIER = TRY_CONVERT(UNIQUEIDENTIFIER, JSON_VALUE(@j, '$.userId'));

        IF @dId IS NULL
        BEGIN
            SET @resp = N'{"ok":false,"error":"userId is required"}';
            RETURN;
        END

        UPDATE dbo.tbUser SET usrStatus = 'Inactive' WHERE usrId = @dId;

        SET @resp = (SELECT CAST(1 AS BIT) AS ok, @@ROWCOUNT AS rowsAffected FOR JSON PATH, WITHOUT_ARRAY_WRAPPER);
        RETURN;
    END

    ------------------------------------------------------------------------
    -- ACTION: linkToClient
    ------------------------------------------------------------------------
    IF @action = 'linkToClient'
    BEGIN
        DECLARE @luUserId UNIQUEIDENTIFIER = TRY_CONVERT(UNIQUEIDENTIFIER, JSON_VALUE(@j, '$.userId'));
        DECLARE @luClientId UNIQUEIDENTIFIER = TRY_CONVERT(UNIQUEIDENTIFIER, JSON_VALUE(@j, '$.clientId'));
        DECLARE @luRole VARCHAR(30) = ISNULL(NULLIF(JSON_VALUE(@j, '$.role'), ''), 'User');

        IF @luUserId IS NULL OR @luClientId IS NULL
        BEGIN
            SET @resp = N'{"ok":false,"error":"userId and clientId are required"}';
            RETURN;
        END

        IF NOT EXISTS (SELECT 1 FROM dbo.tbUser WHERE usrId = @luUserId)
        BEGIN
            SET @resp = N'{"ok":false,"error":"User not found"}';
            RETURN;
        END

        IF NOT EXISTS (SELECT 1 FROM dbo.tbClient WHERE cltId = @luClientId)
        BEGIN
            SET @resp = N'{"ok":false,"error":"Client not found"}';
            RETURN;
        END

        IF EXISTS (SELECT 1 FROM dbo.tbUserClientRole WHERE ucrUsrId = @luUserId AND ucrCltId = @luClientId)
        BEGIN
            UPDATE dbo.tbUserClientRole
            SET ucrRole = @luRole
            WHERE ucrUsrId = @luUserId AND ucrCltId = @luClientId;

            SET @resp = (SELECT CAST(1 AS BIT) AS ok, 'updated' AS action, @luRole AS [role] FOR JSON PATH, WITHOUT_ARRAY_WRAPPER);
            RETURN;
        END

        INSERT INTO dbo.tbUserClientRole (ucrUsrId, ucrCltId, ucrRole)
        VALUES (@luUserId, @luClientId, @luRole);

        SET @resp = (SELECT CAST(1 AS BIT) AS ok, 'created' AS action, @luRole AS [role] FOR JSON PATH, WITHOUT_ARRAY_WRAPPER);
        RETURN;
    END

    ------------------------------------------------------------------------
    -- ACTION: unlinkFromClient
    ------------------------------------------------------------------------
    IF @action = 'unlinkFromClient'
    BEGIN
        DECLARE @ruUserId UNIQUEIDENTIFIER = TRY_CONVERT(UNIQUEIDENTIFIER, JSON_VALUE(@j, '$.userId'));
        DECLARE @ruClientId UNIQUEIDENTIFIER = TRY_CONVERT(UNIQUEIDENTIFIER, JSON_VALUE(@j, '$.clientId'));

        IF @ruUserId IS NULL OR @ruClientId IS NULL
        BEGIN
            SET @resp = N'{"ok":false,"error":"userId and clientId are required"}';
            RETURN;
        END

        DELETE FROM dbo.tbUserClientRole
        WHERE ucrUsrId = @ruUserId AND ucrCltId = @ruClientId;

        SET @resp = (SELECT CAST(1 AS BIT) AS ok, @@ROWCOUNT AS rowsAffected FOR JSON PATH, WITHOUT_ARRAY_WRAPPER);
        RETURN;
    END

    SET @resp = N'{"ok":false,"error":"Unknown action"}';
END
GO
