CREATE PROCEDURE [dbo].[TRN_Account_SetBalance]
	 @UserId						bigint
		,@AccountId						bigint
		,@AccountTransactionTypeId		tinyint			-- FreeTokenCredit = 1, Deposit = 2, Withdraw = 3
		,@Amount						decimal(22,8)
		,@AmountUSD						decimal(18,2)
		,@ExternalReferenceId			varchar(66)		= NULL
		,@OperatorId					int
		,@Comment						nvarchar(1000)
		,@WalletAddress					varchar(42)
		,@PendingId						bigint
		,@IsUserTransactionDonor		bit				= 0
		,@KnokId						bigint			= NULL
		,@TransId						bigint OUTPUT
AS


SET NOCOUNT ON


DECLARE @CurrentBalance					Decimal(22,8),
		@CurrentBonusBalance			Decimal(22,8),
		@TranStarted					bit,
		@RC								int,
		@ErrorMessage					nvarchar(1000)

		
BEGIN TRY 
	SET @RC = 0
	SET	@TranStarted = 0

	IF @AccountTransactionTypeId NOT IN (1,2,3,4,5,8,9)
	BEGIN
		SET @RC = 2
		SET @ErrorMessage = 'AccountTransaction Type is illegal. @AccountTransactionTypeId = ' + Cast(@AccountTransactionTypeId AS Varchar(20))
		RAISERROR (@ErrorMessage,16,1)
	END


	IF not exists(SELECT 1 FROM Accounts WITH (NOLOCK) WHERE [UserId] = @UserId and AccountId=@AccountId)
	BEGIN
		SET @RC = 3
		SET @ErrorMessage = 'User not found for this Account (UserId is NULL value). @AccountId = ' + Cast(@AccountId AS Varchar(20)) 
		RAISERROR (@ErrorMessage,16,1);        
	END

	--TODO: review it. Sometimes there is possible to have same transactions (for example when Platform user receives or returns payments for some knok)
	--IF @KnokId is not null AND @IsUserTransactionDonor = 0 AND exists(SELECT 1 FROM AccountTransactions WITH (NOLOCK) WHERE [UserId] = @UserId and AccountId=@AccountId and KnokId = @KnokId and AccountTransactionTypeId = @AccountTransactionTypeId)
	--BEGIN
	--	SET @RC = 4
	--	SET @ErrorMessage = 'AccountTransaction already exists. @KnokId = ' + Cast(@KnokId AS Varchar(20)) + 'AccountTransactionTypeId = ' + Cast(@AccountTransactionTypeId AS Varchar(20))
	--	RAISERROR (@ErrorMessage,16,1);        
	--END

	--IF @ExternalReferenceId Is Null
	--BEGIN
	--	SET @RC = 4
	--	SET @ErrorMessage = 'External Reference cannot be null'
	--	RAISERROR (@ErrorMessage,16,1);
	--END

	If @ErrorMessage IS NOT NULL AND EXISTS(SELECT 1 FROM AccountTransactions WHERE [ExternalReferenceId] = @ExternalReferenceId)
	BEGIN
		SET @RC = 5
		SET @ErrorMessage = 'External Reference already registered'
		RAISERROR (@ErrorMessage,16,1);
	END					

IF( @@TRANCOUNT = 0 )            
	BEGIN            
		BEGIN TRANSACTION            
		SET @TranStarted = 1            
	END            
	ELSE            
		SET @TranStarted = 0  
	

	SELECT	@CurrentBalance = IsNull(CurrentBalance,0) 	,
			@CurrentBonusBalance = IsNull(CurrentBonusBalance,0 ) 
	FROM Accounts WITH (ROWLOCK) 
	WHERE AccountId = @AccountId
	

	IF @IsUserTransactionDonor = 1 OR @AccountTransactionTypeId in (3) --Withdraw
	BEGIN
		IF (@CurrentBalance  - CAST(IsNull(@Amount,0) AS DECIMAL(22,8)) ) < 0
		BEGIN
			SET @RC = 6
			SET @ErrorMessage = 'Current Balance Cannot be Negative : ' + Cast((@CurrentBalance - @Amount) AS Varchar(20))
			RAISERROR (@ErrorMessage,16,1);        
		END
		
			SET @Amount = -@Amount
			SET @AmountUSD = -@AmountUSD
	END  

	SET @CurrentBalance  = @CurrentBalance + @Amount
    set @CurrentBonusBalance  = @CurrentBonusBalance + @Amount


		EXECUTE @RC = [dbo].[TRN_AccountTransactions_Add] 
		   @UserId
		  ,@AccountId
		  ,@AccountTransactionTypeId
		  ,@Amount
		  ,@AmountUSD
		  ,@CurrentBalance
		  ,@CurrentBonusBalance
		  ,@ExternalReferenceId
		  ,@OperatorId
		  ,@Comment
		  ,@WalletAddress
		  ,@PendingId
		  ,@KnokId
		  ,@TransId OUTPUT




	SELECT  @TransId AS TransId,
			@CurrentBalance AS CurrentBalance,
			@CurrentBonusBalance AS CurrentBonusBalance

	IF( @TranStarted = 1 )            
		COMMIT TRANSACTION            

	RETURN 0

END TRY           
BEGIN CATCH            
    IF( @TranStarted = 1 )            
		ROLLBACK TRANSACTION            

	EXEC [USP_LogError]           
	EXEC [USP_RethrowError]   
	
	IF @RC = 0 
		SET @RC = 1			         
	RETURN @RC
END CATCH