/// <summary>
        /// Command wrong
        /// </summary>
        /// <param name="p_Service">Chat service</param>
        /// <param name="p_Message">Chat message</param>
        private void Command_Wrong(IChatService p_Service, IChatMessage p_Message)
        {
            SongEntry l_SongEntry = null;

            lock (SongQueue)
            {
                l_SongEntry = SongQueue.Where(x => x.RequesterName == p_Message.Sender.UserName).LastOrDefault();
                if (l_SongEntry != null)
                {
                    SongQueue.Remove(l_SongEntry);
                }
            }

            if (l_SongEntry != null)
            {
                SendChatMessage($"@{p_Message.Sender.UserName} (bsr {l_SongEntry.BeatMap.Key}) {l_SongEntry.BeatMap.Metadata.SongName} / {l_SongEntry.BeatMap.Metadata.LevelAuthorName} is removed from queue!");

                /// Update request manager
                OnQueueChanged();
            }
            else
            {
                SendChatMessage($"@{p_Message.Sender.UserName} You have no song in queue!");
            }
        }
        /// <summary>
        /// Command remove
        /// </summary>
        /// <param name="p_Service">Chat service</param>
        /// <param name="p_Message">Chat message</param>
        private void Command_Remove(IChatService p_Service, IChatMessage p_Message, string p_ID)
        {
            if (!HasPower(p_Message.Sender))
            {
                SendChatMessage($"@{p_Message.Sender.UserName} You have no power here!");
                return;
            }

            string l_Key = p_ID.ToLower();

            SongEntry l_SongEntry = null;

            lock (SongQueue)
            {
                l_SongEntry = SongQueue.Where(x => x.BeatMap.Key.ToLower() == l_Key).FirstOrDefault();
                if (l_SongEntry != null)
                {
                    SongQueue.Remove(l_SongEntry);
                }
            }

            if (l_SongEntry != null)
            {
                SendChatMessage($"@{p_Message.Sender.UserName} (bsr {l_SongEntry.BeatMap.Key}) {l_SongEntry.BeatMap.Metadata.SongName} / {l_SongEntry.BeatMap.Metadata.LevelAuthorName} is removed from queue!");

                /// Update request manager
                OnQueueChanged();
            }
            else
            {
                SendChatMessage($"@{p_Message.Sender.UserName} No song in queue found with the key \"{l_Key}\"!");
            }
        }
        /// <summary>
        /// Move song to top
        /// </summary>
        /// <param name="p_Service">Chat service</param>
        /// <param name="p_Message">Chat message</param>
        /// <param name="p_ID">ID of the BSR</param>
        private void Command_MoveToTop(IChatService p_Service, IChatMessage p_Message, string p_ID)
        {
            if (!HasPower(p_Message.Sender))
            {
                SendChatMessage($"@{p_Message.Sender.UserName} You have no power here!");
                return;
            }

            string l_Key = p_ID.ToLower();

            lock (SongQueue)
            {
                var l_BeatMap = SongQueue.Where(x => x.BeatMap.Key.ToLower() == l_Key).FirstOrDefault();
                if (l_BeatMap != null)
                {
                    SongQueue.Remove(l_BeatMap);
                    SongQueue.Insert(0, l_BeatMap);

                    SendChatMessage($"@{p_Message.Sender.UserName} (bsr {l_BeatMap.BeatMap.Key}) {l_BeatMap.BeatMap.Metadata.SongName} / {l_BeatMap.BeatMap.Metadata.LevelAuthorName} is now on top of queue!");

                    /// Update request manager
                    OnQueueChanged();

                    return;
                }

                SendChatMessage($"@{p_Message.Sender.UserName} No song in queue found with the key \"{l_Key}\"!");
            }
        }
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Handle BSR command
        /// </summary>
        /// <param name="p_Service">Chat service</param>
        /// <param name="p_Message">Chat message</param>
        /// <param name="p_ID">ID of the BSR</param>
        private void Command_BSR(IChatService p_Service, IChatMessage p_Message, string p_ID, bool p_ModeratorAddCommand, bool p_ModeratorAddToTop)
        {
            bool l_IsModerator = HasPower(p_Message.Sender);

            if (p_ModeratorAddCommand && !l_IsModerator)
            {
                SendChatMessage($"@{p_Message.Sender.UserName} You have no power here!");
                return;
            }

            if (!QueueOpen && !(l_IsModerator && p_ModeratorAddCommand))
            {
                SendChatMessage($"@{p_Message.Sender.UserName} the queue is closed!");
                return;
            }

            string l_Key = p_ID.ToLower();

            if (!OnlyHexInString(l_Key))
            {
                _ = m_BeatSaver.Search(l_Key).ContinueWith((p_SearchTaskResult) =>
                {
                    if (p_SearchTaskResult.Result == null || p_SearchTaskResult.Result.Docs.Count == 0)
                    {
                        SendChatMessage($"@{p_Message.Sender.UserName} your search \"{l_Key}\" produced 0 results!");
                        return;
                    }

                    var l_Docs     = p_SearchTaskResult.Result.Docs;
                    string l_Reply = $"@{p_Message.Sender.UserName} your search \"{l_Key}\" produced {l_Docs.Count} results : ";

                    int l_I = 0;
                    for (; l_I < l_Docs.Count && l_I < 4; ++l_I)
                    {
                        if (l_I != 0)
                        {
                            l_Reply += ", ";
                        }

                        l_Reply += " (!bsr " + l_Docs[l_I].Key + ") " + l_Docs[l_I].Name;
                    }

                    if (l_I < l_Docs.Count)
                    {
                        l_Reply += "...";
                    }

                    SendChatMessage(l_Reply);
                });

                return;
            }

            var l_UserRequestCount = 0;

            /// Check if blacklisted
            if (!(l_IsModerator && p_ModeratorAddCommand))
            {
                lock (SongBlackList)
                {
                    var l_BeatMap = SongBlackList.Where(x => x.BeatMap.Key.ToLower() == l_Key).FirstOrDefault();
                    if (l_BeatMap != null)
                    {
                        SendChatMessage($"@{p_Message.Sender.UserName} (bsr {l_BeatMap.BeatMap.Key}) {l_BeatMap.BeatMap.Metadata.SongName} / {l_BeatMap.BeatMap.Metadata.LevelAuthorName} is blacklisted!");
                        return;
                    }
                }
            }

            /// Check if already in queue
            lock (SongQueue)
            {
                var l_BeatMap = SongQueue.Where(x => x.BeatMap.Key.ToLower() == l_Key).FirstOrDefault();
                if (l_BeatMap != null)
                {
                    SendChatMessage($"@{p_Message.Sender.UserName} (bsr {l_BeatMap.BeatMap.Key}) {l_BeatMap.BeatMap.Metadata.SongName} / {l_BeatMap.BeatMap.Metadata.LevelAuthorName} is already in queue!");
                    return;
                }

                l_UserRequestCount = SongQueue.Where(x => x.RequesterName == p_Message.Sender.UserName).Count();
            }

            string l_NamePrefix = "";

            /// Handle request limits
            if (p_Service is BeatSaberPlusChatCore.Services.Twitch.TwitchService)
            {
                var l_TwitchUser = p_Message.Sender as BeatSaberPlusChatCore.Models.Twitch.TwitchUser;

                (int, string)l_Limit = (Config.ChatRequest.UserMaxRequest, "Users");

                if (l_TwitchUser.IsVip && !l_TwitchUser.IsSubscriber)
                {
                    l_Limit = (l_Limit.Item1 + Config.ChatRequest.VIPBonusRequest, "VIPs");
                }
                if (l_TwitchUser.IsSubscriber && !l_TwitchUser.IsVip)
                {
                    l_Limit = (l_Limit.Item1 + Config.ChatRequest.SubscriberBonusRequest, "Subscribers");
                }
                if (l_TwitchUser.IsSubscriber && l_TwitchUser.IsVip)
                {
                    l_Limit = (l_Limit.Item1 + Config.ChatRequest.VIPBonusRequest + Config.ChatRequest.SubscriberBonusRequest, "VIP Subscribers");
                }
                if (l_TwitchUser.IsModerator || l_TwitchUser.IsBroadcaster)
                {
                    l_Limit = (1000, "Moderators");
                }

                if (l_TwitchUser.IsModerator || l_TwitchUser.IsBroadcaster)
                {
                    l_NamePrefix = "🗡";
                }
                else if (l_TwitchUser.IsVip)
                {
                    l_NamePrefix = "💎";
                }
                else if (l_TwitchUser.IsSubscriber)
                {
                    l_NamePrefix = "👑";
                }

                if (l_UserRequestCount >= l_Limit.Item1)
                {
                    SendChatMessage($"@{p_Message.Sender.UserName} You already have {l_UserRequestCount} on the queue. {l_Limit.Item2} are limited to {l_Limit.Item1} request(s).");
                    return;
                }
            }

            /// Check if already requested
            if (!(l_IsModerator && p_ModeratorAddCommand) && m_RequestedThisSession.Contains(l_Key))
            {
                SendChatMessage($"@{p_Message.Sender.UserName} this song was already requested this session!");
                return;
            }

            /// Fetch beatmap
            _ = m_BeatSaver.Key(l_Key).ContinueWith(p_SongTaskResult =>
            {
                try
                {
                    string l_Reply = "@" + p_Message.Sender.UserName + " map " + l_Key + " not found.";
                    if (p_SongTaskResult.Result != null && ((l_IsModerator && p_ModeratorAddCommand) || FilterBeatMap(p_SongTaskResult.Result, p_Message.Sender.UserName, out l_Reply)))
                    {
                        var l_BeatMap = p_SongTaskResult.Result;
                        float l_Vote  = (float)Math.Round((double)l_BeatMap.Stats.Rating * 100f, 0);

                        if ((l_IsModerator && p_ModeratorAddCommand) || !m_RequestedThisSession.Contains(l_Key))
                        {
                            m_RequestedThisSession.Add(l_Key.ToLower());

                            var l_Entry = new SongEntry()
                            {
                                BeatMap       = l_BeatMap,
                                RequesterName = p_Message.Sender.UserName,
                                RequestTime   = DateTime.Now,
                                NamePrefix    = l_NamePrefix
                            };

                            lock (SongQueue)
                            {
                                if (l_IsModerator && p_ModeratorAddToTop)
                                {
                                    SongQueue.Insert(0, l_Entry);
                                }
                                else
                                {
                                    SongQueue.Add(l_Entry);
                                }
                            }

                            /// Update request manager
                            OnQueueChanged();

                            l_Reply = $"(bsr {l_BeatMap.Key}) {l_BeatMap.Metadata.SongName} / {l_BeatMap.Metadata.LevelAuthorName} {l_Vote}% requested by @{p_Message.Sender.UserName} added to queue.";
                        }
                        else
                        {
                            l_Reply = $"@{p_Message.Sender.UserName} this song was already requested this session!";
                        }
                    }

                    SendChatMessage(l_Reply);
                }
                catch (System.Exception p_Exception)
                {
                    Logger.Instance.Error("Command_BSR");
                    Logger.Instance.Error(p_Exception);
                }
            });
        }