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

    ------------------------------------------------------------------------
    -- ACTION: list
    ------------------------------------------------------------------------
    IF @action = 'list'
    BEGIN
        DECLARE @lClientId UNIQUEIDENTIFIER = TRY_CONVERT(UNIQUEIDENTIFIER, JSON_VALUE(@j, '$.clientId'));
        DECLARE @lUserId UNIQUEIDENTIFIER = TRY_CONVERT(UNIQUEIDENTIFIER, JSON_VALUE(@j, '$.userId'));
        DECLARE @lActiveOnly BIT = ISNULL(TRY_CAST(JSON_VALUE(@j, '$.activeOnly') AS BIT), 1);
        DECLARE @lLimit INT = ISNULL(TRY_CAST(JSON_VALUE(@j, '$.limit') AS INT), 100);

        DECLARE @sessions NVARCHAR(MAX);
        SELECT @sessions = (
            SELECT TOP (@lLimit)
                s.sesId AS sessionId,
                u.usrId AS userId,
                u.usrEmail AS userEmail,
                u.usrDisplayName AS displayName,
                c.cltId AS clientId,
                c.cltName AS clientName,
                s.sesCreatedUtc AS createdAt,
                s.sesExpiresUtc AS expiresAt,
                s.sesLastActivityUtc AS lastActivity,
                s.sesIpAddress AS ipAddress,
                s.sesIsRevoked AS isRevoked
            FROM dbo.tbSession s
            JOIN dbo.tbUser u ON u.usrId = s.sesUsrId
            JOIN dbo.tbClient c ON c.cltId = s.sesCltId
            WHERE (@lClientId IS NULL OR c.cltId = @lClientId)
              AND (@lUserId IS NULL OR u.usrId = @lUserId)
              AND (@lActiveOnly = 0 OR (s.sesIsRevoked = 0 AND s.sesExpiresUtc > SYSUTCDATETIME()))
            ORDER BY s.sesLastActivityUtc DESC
            FOR JSON PATH
        );

        SET @resp = (
            SELECT 
                CAST(1 AS BIT) AS ok,
                JSON_QUERY(ISNULL(@sessions, '[]')) AS sessions
            FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
        );
        RETURN;
    END

    ------------------------------------------------------------------------
    -- ACTION: revoke
    ------------------------------------------------------------------------
    IF @action = 'revoke'
    BEGIN
        DECLARE @rSessionId UNIQUEIDENTIFIER = TRY_CONVERT(UNIQUEIDENTIFIER, JSON_VALUE(@j, '$.sessionId'));

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

        UPDATE dbo.tbSession SET sesIsRevoked = 1 WHERE sesId = @rSessionId;

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

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

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

        UPDATE dbo.tbSession SET sesIsRevoked = 1 WHERE sesUsrId = @raUserId;

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

    ------------------------------------------------------------------------
    -- ACTION: cleanup
    ------------------------------------------------------------------------
    IF @action = 'cleanup'
    BEGIN
        DECLARE @daysOld INT = ISNULL(TRY_CAST(JSON_VALUE(@j, '$.daysOld') AS INT), 30);

        DELETE FROM dbo.tbSession
        WHERE sesExpiresUtc < DATEADD(DAY, -@daysOld, SYSUTCDATETIME());

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

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