import instructor
import openai
import os
import json
from dotenv import load_dotenv
from src.core.sentiment_analyzer import ReviewSentimentAnalyzer  
from src.core.batch_sentiment_analyzer import BatchReviewSentimentAnalyzer
from sqlalchemy.orm import Session
from datetime import datetime
from src.utils.models import Store, Topic
from time import sleep
from typing import List, Dict

# Load environment variables
load_dotenv()

API_KEY = os.getenv("AZURE_OPENAI_API_KEY")
ENDPOINT = os.getenv("AZURE_OPENAI_ENDPOINT")
DEPLOYMENT = os.getenv("AZURE_OPENAI_DEPLOYMENT")
API_VERSION = os.getenv("AZURE_OPENAI_API_VERSION")

# Initialize Azure OpenAI Client
llm = openai.AzureOpenAI(
    api_key=API_KEY,
    api_version=API_VERSION,
    azure_endpoint=ENDPOINT,
    azure_deployment=DEPLOYMENT
)

# OpenAI client setup using Instructor
client = instructor.from_openai(llm)

# Initialize Sentiment Analyzers
sentiment_analyzer = ReviewSentimentAnalyzer(client=client)
batch_sentiment_analyzer = BatchReviewSentimentAnalyzer(client=client)

# Full static topic list used in prompt
STATIC_TOPICS = [
    "Service Experience", "Cleanliness & Hygiene", "Ambiance & Atmosphere", "Pricing & Value",
    "Online Ordering & Delivery", "Complaint Resolution", "Customer Loyalty", "Menu Preferences",
    "Waiting Time", "Portion Size", "Staff Friendliness", "Payment Experience", 
    "Special Requests Handling", "Reservation Experience", "Parking & Accessibility",
    "Food Presentation", "Seasonal Trends", "Offer & Promotions", "Food Quality", "Serving"
]

def categorize_topic(detected_topic, predefined_topics):
    """
    Matches detected topic to the closest predefined static topic, else returns 'Others'.
    """
    for topic in predefined_topics:
        if topic.lower() in detected_topic.lower() or detected_topic.lower() in topic.lower():
            return topic
    return "Others"

def analyze_sentiment(text: str, store_id=None):
    """
    Analyzes text sentiment using static topic mapping. Ignores DB store_id.
    """
    try:
        result = sentiment_analyzer.analyze_review(text)

        raw_topics = result.relevant_topics_sentiment if isinstance(result.relevant_topics_sentiment, dict) else {}
        categorized_topics = {}

        for topic, sentiment in raw_topics.items():
            mapped_topic = categorize_topic(topic, STATIC_TOPICS)
            categorized_topics[mapped_topic] = sentiment

        # Process emotion/arousal
        emotion_data = result.relevant_emotions_with_arousal
        emotions = [list(d.keys())[0] for d in emotion_data] if emotion_data else []
        arousal = [list(d.values())[0] for d in emotion_data] if emotion_data else []
        dominant_arousal = arousal[0] if arousal and arousal[0] in ["active", "passive"] else "neutral"

        return {
            "sentiment": result.overall_sentiment,
            "confidence_score": 1.0,
            "emotion": emotions,
            "arousal": dominant_arousal,
            "relevant_topics_sentiment": categorized_topics,
            "important_words_sentiment": result.important_words_sentiment if isinstance(result.important_words_sentiment, dict) else {}
        }

    except Exception as e:
        print(f"[Sentiment Analysis Error] {str(e)}")
        return {
            "sentiment": "unknown",
            "confidence_score": 0.0,
            "emotion": [],
            "arousal": "neutral",
            "relevant_topics_sentiment": {},
            "important_words_sentiment": {}
        }

def analyze_batch_sentiment(reviews: List[str], store_id=None):
    """
    Analyzes batch review sentiment. Ignores DB store_id.
    """
    try:
        results = batch_sentiment_analyzer.analyze_reviews(reviews)
        sentiments = []

        for result in results.sentiments:
            raw_topics = result.relevant_topics_sentiment if isinstance(result.relevant_topics_sentiment, dict) else {}
            categorized_topics = {}

            for topic, sentiment in raw_topics.items():
                mapped_topic = categorize_topic(topic, STATIC_TOPICS)
                categorized_topics[mapped_topic] = sentiment

            emotion_data = result.relevant_emotions_with_arousal
            emotions = [list(d.keys())[0] for d in emotion_data] if emotion_data else []
            arousal = [list(d.values())[0] for d in emotion_data] if emotion_data else []
            dominant_arousal = arousal[0] if arousal and arousal[0] in ["active", "passive"] else "neutral"

            obj = {
                "sentiment": result.overall_sentiment,
                "confidence_score": 1.0,
                "emotion": emotions,
                "arousal": dominant_arousal,
                "relevant_topics_sentiment": categorized_topics,
                "important_words_sentiment": result.important_words_sentiment if isinstance(result.important_words_sentiment, dict) else {}
            }

            sentiments.append(obj)

        return sentiments


    except Exception as e:
        print(f"[Sentiment Analysis Error] {str(e)}")
        return []
