/// <summary>
        /// This method will fetch all information about direct messaging entry.
        /// </summary>
        /// <param name="userId">The id of the requesting user</param>
        /// <param name="firstParticipantId">The user id of the first participant</param>
        /// <param name="secondParticipantId">The user id of the second participant</param>
        /// <returns>An either monad</returns>
        public Either <DirectMessaging, Error> Get(long userId, long firstParticipantId, long secondParticipantId)
        {
            try
            {
                if (userId != firstParticipantId && userId != secondParticipantId)
                {
                    return(new Failure <DirectMessaging, Error>(DirectMessagingErrors.DirectMessagingNotFound()));
                }

                var directMessaging = _burstChatContext
                                      .DirectMessaging
                                      .Include(dm => dm.FirstParticipantUser)
                                      .Include(dm => dm.SecondParticipantUser)
                                      .FirstOrDefault(dm => (dm.FirstParticipantUserId == firstParticipantId && dm.SecondParticipantUserId == secondParticipantId) ||
                                                      (dm.FirstParticipantUserId == secondParticipantId && dm.SecondParticipantUserId == firstParticipantId));

                return(directMessaging is not null
                    ? new Success <DirectMessaging, Error>(directMessaging)
                    : new Failure <DirectMessaging, Error>(DirectMessagingErrors.DirectMessagesNotFound()));
            }
            catch (Exception e)
            {
                _logger.LogError(e.Message);
                return(new Failure <DirectMessaging, Error>(SystemErrors.Exception()));
            }
        }
        /// <summary>
        /// This method will delete a message from the direct messaging entry.
        /// </summary>
        /// <param name="userId">The id of the requesting user</param>
        /// <param name="directMessagingId">The id of the direct messaging entry</param>
        /// <param name="messageId">The id of the message to be deleted</param>
        /// <returns>An either monad</returns>
        public Either <Message, Error> DeleteMessage(long userId, long directMessagingId, long messageId)
        {
            try
            {
                return(Get(userId, directMessagingId).Bind <Message>(_ =>
                {
                    var directMessaging = _burstChatContext
                                          .DirectMessaging
                                          .Include(dm => dm.Messages.Where(m => m.Id == messageId))
                                          .First(dm => dm.Id == directMessagingId);

                    if (!directMessaging.Messages.Any())
                    {
                        return new Failure <Message, Error>(DirectMessagingErrors.DirectMessagesNotFound());
                    }

                    var message = directMessaging.Messages.First() !;
                    directMessaging.Messages.Remove(message);
                    _burstChatContext.SaveChanges();

                    return new Success <Message, Error>(message);
                }));
            }
            catch (Exception e)
            {
                _logger.LogError(e.Message);
                return(new Failure <Message, Error>(SystemErrors.Exception()));
            }
        }
        /// <summary>
        /// This method will add a new message to a direct messaging entry.
        /// </summary>
        /// <param name="userId">The id of the requesting user</param>
        /// <param name="directMessagingId">The id of the target direct messaging entry</param>
        /// <param name="message">The message instance that will be used for the insertion</param>
        /// <returns>An either monad</returns>
        public Either <Message, Error> InsertMessage(long userId, long directMessagingId, Message message)
        {
            try
            {
                return(Get(userId, directMessagingId).Bind <Message>(directMessaging =>
                {
                    var user = _burstChatContext
                               .Users
                               .FirstOrDefault(u => u.Id == userId);

                    if (user is null || message is null)
                    {
                        return new Failure <Message, Error>(DirectMessagingErrors.DirectMessagesNotFound());
                    }

                    var newMessage = new Message
                    {
                        User = user,
                        Links = message.GetLinksFromContent(),
                        Content = message.RemoveLinksFromContent(),
                        Edited = false,
                        DatePosted = message.DatePosted
                    };
                    directMessaging.Messages.Add(newMessage);
                    _burstChatContext.SaveChanges();

                    return new Success <Message, Error>(newMessage);
                }));
            }
            catch (Exception e)
            {
                _logger.LogError(e.Message);
                return(new Failure <Message, Error>(SystemErrors.Exception()));
            }
        }
        /// <summary>
        /// This method will create a new direct messaging entry.
        /// </summary>
        /// <param name="userId">The id of the requesting user</param>
        /// <param name="firstParticipantId">The user id of the first participant</param>
        /// <param name="secondParticipantId">The user id of the second participant</param>
        /// <returns>An either monad</returns>
        public Either <DirectMessaging, Error> Insert(long userId, long firstParticipantId, long secondParticipantId)
        {
            try
            {
                var isProperUser = firstParticipantId == userId ||
                                   secondParticipantId == userId;

                var directMessaging = _burstChatContext
                                      .DirectMessaging
                                      .FirstOrDefault(dm => (dm.FirstParticipantUserId == firstParticipantId && dm.SecondParticipantUserId == secondParticipantId) ||
                                                      (dm.FirstParticipantUserId == secondParticipantId && dm.SecondParticipantUserId == firstParticipantId));

                if (!isProperUser || directMessaging is not null)
                {
                    return(new Failure <DirectMessaging, Error>(DirectMessagingErrors.DirectMessagingAlreadyExists()));
                }

                var newDirectMessaging = new DirectMessaging
                {
                    FirstParticipantUserId  = firstParticipantId,
                    SecondParticipantUserId = secondParticipantId,
                };
                _burstChatContext
                .DirectMessaging
                .Add(newDirectMessaging);
                _burstChatContext.SaveChanges();

                return(new Success <DirectMessaging, Error>(newDirectMessaging));
            }
            catch (Exception e)
            {
                _logger.LogError(e.Message);
                return(new Failure <DirectMessaging, Error>(SystemErrors.Exception()));
            }
        }
        /// <summary>
        /// This method will fetch all information about direct messaging entry.
        /// </summary>
        /// <param name="userId">The id of the requesting user</param>
        /// <param name="directMessagingId">The id of the direct messages</param>
        /// <returns>An either monad</returns>
        public Either <DirectMessaging, Error> Get(long userId, long directMessagingId)
        {
            try
            {
                var directMessaging = _burstChatContext
                                      .DirectMessaging
                                      .FirstOrDefault(dm => dm.Id == directMessagingId &&
                                                      (dm.FirstParticipantUserId == userId ||
                                                       dm.SecondParticipantUserId == userId));

                return(directMessaging is not null
                    ? new Success <DirectMessaging, Error>(directMessaging)
                    : new Failure <DirectMessaging, Error>(DirectMessagingErrors.DirectMessagesNotFound()));
            }
            catch (Exception e)
            {
                _logger.LogError(e.Message);
                return(new Failure <DirectMessaging, Error>(SystemErrors.Exception()));
            }
        }
        /// <summary>
        /// This method will be edit a message of a direct messaging entry.
        /// </summary>
        /// <param name="userId">The id of the requesting user</param>
        /// <param name="directMessagingId">The id of the direct messaging entry</param>
        /// <param name="message">The message instance that will be used for the edit</param>
        /// <returns>An either monad<returns>
        public Either <Message, Error> UpdateMessage(long userId, long directMessagingId, Message message)
        {
            try
            {
                if (message is null)
                {
                    return(new Failure <Message, Error>(DirectMessagingErrors.DirectMessageNotFound()));
                }

                return(Get(userId, directMessagingId).Bind <Message>(_ =>
                {
                    var entries = _burstChatContext
                                  .DirectMessaging
                                  .Include(dm => dm.Messages)
                                  .ThenInclude(dm => dm.User)
                                  .Include(dm => dm.Messages)
                                  .ThenInclude(dm => dm.Links)
                                  .Where(dm => dm.Id == directMessagingId)
                                  .Select(dm => dm.Messages.FirstOrDefault(m => m.Id == message.Id))
                                  .ToList();

                    if (entries.Count != 1)
                    {
                        return new Failure <Message, Error>(DirectMessagingErrors.DirectMessageNotFound());
                    }

                    var entry = entries.First() !;
                    entry.Links = message.GetLinksFromContent();
                    entry.Content = message.RemoveLinksFromContent();
                    entry.Edited = true;
                    _burstChatContext.SaveChanges();

                    return new Success <Message, Error>(entry);
                }));
            }
            catch (Exception e)
            {
                _logger.LogError(e.Message);
                return(new Failure <Message, Error>(SystemErrors.Exception()));
            }
        }