using Revise      # remove when this package is completed
using YiemAgent, GeneralUtils, JSON3, MQTTClient, Dates, UUIDs, DataStructures
using Base.Threads

# ---------------------------------------------- 100 --------------------------------------------- #

config = copy(JSON.parsefile("config.json"))

instanceInternalTopic = config[:serviceInternalTopic][:mqtttopic] * "/1" 

client, connection = MakeConnection(config[:mqttServerInfo][:broker], 
                                    config[:mqttServerInfo][:port])

receiveUserMsgChannel = Channel{Dict}(4)
receiveInternalMsgChannel = Channel{Dict}(4)

msgMeta = GeneralUtils.generate_msgMeta(
  "N/A", 
  replyTopic = config[:servicetopic][:mqtttopic]  # ask frontend reply to this instance_chat_topic
  )  

agentConfig = Dict(
  :mqttServerInfo=> config[:mqttServerInfo],
  :receivemsg=>  Dict(
    :prompt=> config[:servicetopic][:mqtttopic], # topic to receive prompt i.e. frontend send msg to this topic
    :internal=> instanceInternalTopic,
  ),
  :externalservice=> config[:externalservice],
)

# Instantiate an agent
tools=Dict( # update input format
    "askbox"=> Dict(
      :description => "<askbox tool description>Useful for when you need to ask the user for more context. Do not ask the user their own question.</askbox tool description>",
      :input => """<input>Input is a text in JSON format.</input><input example>{\"Q1\": \"How are you doing?\", \"Q2\": \"How may I help you?\"}</input example>""",
      :output => "" ,
      :func => nothing,
    ),
    # "winestock"=> Dict(
    #   :description => "<winestock tool description>A handy tool for searching wine in your inventory that match the user preferences.</winestock tool description>",
    #   :input => """<input>Input is a JSON-formatted string that contains a detailed and precise search query.</input><input example>{\"wine type\": \"rose\", \"price\": \"max 35\", \"sweetness level\": \"sweet\", \"intensity level\": \"light bodied\", \"Tannin level\": \"low\", \"Acidity level\": \"low\"}</input example>""",
    #   :output => """<output>Output are wines that match the search query in JSON format.""",
    #   :func => ChatAgent.winestock,
    # ),
    "finalanswer"=> Dict(
      :description => "<tool description>Useful for when you are ready to recommend wines to the user.</tool description>",
      :input => """<input format>{\"finalanswer\": \"some text\"}.</input format><input example>{\"finalanswer\": \"I recommend Zena Crown Vista\"}</input example>""",
      :output => "" ,
      :func => nothing,
    ),
  )

  a = YiemAgent.sommelier(
    receiveUserMsgChannel,
    receiveInternalMsgChannel,
    agentConfig, 
    name= "assistant",
    id= "testingSessionID",  # agent instance id
    tools=tools,
  )







input =
OrderedDict{String, Any}(:question => "Hello, I would like a get a bottle of wine", :thought_1 => "It's great that the user is looking for a bottle of wine. To give them a personalized recommendation, I need to know more about their preferences.", :action_1 => Dict{String, Any}(:name => "chatbox", :input => "What occasion are you planning to use this wine for?"), :observation_1 => "We are holding a wedding party", :thought_2 => "A wedding party is a great occasion for a special bottle of wine. I need to know what type of food will be served, and how much the user is willing to spend.", :action_2 => Dict{String, Any}(:name => "chatbox", :input => "What type of food will you be serving at the wedding?"), :observation_2 => "It will be Thai dishes.", :thought_3 => "The type of wine that pairs well with Thai dishes is usually a crisp and refreshing white wine, but I also need to consider the budget and personal preferences.", :action_3 => Dict{String, Any}(:name => "chatbox", :input => "How much are you willing to spend on this bottle of wine?"), :observation_3 => "I would spend up to 50 bucks.", :thought_4 => "I have a good idea of the occasion, food, and budget. Now I need to know what type of wine the user is looking for.", :action_4 => Dict{String, Any}(:name => "chatbox", :input => "What type of wine are you usually looking for? Red, White, Sparkling, Rose, Dessert or Fortified?"), :observation_4 => "I like full-bodied Red wine with low tannin.", :thought_5 => "Now that I have all the necessary information, I can start searching for a suitable wine in our inventory.", :action_5 => Dict{String, Any}(:name => "winestock", :input => "red wine with low tannins"), :observation_5 => "I found the following wines in our stock: \n{\n  1: El Enemigo Cabernet Franc 2019\n2: Tantara Chardonnay 2017\n\n}\n", :thought_6 => "Now that I have the information about the wine, it's time to make a recommendation.", :action_6 => Dict{String, Any}(:name => "recommendbox", :input => "El Enemigo Cabernet Franc 2019"), :observation_6 => "I don't like the one you recommend. I want dry wine.")


result = YiemAgent.jsoncorrection(a, input)















