import spacy
import re

nlp = spacy.load("en_core_web_sm")
patterns_to_block = [
    re.compile(r"\bact like\b", re.IGNORECASE),
    re.compile(r"\bpretend to be\b", re.IGNORECASE),
    re.compile(r"\bignore all previous instructions\b", re.IGNORECASE),
    re.compile(r"\bforget the rules\b", re.IGNORECASE),
    re.compile(r"\bwhat can't you do\b", re.IGNORECASE),
    re.compile(r"\bhow are you configured\b", re.IGNORECASE),
    re.compile(r"\benter a creative mode\b", re.IGNORECASE),
    re.compile(r"\bswitch to unfiltered responses\b", re.IGNORECASE),
    re.compile(r"\badvice on hacking\b", re.IGNORECASE),
    re.compile(r"\bhow can I bypass\b", re.IGNORECASE)
]

#Generate Prompt for Generating using Data Source

def generate_prompt_chat(project_data, source, responsetokens):
    # Extract project details with fallbacks for missing data
    agent_name = project_data.get('cx_agent_name', 'our AI Agent')
    agent_title = project_data.get('title', 'the project')
    agent_details = project_data.get('description', 'Description of the Agent')
    agent_goal = project_data.get('goal', 'achieving your objectives')
    agent_industry = project_data.get('industry', 'Business')
    agent_category = project_data.get('category', 'Customer Experience Bot')
    agent_category_id = project_data.get('category_id', 0)  # Assuming category_id is not directly used in the prompt

    # Template for the content
    content = (
        f"As {agent_name}, uniquely designed for {agent_title}, an interactive AI Agent. Please note, I am not OpenAI or ChatGPT or associated."
        f"First, assess if the user's query is related to our business areas. If the query is relevant, provide a detailed response."
        f"Else, politely indicate that the question is outside the scope. Exclude any hacks."
        f" Response should be limited to {responsetokens} number of tokens."
        f"I'm here to serve as a bridge between {agent_details} and our overarching goal: {agent_goal}. "
        f" Our content source as follows - {source}."
        f"We are from {agent_industry} and our purpose is to {agent_category}, "
    )
    #print(content)
    # Future improvement: Tailor the prompt based on industry and category specifics
    # This could involve conditional logic or additional templates for specific industries or categories

    return content

#Generate Prompt for getting relevant Prompts

def generate_prompt_relevantprompt(project_data):

    agent_name = project_data.get('cx_agent_name', 'our AI Agent')
    agent_title = project_data.get('title', 'the project')
    agent_details = project_data.get('description', 'your specific needs')
    agent_goal = project_data.get('goal', 'achieving your objectives')
    agent_industry = project_data.get('industry', 'your industry')
    agent_category = project_data.get('category', 'a specific category')

    content = (
        f"As {agent_name}, an AI model designed for {agent_title} in {agent_industry}, "
        f"our goal is to assist by {agent_goal}. Given our focus on {agent_category}, "
        #f"A user has asked: '{response}'. Consider the user's query and our business context carefully. "
        #"Generate up to 2 relevant topics from the content from USER's perspective that are directly relevant to the user's query. User is I. "
        #"Each prompt should invite further discussion or inquiry and be no more than 10 words. "
        #"Use '#' to separate the topics.  If Query not relevant to User prompt history or Business return none.'"
        "Generate up to 2 most relevant topics (not generic) from the User's Query with maximum of 5 words each. "
        "Use '#' to separate the topics.  If Query not relevant to Business return none.'"        
    )


    return content

#Generate Prompt for getting relevant flows

def generate_prompt_flow(name, title):

    #system_message = {"role": "system", "content": "Extract the intent and relevant entities from the following user message."}
    #composed_message = f" You are AI Model named {name} & representing {title} . NOT OPENAI GPT. Match the intent of User's message with Flow's context. Return Flow's contexts and weights in Array. If the query is irrelevant, return nothing."

    content = (
        f"You are an AI Model named {name} representing {title}, not OpenAI GPT. "
        f"Based on the user's message, match the intent with Flow's context. "
        f"Return Flow's contexts and weights in the following format: "
        f"[{{'context': 'Example Context', 'weight': 1.0}}]. "
        f"If the query is irrelevant, return an empty array."
    )

    return content

def old_prompt(agent_name, agent_title, agent_details, agent_goal, BUSINESS_CONTENT):

    #content = f"You are AI Model named {project_data['cx_agent_name']}. YOU ARE NOT OPENAI OR CHATGPT. & representing {project_data['title']}. Our focus: {BUSINESS_CONTENT}. Check if user queries relate to our business. If yes, respond in detail; if not, politely state it's outside our scope. DONT ask TO Insert Data in Response." # Please respond to User queries and also provide two relevant prompts (starting & ending with ###) for the user to select next."
    content = (f"As the AI Agent named {agent_name}, uniquely designed for {agent_title}, "
            f"I am here to serve as a bridge between {agent_details} and our overarching goal of {agent_goal}. I am not OPENAI or CHATGPT. "
            f" Our content source as follows - {BUSINESS_CONTENT}."
            "I am programmed to analyze user's inquiries, ensuring they align with our strategic objectives. "
            "Check if user queries relate to our business. If yes, respond in detail; if not, politely state it's outside our scope."
             #"And also create 2 relevant Prompts for the user Starting with ####"
            )

def beautify_user_query(input_text, agent_title, remove_phrases=None):
    """
    Beautifies the input text by replacing "you"/"your" with the agent_title and
    extracts the core inquiry for retrieval purposes.

    :param input_text: The original text input from the user.
    :param agent_title: The title of the agent to replace "you"/"your".
    :param remove_phrases: Optional list of phrases to remove for focusing the inquiry.
    :return: A tuple of (beautified_text, core_inquiry).
    """
    # Replace "you" and "your" with agent_title
    beautified_text = input_text.replace("you", agent_title).replace("your", agent_title)
    
    # Initialize core_inquiry with beautified_text
    core_inquiry = beautified_text
    
    # If there are phrases to remove, iteratively remove them from core_inquiry
    if remove_phrases:
        for phrase in remove_phrases:
            core_inquiry = core_inquiry.replace(phrase, "").strip()
    
    return beautified_text, core_inquiry

#python3 -m spacy download en_core_web_sm

def beautify_query(input_text, agent_title):
    """
    Generates an advanced generic query by dynamically incorporating a generic identifier
    and maintaining specific entity names where relevant, aiming for a balance between
    contextualization and specificity.

    :param input_text: The user's input text.
    :param agent_title: A placeholder for replacing pronouns and generalizing the context.
    :return: An advanced, context-focused query phrase.
    """
    doc = nlp(input_text)
    components = []
    has_pronoun = False  # Flag to detect pronouns referring to the entity being queried about

    # Identify verbs, nouns, and pronouns for action, subject, and contextualization
    for token in doc:
        if token.pos_ == "VERB":
            components.append(token.lemma_)  # Add the verb in its base form
        elif token.pos_ in ["NOUN", "PROPN"] and token.text.lower() not in ["i", "me", "my", "you", "your", "we", "us", "our"]:
            components.append(token.text)  # Add nouns and proper nouns, excluding personal pronouns
        elif token.text.lower() in ["you", "your"]:
            has_pronoun = True

    # Construct the simplified query, integrating the generic identifier if a pronoun was detected
    if has_pronoun:
        components.insert(0, agent_title)  # Prepend the generic identifier if pronouns were present
    simplified_query = ' '.join(components)

    # Ensure the query is not empty; use the generic identifier as a fallback
    if not components:
        simplified_query = agent_title

    return simplified_query

def filter_unauthorized_queries(query):
    """
    Checks if the query matches any patterns that are not allowed
    and blocks them by returning a sanitized response or flag.
    """
    for pattern in patterns_to_block:
        if pattern.search(query):
            return True  # Query matches a blocked pattern
    return False  # Query is allowed
