############################################################################
# import the necessary libraries
############################################################################

from Ai_Agents.services.llm_functions.determine_intent import determine_intent
from Ai_Agents.services.llm_functions.generate_objective_response import generate_objective_response
from Ai_Agents.services.llm_functions.get_action_response import get_action_response
from Ai_Agents.services.process_requests.process_request_knowledge_bank import process_request
from Ai_Agents.services.llm_functions.count_tokens import count_tokens

from app.database.fetch_data import get_mongo_client, get_character_by_id, fetch_mannual_triggers, fetch_sections, fetch_triggers, filter_data_by_character_id
from dotenv import load_dotenv # type: ignore

load_dotenv()


# /chat route


############################################################################
# function to process the message
############################################################################

def process_message(client,data,sid):
    character_id = data.get("character_id")
    message = data.get("message")
    section_id = data.get("section_id")

    #client = get_mongo_client()
    sections = fetch_sections(client)
    triggers = fetch_triggers(client)
    
    mannual_triggers = fetch_mannual_triggers(client)
    data = get_character_by_id(character_id)
    name = data.get("name", "Unknown")
    gender = data.get("gender", "Unknown")
    backstory = data.get("backstory", "Unknown")
    print("Sections fetched:", sections)
    mannual_trigger, triggers, sections = filter_data_by_character_id(character_id, mannual_triggers, triggers, sections)
    trigger_message_list = [trigger["message"] for trigger in list(triggers)]
    section_map = {section.get("section_id", None): index for index, section in enumerate(sections) if "section_id" in section}
    trigger_map = {trigger.get("message", None): index for index, trigger in enumerate(triggers)}
    mannual_trigger_map = {trigger.get("mannual_trigger_id", None): index for index, trigger in enumerate(mannual_triggers)}
    print("Sections map:", section_map)
    print("trigger maps:", trigger_map)

    # print("name :", name)
    # print("gender :", gender)
    # print("backstory :", backstory)

    # print("fetching done!!!")

    try:
        if section_id == "$":
            # print("Nongdambgaa - 0")
            # trigger
            intent_result = determine_intent(message, trigger_message_list)
            intent = intent_result.get("decision") if intent_result else None

            print(intent)

            if intent and intent in trigger_message_list:
                trigger_index = trigger_map[intent]
                trigger = triggers[trigger_index]
                print(trigger)
                section_id_new = trigger["destination_id"] 
                section_index = section_map[section_id_new]
                section = sections[section_index]

                response = generate_objective_response(section["objective"], name, gender, backstory)
                token_usage = count_tokens(f"{name} {gender} {backstory} {message} {response}")
                return {"response": response, "section_id": section_id_new, "token_usage": token_usage}
            else:

                # change this with the knowledge bank part
                data = {
                    "character_id": character_id,
                    "message": message,
                    "section_id": section_id,
                }
                response = process_request(client,data,sid)
                return response
            
        elif "Actions" in data and "Distances" in data:

            # print("Nongdambgaa - 1")

            actions = data.get("Actions")
            distances = data.get("Distances")

            db = client['narrative_design_test']
            actions_collection = db['actions']
            objects_collection = db['objects']

            actions_collection.insert_one({"actions": actions})
            objects_collection.insert_one({"distances": distances})
            

            section_index = section_map[section_id]
            section = sections[section_index]

            intent_result = determine_intent(message, section["decisions"])
            intent = intent_result.get("decision") if intent_result else None

            print(intent)

            if intent and intent in section["decisions"]:
                mannual_trigger_id = section["mapping"][intent]
                mannual_trigger_index = mannual_trigger_map[mannual_trigger_id]
                mannual_trigger = mannual_triggers[mannual_trigger_index]

                mannual_trigger_id = mannual_trigger["mannual_trigger_id"]
                action_response = get_action_response(message, actions, distances)

                response = action_response['response']
                action = action_response['action_id']
                destination = action_response['destination']
                joined_actions = " ".join(actions)
                token_usage = count_tokens(f"{joined_actions} {message} {response}")
                return {
                    "response": response, 
                    "action_id": action, 
                    "destination": destination, 
                    "mannual_trigger_id": mannual_trigger_id,
                    "token_usage": token_usage
                }
        else:

            # print("Nongdambgaa - 2")
            # section
            section_index = section_map[section_id]
            section = sections[section_index]


            intent_result = determine_intent(message, section["decisions"])
            intent = intent_result.get("decision") if intent_result else None

            # print(intent)

            if intent and intent in section["decisions"]:
                new_section_id = section["mapping"][intent]
                #print("New Section:", new_section, "Type:", type(new_section))
                new_section_index = section_map[new_section_id]
                new_section = sections[new_section_index]

                response = generate_objective_response(new_section["objective"], name, gender, backstory)
                token_usage = count_tokens(f"{name} {gender} {backstory} {message} {response}")
                return {
                    "response": response, 
                    "section_id": new_section_id,
                    "token_usage": token_usage
                }
            elif section["objective"]:
                response= generate_objective_response(section["objective"], name, gender, backstory)
                token_usage = count_tokens(f"{name} {gender} {backstory} {message} {response}")
                return {
                    "response": response,
                    "section_id": section["section_id"],
                    "token_usage": token_usage
                }
            else:

                data = {
                    "character_id": character_id,
                    "message": message,
                    "section_id": section_id
                }

                response = process_request(client,data,sid)
                return response
    except KeyError as e:
        raise KeyError(f"Missing key: {str(e)} in sections or triggers.")
    except Exception as e:
        raise RuntimeError(f"Error processing message: {str(e)}")


############################################################################
# function to process the request
############################################################################

def process_request_1(client,data,sid):
    character_id = data.get("character_id")
    message = data.get("message")
    section_id = data.get("section_id")

    sections = fetch_sections(client)
    triggers = fetch_triggers(client)
    mannual_triggers = fetch_mannual_triggers(client)
    data = get_character_by_id(character_id)
    name = data.get("name", "Unknown")
    gender = data.get("gender", "Unknown")
    backstory = data.get("backstory", "Unknown")

    trigger_message_list = [trigger["message"] for trigger in triggers]
    section_map = {section.get("section_id", None): index for index, section in enumerate(sections) if "section_id" in section}
    trigger_map = {trigger["message"]: index for index, trigger in enumerate(triggers)}
    mannual_trigger_map = {trigger.get("mannual_trigger_id", None): index for index, trigger in enumerate(mannual_triggers)}


    print("name :", name)
    print("gender :", gender)
    print("backstory :", backstory)

    print("fetching done!!!")

    if "mannual_trigger_id" in data:
        mannual_trigger_id = data.get("mannual_trigger_id")
        mannual_trigger_index = mannual_trigger_map[mannual_trigger_id]
        mannual_trigger = mannual_triggers[mannual_trigger_index]

        new_section_id = mannual_trigger["destination_id"]
        new_section_index = section_map[new_section_id]
        new_section = sections[new_section_index]

        response = generate_objective_response(new_section["objective"], name, gender, backstory)
        token_usage = count_tokens(f"{name} {gender} {backstory} {message} {response}")
        return {
            "response": response, 
            "section_id": new_section_id,
            "token_usage": token_usage
        }        

    else:
        response = process_message(client,data,sid)

    return response


