using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace ProxyTunnel.Models
{
    /// <summary>
    /// When returned by a BotProxy using the GenericBot scripts,
    /// the inContact platform can continue the GenericBot script loop (prompt/collect response),
    /// or break out of the BotLoop, returning control to the inContact script (with optional automatic command payloads)
    /// 
    /// </summary>
    public class BotExchangeResponse
    {
        #region Branch Definitions
        /// <summary>
        /// Branching options for GenericBots
        /// </summary>
        public enum BotExchangeBranch
        {
            DoNotBegin,
            PromptAndCollectNextResponse,
            ReturnControlToScript,
            EndContact,
            AudioInputUntranscribeable,
            //TransferContact, idea for later, with its own custom command params
            //RequestAgent, idea for later, with its own custom command params
            Error,
            DTMFBreakout,
            UserInputTimeout,
            UserInputNotUnderstood
        }

        /// <summary>
        /// Branching options for GenericBot.  Possible values:
        ///   •DoNotBegin - Applicable to an initialize operation, do not run the bot
        ///   •PromptAndCollectNextResponse - Continue the GenericBot loop by prompting user and collecting next response
        ///   •ReturnControlToScript - Break out of the bot loop and return control to inContact script
        ///   •EndContact - End the Contact, depending on media type (hangup phone call, etc)
        ///   •AudioInputUntranscribeable - Audio utterance provided no transcription (noisy environment, caugh, etc).  MediaServer may choose to continue utterance detection and resubmit for the same 'turn'
        ///   •Error - Something went wrong.  See ErrorDetails variable
        /// </summary>
        [JsonConverter(typeof(StringEnumConverter))]
        public BotExchangeBranch branchName { get; set; }
        #endregion

        /// <summary>
        /// Sequence of prompts to be rendered to customer on next round of the BotLoop
        /// </summary>
        public PromptSequence nextPromptSequence { get; set; }

        /// <summary>
        /// Information from the bot on current user intent
        /// </summary>
        public IntentInfo intentInfo { get; set; }

        /// <summary>
        /// Instructions for the next round of prompting the user
        /// </summary>
        public PromptBehaviors nextPromptBehaviors { get; set; }

        /// <summary>
        /// Supply any named data to the platform as 'script variables'.
        /// These variables can be used in custom scripting, or referenced in subsequent prompts using {syntax}.
        /// 
        /// Recommend against nested JSON structures, as custom SNIPPET scripting is required to dereference nested
        /// values.  Scripting is more convenient is customVariables is a flat, single level JSON object
        /// </summary>
        public Dictionary<string, object> customPayload { get; set; }


        /// <summary>
        /// Diagnostic information for errors, and error handling behavior configuration
        /// </summary>
        public BotErrorDetails errorDetails { get; set; }

        /// <summary>
        /// A state object that will be returned in the next 'botExchange' of the GenericBot loop.
        /// This should contain at least enough information to form a unique session identifier, and allow a bot to resume from where it left off in the last exchange.
        /// This can be used to persist the entire bot state in a session, allowing for 'stateless' server side implementations.
        /// Including the entire transcript in this object is also possible, though size implications should be considered.
        /// </summary>
        public object botSessionState { get; set; }

        public BotExchangeResponse()
        {
            nextPromptSequence = new PromptSequence();
            customPayload = new Dictionary<string, object>();

            nextPromptBehaviors = new PromptBehaviors();

            nextPromptBehaviors.audioCollectionRules.collectionType = AudioCollectionRules.UserInputCollectType.SEND_DTMF_ONLY_AS_TEXT;
            nextPromptBehaviors.audioCollectionRules.dtmfRules = CollectDtmfRules.SurveyResponseSettings();

            intentInfo = new IntentInfo();
        }

        #region Standard response templates

        public static BotExchangeResponse GetRecordSurveyResponseTemplate()
        {
            BotExchangeResponse botResponse = new BotExchangeResponse();

            botResponse.branchName = BotExchangeResponse.BotExchangeBranch.PromptAndCollectNextResponse;
            PromptDefinition thePrompt = new PromptDefinition();
            thePrompt.transcript = "After the beep, describe your experience.  When finished, please hit the pound key.";
            botResponse.nextPromptSequence.prompts.Add(thePrompt);


            botResponse.nextPromptBehaviors.silenceRules.millisecondsToWaitForUserResponse = 15000;

            botResponse.nextPromptBehaviors.audioCollectionRules = new AudioCollectionRules();
            botResponse.nextPromptBehaviors.audioCollectionRules.collectionType = AudioCollectionRules.UserInputCollectType.SEND_UTTERANCE_AUDIO;

            //TODO satmetrix support
            //botResponse.nextPromptBehaviors.audioCollectionRules.utteranceCollectAndArchiveRuleSet = new UtteranceCollectAndArchiveRules();
            //botResponse.nextPromptBehaviors.audioCollectionRules.utteranceCollectAndArchiveRuleSet.storageServicesUtteranceArchivePath = "/openendedresposnes/{contactId}/msdmdfmfkdk.wav";


            botResponse.nextPromptBehaviors.audioCollectionRules.dtmfRules = new CollectDtmfRules();
            botResponse.nextPromptBehaviors.audioCollectionRules.dtmfRules.clearDigits = false;
            botResponse.nextPromptBehaviors.audioCollectionRules.dtmfRules.detectDtmf = false;
            botResponse.nextPromptBehaviors.audioCollectionRules.dtmfRules.terminationCharacters = "@";// any
            botResponse.nextPromptBehaviors.audioCollectionRules.dtmfRules.maxDigits = 1;

            botResponse.nextPromptBehaviors.audioCollectionRules.bargeConfiguration = new PromptBargeConfiguration();
            botResponse.nextPromptBehaviors.audioCollectionRules.bargeConfiguration.enableSpeakerBarge = true;

            Dictionary<string, object> botSessionExample = new Dictionary<string, object>();
            botSessionExample["ExampleSurveySessionId"] = "sdlfjkh3453sdfkjhsh356ruducjedj";
            botResponse.botSessionState = botSessionExample;



            botResponse.errorDetails = new BotErrorDetails();
            botResponse.errorDetails.errorPromptSequence = new PromptSequence();

            PromptDefinition errorPrompt = new PromptDefinition();
            errorPrompt.transcript = "We are sorry, but its your unlucky day!";
            errorPrompt.audioFilePath = "/errormessages/unluckday.wav";

            botResponse.errorDetails.errorPromptSequence.prompts.Add(errorPrompt);

            return botResponse;
        }

        #endregion
    }
}
