# llm/openai_client.py
import os
import json
from dotenv import load_dotenv
from openai import AzureOpenAI

# Load env variables once here
load_dotenv()

AZURE_OPENAI_ENDPOINT = os.getenv("AZURE_OPENAI_ENDPOINT")
AZURE_OPENAI_KEY = os.getenv("AZURE_OPENAI_KEY")
AZURE_OPENAI_DEPLOYMENT = os.getenv("AZURE_OPENAI_DEPLOYMENT")
AZURE_OPENAI_API_VERSION = os.getenv("AZURE_OPENAI_API_VERSION")

# Initialize client once
openai_client = AzureOpenAI(
    azure_endpoint=AZURE_OPENAI_ENDPOINT,
    api_key=AZURE_OPENAI_KEY,
    api_version=AZURE_OPENAI_API_VERSION,
)

def generate_summary(data):
    system_prompt = """Analyze the JSON order activity log below and create a structured summary. Focus on:  
1. **Final Outcome**: Clearly state if the order was *Cancelled* or *Returned* or anything else (with reasons from the data and outcome and last recorded activity).  
2. **Order Timeline Overview** (creation timestamp, final status, key users/teams involved)  
3. **Critical Events**: Chronological breakdown of:  
   - Fraud checks (declines, locks, emails)  
   - Payment actions (authorization, voids)  
   - Cancellation/return triggers (e.g., "Order Cancelled" descriptions)  
   - Post-resolution access (e.g., coaching/reviews).  
4. **Key Notes** (patterns, automation flags, unusual access patterns, or notable reasons)    
5. **Key Evidence**: Specific JSON entries proving the outcome (e.g., "Cancelled due to DECLINED: Fraud").  

**Structure Requirements**:  
- Use markdown headers and bullet points.  
- Differentiate between system automation (e.g., "DOT COM") and human actions.  
- Group repeated events (e.g., multiple "Coaching" logs).  
- Highlight the *exact reason* for cancellation/return from the "text" or "description" fields.  

**Rules**:  
- If "Cancelled" appears in any "description" or "text" field, declare it as the outcome.  
- If "Returned" is not explicitly mentioned, assume cancellation.  
- Never guess – use only the provided JSON for conclusions.


"""

    try:
        response = openai_client.chat.completions.create(
            model=AZURE_OPENAI_DEPLOYMENT,
            messages=[
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": json.dumps(data, indent=2)}
            ],
            temperature=0,
        )
        return response.choices[0].message.content
    except Exception as e:
        return f"Error generating summary: {str(e)}"

this is an example of the code make below code as same as above


# llm/gemini_client.py
import os
import time
import json
from helpers import estimate_tokens

try:
    from google import genai
except ImportError:
    genai = None


class GeminiClient:
    def __init__(self):
        self.project = os.getenv("GOOGLE_CLOUD_PROJECT", "")
        self.location = os.getenv("GOOGLE_CLOUD_LOCATION", "us-central1")
        if not self.project:
            raise ValueError("Set GOOGLE_CLOUD_PROJECT environment variable")
        if genai is None:
            raise ImportError("Please install google-generativeai package")

        self.client = genai.Client(
            vertexai=True,
            project=self.project,
            location=self.location,
        )
        self.last_request_tokens = 0
        self.last_response_tokens = 0
        self.last_response_time = 0.0
        self.model_name = "gemini-2.0-flash-001"

    def generate(self, system_prompt: str, user_content: str) -> str:
        full_message = system_prompt + "\n\n" + user_content

        self.last_request_tokens = estimate_tokens(full_message)

        start_time = time.time()
        response = self.client.models.generate_content(
            model=self.model_name,
            contents=full_message,
        )
        end_time = time.time()
        self.last_response_time = end_time - start_time

        text = response.candidates[0].content.parts[0].text
        self.last_response_tokens = estimate_tokens(text)

        return text