import os
from dotenv import dotenv_values
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import ToolNode
from langchain_core.tools import tool

import stripe
import json
# Load values directly from .env file without setting environment variables
env_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), '.env')
env_vars = dotenv_values(env_path)


stripe.api_key = env_vars.get("STRIPE_API_KEY")
#product_name is the name of the product in the payments/products.json file
def generate_payment_link(product_quantities_str: str) -> str:
    """Generate a Stripe payment link for specified products.
    
    Args:
        product_quantities_str: String with format "(product_1,k_1),(product_2,k_2),...,(product_n,k_n)" where product_i must match a key in products.json and k_i is the quantity. Example: "(finasteride,1),(NP_consultation,1)"
    """
    # Parse the input string
    product_quantities = []
    pairs = product_quantities_str.strip().split("),(")
    
    for pair in pairs:
        # Clean up the pair string
        pair = pair.replace("(", "").replace(")", "")
        if not pair:
            continue
            
        parts = pair.split(",")
        if len(parts) != 2:
            raise ValueError(f"Invalid format in pair: {pair}. Expected 'product,quantity'")
            
        product_id, quantity_str = parts
        try:
            quantity = int(quantity_str)
        except ValueError:
            raise ValueError(f"Quantity must be an integer: {quantity_str}")
            
        product_quantities.append((product_id, quantity))
    
    # Load the product catalog - adjust path based on script location
    import os
    script_dir = os.path.dirname(os.path.abspath(__file__))
    catalog_path = os.path.join(script_dir, "products.json")
    catalog = json.load(open(catalog_path))
    
    # Create line items for the payment link
    # Use a dictionary to track and combine items with the same price_id
    price_quantities = {}
    for product_id, quantity in product_quantities:
        if product_id not in catalog:
            raise ValueError(f"Product '{product_id}' not found in catalog")
        
        price_id = catalog[product_id]["price_id"]
        if price_id in price_quantities:
            price_quantities[price_id] += quantity
        else:
            price_quantities[price_id] = quantity
    
    # Create line items from the consolidated price_quantities
    line_items = [
        {"price": price_id, "quantity": quantity}
        for price_id, quantity in price_quantities.items()
    ]
    
    # Create the payment link
    payment_link = stripe.PaymentLink.create(
        line_items=line_items,
        phone_number_collection={"enabled": True},
        after_completion={
            "type": "hosted_confirmation",
            "hosted_confirmation": {
                "custom_message": "Thank you for your order! 🎉.\n A nurse practitioner will review your order and contact you shortly."
            }
        }
    )
    
    return payment_link.url


def process_purchase_request(user_input):
    """
    Process a purchase request from a user input string.
    
    Args:
        user_input (str): A string containing purchase intent like 
                         "I want to buy 3 items of product_i and 2 of product_k"
    
    Returns:
        dict: The response from the tool node containing payment information
    """
    # Use the API key directly from the loaded .env values
    llm = ChatOpenAI(model='gpt-4o-mini', api_key=env_vars.get("OPENAI_API_KEY"), temperature=0)

    # Tool creation
    tools = [generate_payment_link]
    tool_node = ToolNode(tools)

    # Tool binding
    model_with_tools = llm.bind_tools(tools)
    # Get the LLM to understand the request and format it for tool calling
    llm_response = model_with_tools.invoke(user_input)
    print(llm_response)
    # Pass the LLM's response to the tool node for execution
    tool_response = tool_node.invoke({"messages": [llm_response]})
    print(tool_response)
    return tool_response

# Example usage
if __name__ == "__main__":
    sample_request = '1 Finasteride consultation, 1 Minoxidil consultation'
    result = process_purchase_request(sample_request)
    print(result)
    
    # You can test with other examples
    # result2 = process_purchase_request("I want to buy 3 items of product_i and 2 of product_k")
    # print(result2)