// Traverses the graph of goals to find the next list of goals
        private List <Goal> TraverseGoalGraph(string nextGoalID, Dictionary <string, object> entityValues, List <Response> responses)
        {
            List <Goal> goalList = new List <Goal>();

            Goal currentGoal;

            bool canTraverse = true;

            while (canTraverse)
            {
                currentGoal = Goals.Find(x => x.ID == nextGoalID);

                if (!currentGoal.IsActive(entityValues) || currentGoal.IsAchieved(Goals, entityValues, responses))
                {
                    nextGoalID = currentGoal.ParentID;
                    continue;
                }

                if (currentGoal.GetType() == typeof(CompositeGoal))
                {
                    if (((CompositeGoal)currentGoal).DoSkip(Goals, entityValues, responses))
                    {
                        foreach (string subgoalID in ((CompositeGoal)currentGoal).SubgoalIDs)
                        {
                            Goal subgoal = Goals.Find(x => x.ID == subgoalID);

                            if (subgoal.IsActive(entityValues) && !subgoal.IsAchieved(Goals, entityValues, responses))
                            {
                                nextGoalID = subgoalID;
                                break;
                            }
                        }
                    }
                    else
                    {
                        goalList.Add(currentGoal);
                        canTraverse = false;
                    }
                }
                else if (currentGoal.GetType() == typeof(AtomicInformativeGoal))
                {
                    goalList.Add(currentGoal);
                    canTraverse = ((AtomicInformativeGoal)currentGoal).DoContinue; // If DoConitnue == True, then will continue traversing graph. Otherwise it will stop.
                }
                else
                {
                    goalList.Add(currentGoal);
                    canTraverse = false;
                }
            }

            return(goalList);
        }
        public async Task <UserResponse> ParseUserText(string userText, List <Response> responses)
        {
            string responseString = await AppServiceClient.client.GetStringAsync($"https://westus.api.cognitive.microsoft.com/luis/prediction/v3.0/apps/0006203c-aabd-4bd2-8665-e463ed9314c1/slots/staging/predict?subscription-key=be53086b4a72494c90eeb673aeb10860&verbose=true&show-all-intents=true&log=true&query={userText}");

            dynamic json = JsonConvert.DeserializeObject(responseString);

            string        responseType = "";
            List <string> intentIDs    = new List <string>();
            Dictionary <string, object> entityValues = new Dictionary <string, object>();

            if (json.prediction.topIntent == "Greeting")
            {
                intentIDs.Add("Greet");
            }
            else if (json.prediction.topIntent == "None")
            {
                intentIDs.Add("Fallback");
            }
            else if (json.prediction.topIntent == "Unsure")
            {
                AgentResponse recentAgentResponse = (AgentResponse)responses.FindLast(x => x.GetType() == typeof(AgentResponse));
                intentIDs.Add($"Unsure{recentAgentResponse.GoalIDs.Last()}");
            }
            else if (json.prediction.topIntent == "No")
            {
                AgentResponse recentAgentResponse = (AgentResponse)responses.FindLast(x => x.GetType() == typeof(AgentResponse));
                Goal          goal = Goals.FindLast(x => recentAgentResponse.GoalIDs.Contains(x.ID) && x.GetType() == typeof(AtomicRetrievalGoal));

                if (goal == null)
                {
                    intentIDs.Add($"Unsure{recentAgentResponse.GoalIDs.Last()}");
                }
                else
                {
                    foreach (string goalID in recentAgentResponse.GoalIDs)
                    {
                        if (Goals.Find(x => x.ID == goalID).GetType() == typeof(AtomicRetrievalGoal))
                        {
                            intentIDs.Add($"Validate{goalID}");
                        }
                    }
                }
            }

            // Fix up this method lmao

            return(new UserResponse());
        }