private async Task CallLuisPhoneNodeAsync(List <string> basket, IDialogContext context)
        {
            StringBuilder sb = new StringBuilder();  // Only works for debug
            IntentDecoder theDecoder;
            TopFeatures   topFeatures;
            Activity      reply = ((Activity)context.Activity).CreateReply("You can also at any stage ask for all phones and work through the different options on your own, just type \"Start Again\"");

            handSets.InitializeBag(basket);
            theDecoder  = new IntentDecoder(handSets, null, null, basket);
            topFeatures = new TopFeatures(theDecoder);
            if (debugMessages)
            {
                await context.PostAsync($"DEBUG : bag is beginning with {handSets.BagCount()}");
            }
            if (debugMessages)
            {
                await context.PostAsync("DEBUG : String Representation = " + handSets.BuildStrRep());
            }
            if (GetModelCount() == basket.Count)
            {
                await Miscellany.InsertDelayAsync(context);

                await context.PostAsync($"We have over {basket.Count} different models of phone to choose from.");

                await Miscellany.InsertDelayAsync(context);

                await context.PostAsync("As you are unsure what is your best model then let me know what is important to you and I'll select a few for you to choose from");

                await Miscellany.InsertDelayAsync(context);

                await context.PostAsync(" If you like a particular brand just say which ones.");

                await Miscellany.InsertDelayAsync(context);

                await context.PostAsync("Or you can choose features (like weight, battery life, camera...) or just tell me how you mostly use your phone (e.g. I like to play games on my iPhone, I regularly read books on my phone)");
            }
            else
            {
                await Miscellany.InsertDelayAsync(context);

                await context.PostAsync($"We have {basket.Count} phones which match your requirement.If you tell me what is important to you or how you use your phone then I can help you to pick the right one.");
            }
            reply.SuggestedActions = topFeatures.GetTop4Buttons(sb);
            if (debugMessages)
            {
                await context.PostAsync("DEBUG : Results " + sb.ToString());
            }
            await Miscellany.InsertDelayAsync(context);

            await context.PostAsync(reply);

            context.Call(new NodeLUISPhoneDialog(topFeatures, handSets, null, null, basket), LuisResponseHandlerAsync);
            LuisCalled = true;
        }
        private async Task LuisResponseHandlerAsync(IDialogContext context, IAwaitable <object> awaitable)
        {
            List <string> modelsInBag;
            int           handSetsLeft          = 4;
            IntentDecoder decoder               = null;
            bool          showGreatChoiceBanner = true;

            LuisCalled = true;
            try
            {
                decoder      = (IntentDecoder)(await awaitable);
                handSets     = (HandSets)decoder.PhonesLeft;
                handSetsLeft = handSets.BagCount();
            }
            catch (Exception xception)
            {
                if (debugMessages)
                {
                    await context.PostAsync("DEBUG : xception message " + xception.Message);
                }
            }
            modelsInBag = handSets.GetBagModels();
            if (debugMessages)
            {
                if (debugMessages)
                {
                    await context.PostAsync($"DEBUG : bag has {modelsInBag.Count}");
                }
            }
            if (decoder.FeatureOrNeedDesc == "Start Again")
            {
                // context.Call(new BrandModelNode(), FinalSelectionReceivedAsync);
                await AskPickOrRecommendOption(context);
            }
            else
            {
                if (decoder.FeatureOrNeedDesc == "Show Me All")
                {
                    decoder.FeatureOrNeedDesc = null;
                    /* In this case, there is no need to write "Great Choice! ... */
                    showGreatChoiceBanner = false;
                    context.ConversationData.SetValue <List <string> >(BotConstants.SELECTED_BRANDS_KEY, new List <string>()
                    {
                        BotConstants.SHOW_ME_ALL
                    });
                }
                context.Call(new LessThan5Node(modelsInBag, showGreatChoiceBanner, decoder.LastOneWasNeed, decoder.FeatureOrNeedDesc), FinalSelectionReceivedAsync);
            }
        }
        public NodeLUISPhoneDialog(TopFeatures mostDemanded, HandSets handSets, string brand, DateTime?currentModelReleaseDate, List <string> narrowedListOfModels) : base()
        {
            smallDesc = new Dictionary <EIntents, string>()
            {
                { EIntents.BatteryLife, "Battery life" },
                { EIntents.Small, "Physical Size" }
            };
            acknowledgeMessages = new Dictionary <EIntents, string[]>()
            {
                { EIntents.BandWidth, new String[] { "I've picked out the phones that have access to internet and wide bandwidth" } },
                { EIntents.BatteryLife, new String[] { "I've picked out the phones that have a big battery life", "I've picked out all the phones that have a battery life longer than {0} hours" } },
                { EIntents.Brand, new String[] { "I understand that for you the brand is important so I've picked out all the phones from {0}" } },
                { EIntents.Camera, new String[] { "I've excluded all the phones with camera resolution less than 12 MegaPixels.", "I've picked out all the phones with cameras of at least {0} MegaPixels" } },
                { EIntents.DualCamera, new String[] { "I've picked out the phones with a Dual Camera." } },
                { EIntents.DualSIM, new String[] { "I've picked out the phones with DualSIM." } },
                { EIntents.ExpandableMemory, new String[] { "I've picked out the phones with expandable memory." } },
                { EIntents.FMRadio, new String[] { "I've picked out the phones with FM Radio Antenna." } },
                { EIntents.FaceID, new String[] { "I've picked out the phones with Face ID recognition." } },
                { EIntents.GPS, new String[] { "I've picked out the phones with GPS." } },
                { EIntents.HDVoice, new String[] { "I've picked out the phones with High Definition voice." } },
                { EIntents.HighResDisplay, new String[] { "I've picked out the phones with High resolution display.", "I've picked out all the phones with display resolution higher than {0} pixels" } },
                { EIntents.LargeStorage, new String[] { "I've picked out the phones with the largest storage capability.", "I've picked out all the phones that have a storage capacity higher than {0} MB" } },
                { EIntents.OS, new String[] { "I understand that operating System is important for you and you would like to have a phone with {0}" } },
                { EIntents.ScreenSize, new String[] { "I've picked out the phones with the largest screen size.", "I've picked out all the phones that have a screen size larger than {0} inches" } },
                { EIntents.SecondaryCamera, new String[] { "I've picked out the phones with a secondary camera." } },
                { EIntents.Small, new String[] { "I've picked out the phones with the smallest dimensions.", "I've picked out the biggest phones", "I've picked out all the phones smaller than {0}", "I've picked out all the phones bigger than {0}", "Picked all the phones roughly the same size of yours" } },
                { EIntents.SmartPhone, new String[] { "I understand that you want a smartphone, not a feature phone." } },
                { EIntents.WaterResist, new String[] { "I've picked out the phones that are water resistant." } },
                { EIntents.Weight, new String[] { "I've picked out the lightest phones.", "I've picked out all the phones weighting less than {0}." } },
                { EIntents.WiFi, new String[] { "I've picked out the phones with WiFi." } },
                { EIntents.Color, new String[] { "I understand that for you the color is important so I picked the phones with your preferred colors : {0}" } },
                { EIntents.Newest, new String[] { "I've picked out the most recent models.", "I've picked out all the models that have a release date more recent than {0}" } },
                { EIntents.FeaturePhone, new String[] { "I understand that you want a simple, classic, feature phone" } }
            };

            handSetsBag             = handSets;
            brandDesired            = brand;
            ReleaseDateCurrentModel = currentModelReleaseDate;
            decoder     = mostDemanded.AssociatedDecoder;
            topButtons  = mostDemanded;
            needsScores = new ScoreFuncs(handSets);
        }
        private async Task RecommendPhoneAsync(IDialogContext context, string brand, DateTime?lowerThreshold = null)
        {
            int           count;
            TopFeatures   topFeatures;
            IntentDecoder theDecoder = new IntentDecoder(handSets, brand, lowerThreshold, null);

            StringBuilder sb = new StringBuilder("");   // For debugging purposes

            try
            {
                topFeatures = new TopFeatures(theDecoder);
                handSets.InitializeBag(brand, lowerThreshold);
                count = handSets.BagCount();
                if (count > BotConstants.MAX_CAROUSEL_CARDS)
                {
                    if (debugMessages)
                    {
                        if (debugMessages)
                        {
                            await context.PostAsync($"DEBUG : bag is beginning with {handSets.BagCount()}");
                        }
                    }
                    if (debugMessages)
                    {
                        await context.PostAsync("DEBUG : String Representation = " + handSets.BuildStrRep());
                    }
                    Activity message = (Activity)context.Activity;
                    Activity reply   = message.CreateReply(isUnsure ? "If you like a particular brand just say which one and I can display all the models available from that supplier in a carousel below" :
                                                           "Remember that you can always ask for all phones and work through the different options on your own,just enter \"Start Again\"");
                    reply.SuggestedActions = topFeatures.GetTop4Buttons(sb);
                    if (debugMessages)
                    {
                        await context.PostAsync("DEBUG : " + sb.ToString());
                    }
                    await Miscellany.InsertDelayAsync(context);

                    await context.PostAsync($"We have over { count} different models of phone to choose from. ");

                    if (isUnsure)
                    {
                        await Miscellany.InsertDelayAsync(context);

                        await context.PostAsync("As you are unsure what is your best model then let me know what is important to you and I'll select a few for you to choose from. If you like a particular brand just say which ones.");
                    }
                    await Miscellany.InsertDelayAsync(context);

                    await context.PostAsync("Or you can choose features (like weight, battery life, camera...) ");

                    await Miscellany.InsertDelayAsync(context);

                    await context.PostAsync("I can also recommend some models if you tell me how you mostly use your phone (e.g. I like to play games on my iPhone, I regularly read books on my phone)");

                    await Miscellany.InsertDelayAsync(context);

                    await context.PostAsync(reply);

                    context.Call(new NodeLUISPhoneDialog(topFeatures, handSets, brand, lowerThreshold, null), LuisResponseHandlerAsync);
                }
                else
                {
                    context.Call(new LessThan5Node(handSets.GetBagModels(), true), FinalSelectionReceivedAsync);
                }
            }
            catch (Exception xception)
            {
                if (debugMessages)
                {
                    await context.PostAsync("DEBUG : Message from the exception : " + xception.Message + "\r\nDEBUG : string builder : " + sb.ToString());
                }
            }
        }