import json
import time
import airtable
import requests
import threading
import functions
import logging

# Setup separate logger for function calls (don't interfere with Flask logs)
function_logger = logging.getLogger('function_calls')
function_logger.setLevel(logging.INFO)

# Create file handler for function calls
if not function_logger.handlers:
    handler = logging.FileHandler('function_calls.log', mode='a')
    formatter = logging.Formatter('%(asctime)s - %(message)s')
    handler.setFormatter(formatter)
    function_logger.addHandler(handler)
    function_logger.propagate = False  # Don't send to root logger

# ManyChat response process, waits for the OpenAI response and calls the ManyChat API to send back the response
def background_process(bob, client, thread_id, assistant_id, user_input,
                       platform, contact_id, request_start_time):
    import functions
    
    start_time = time.time()

    #create message and start run
    message = client.beta.threads.messages.create(thread_id=thread_id,
                                                  role="user",
                                                  content=user_input)
    run = client.beta.threads.runs.create_and_poll(thread_id=thread_id,
                                                   assistant_id=assistant_id)
    run_id = run.id

    if not run_id:
        print("ERROR: Failed to start run for thread_id = ", thread_id)
        return

    while time.time() - start_time < 60:
        run_status = client.beta.threads.runs.retrieve(thread_id=thread_id,
                                                       run_id=run_id)

        if run_status.status == 'completed':
            messages = client.beta.threads.messages.list(thread_id=thread_id)
            message_content = messages.data[0].content[0].text
            #message_usage = messages.data[0].content[0].usage

            #remove annotations
            annotations = message_content.annotations
            for annotation in annotations:
                message_content.value = message_content.value.replace(
                    annotation.text, '')

            agent_reply = message_content.value

            #call the ManyChat API to return the reply
            return_reply(bob, contact_id, agent_reply)

            #calculate elapsed time since OpenAI request started
            request_end_time = time.time()
            request_duration = request_end_time - request_start_time

            tokens = run_status.usage.total_tokens

            #start another background thread to save the reply
            thread = threading.Thread(
                target=airtable.save_reply,
                args=(bob, thread_id, assistant_id, user_input, agent_reply,
                      request_duration, platform, tokens))

            thread.start()
            return

        if run_status.status == 'requires_action':
            function_logger.info(f"Processing function calls for thread {thread_id}")
            function_logger.info(f"Number of tool calls: {len(run_status.required_action.submit_tool_outputs.tool_calls)}")
            print(f"INFO: Processing function calls for thread {thread_id}")
            print(f"INFO: Number of tool calls: {len(run_status.required_action.submit_tool_outputs.tool_calls)}")
            for tool_call in run_status.required_action.submit_tool_outputs.tool_calls:
                function_logger.info(f"Function name: {tool_call.function.name}")
                function_logger.info(f"Function arguments: {tool_call.function.arguments}")
                print(f"INFO: Function name: {tool_call.function.name}")
                print(f"INFO: Function arguments: {tool_call.function.arguments}")
                try:
                    if tool_call.function.name == "create_lead":
                        print(f"INFO: Processing create_lead function call")
                        # Process the 'create_lead' function call by the agent
                        arguments = json.loads(tool_call.function.arguments)

                        thread = threading.Thread(
                            target=airtable.create_lead,
                            args=(bob, thread_id, arguments["nume"],
                                  arguments["telefon"], arguments["adresa"],
                                  platform))
                        thread.start()

                        output = 'LEAD CONTACT INFO SAVED AND EMAILED TO THE BUSINESS'
                        client.beta.threads.runs.submit_tool_outputs(
                            thread_id=thread_id,
                            run_id=run_id,
                            tool_outputs=[{
                                "tool_call_id": tool_call.id,
                                "output": json.dumps(output)
                            }])
                        print(f"INFO: Successfully submitted create_lead output")

                    elif tool_call.function.name == "search_products":
                        function_logger.info(f"Processing search_products function call")
                        print(f"INFO: Processing search_products function call")
                        # Process the 'search_products' function call by the agent
                        arguments = json.loads(tool_call.function.arguments)
                        query = arguments.get('query', 'N/A')
                        function_logger.info(f"Search query: {query}")
                        print(f"INFO: Search query: {query}")

                        output = functions.search_products(arguments["query"])
                        products_found = output.get('total_found', 0)
                        function_logger.info(f"Search found {products_found} products")
                        print(f"INFO: Search found {products_found} products")

                        client.beta.threads.runs.submit_tool_outputs(
                            thread_id=thread_id,
                            run_id=run_id,
                            tool_outputs=[{
                                 "tool_call_id": tool_call.id,
                                 "output": json.dumps(output)
                             }])
                        function_logger.info(f"Successfully submitted search_products output")
                        print(f"INFO: Successfully submitted search_products output")

                    else:
                        print(f"WARNING: Unknown function call: {tool_call.function.name}")

                except Exception as e:
                    print(f"ERROR: Function call failed for {tool_call.function.name}: {str(e)}")
                    # Submit error response to continue the conversation
                    error_output = f"Function call failed: {str(e)}"
                    try:
                        client.beta.threads.runs.submit_tool_outputs(
                            thread_id=thread_id,
                            run_id=run_id,
                            tool_outputs=[{
                                "tool_call_id": tool_call.id,
                                "output": json.dumps(error_output)
                            }])
                        function_logger.info(f"Submitted error response for {tool_call.function.name}")
                        print(f"INFO: Submitted error response for {tool_call.function.name}")
                    except Exception as submit_error:
                        function_logger.error(f"Failed to submit error response: {str(submit_error)}")
                        print(f"ERROR: Failed to submit error response: {str(submit_error)}")
                        return

        time.sleep(1)

    print("ERROR: Run timed out")
    #calculate elapsed time since OpenAI request started
    request_end_time = time.time()
    request_duration = request_end_time - request_start_time

    airtable.save_orphan_reply(bob, thread_id, assistant_id, user_input,
                               request_duration, platform)

    return


#call the ManyChat API to return the reply
def return_reply(bob, contact_id, agent_reply):
    MANYCHAT_API_KEY = bob['ManyChat']['API_KEY']
    MANYCHAT_FIELD_ID = bob['ManyChat']['reply_field_ID']

    url = f'https://api.manychat.com/fb/subscriber/setCustomField'
    headers = {
        'Authorization': 'Bearer ' + MANYCHAT_API_KEY,
        'Content-Type': 'application/json'
    }
    data = {
        "subscriber_id": contact_id,
        "field_id": MANYCHAT_FIELD_ID,
        "field_value": agent_reply
    }
    response = requests.post(url, headers=headers, json=data)

    if response.status_code != 200:
        print(f"ERROR: Failed to send reply to ManyChat: {response.text}")
