from sqlalchemy.orm import Session
from datetime import datetime
from src.utils.db import SessionLocal
import time
from src.utils.models import Feedback, Task
from celery.signals import task_postrun, task_prerun
from src.core.sentiment_analysis import analyze_sentiment
from src.apps.sentiment.models import Word, ReviewTopic, Emotion
from sqlalchemy.orm import Session
from datetime import datetime
from src.utils.models import Feedback, ReviewTopic, Topic, Word
from src.core.sentiment_analysis import analyze_sentiment
from dateutil import parser
from datetime import datetime

def is_ambiguous(date_str):
    separators = ['/', '-']
    for sep in separators:
        parts = date_str.split(sep)
        if len(parts) == 3 and all(p.isdigit() for p in parts):
            day, month = int(parts[0]), int(parts[1])
            # If both day and month <= 12, it's ambiguous
            return day <= 12 and month <= 12
    return False

def convert_to_iso_safe(date_str, assume_dayfirst=True):
    try:
        if is_ambiguous(date_str):
            print(f"⚠️ Ambiguous date detected: {date_str}")
            if assume_dayfirst:
                print("Assuming format is **dd/mm/yyyy**")
            else:
                print("Assuming format is **mm/dd/yyyy**")
        parsed_date = parser.parse(date_str, dayfirst=assume_dayfirst)
        return parsed_date.strftime('%Y-%m-%d')
    except Exception as e:
        print(f"[Date Parse Error]: {e}")  # optional logging
        return None


def get_topic_info(db: Session, topic_name: str) -> tuple:
    topic = db.query(Topic).filter(Topic.topic_name.ilike(topic_name)).first()
    if topic:
        return topic.topic_id, topic.topic_name

    others_topic = db.query(Topic).filter(Topic.topic_name == "Others").first()
    if others_topic:
        return others_topic.topic_id, others_topic.topic_name
    else:
        new_topic = Topic(topic_name="Others", created_at=datetime.utcnow())
        db.add(new_topic)
        db.commit()
        db.refresh(new_topic)
        return new_topic.topic_id, new_topic.topic_name

def insert_feedback_entries(db: Session, payload: dict):
    try:
        store_id = payload["store_id"]
        branch_id = payload["branch_id"]
        datasource_id = payload["datasource_id"]
        datasource_source = payload["datasource_source"]
        reviews = payload["reviews"]

        feedback_entries = []

        for review in reviews:
            sentiment_result = review["sentiment_result"]
            rel_emotions = sentiment_result.get("emotion", [])

            feedback = Feedback(
                store_id=store_id,
                branch_id=branch_id,
                datasource_id=datasource_id,
                feedback_source=datasource_source,
                feedback_rating=review["rating"],
                feedback_type="text",
                original_content=review["comment"],
                transcription=None,
                sentiment=sentiment_result["sentiment"],
                confidence_score=sentiment_result["confidence_score"],
                emotion=str(rel_emotions),
                arousal=sentiment_result["arousal"],
                customer_name=review["name"],
                feedback_posting_date=convert_to_iso_safe(review["date"], assume_dayfirst=True),
                created_at=datetime.utcnow(),
            )

            db.add(feedback)
            db.flush()
            feedback_entries.append(feedback)

        return feedback_entries

    except Exception as e:
        db.rollback()
        print(f"[Service] Error inserting feedback: {str(e)}")
        raise

def insert_related_data(db: Session, feedback_entries, payload: dict):
    try:
        store_id = payload["store_id"]
        branch_id = payload["branch_id"]
        datasource_id = payload["datasource_id"]
        reviews = payload["reviews"]

        words_entries = []
        topics_entries = []
        emotions_entries = []

        for feedback_entry, review in zip(feedback_entries, reviews):
            feedback_id = feedback_entry.feedback_id
            if feedback_id is None:
                continue

            sentiment_result = review["sentiment_result"]
            rel_words = sentiment_result.get("important_words_sentiment", {})
            rel_topics = sentiment_result.get("relevant_topics_sentiment", {})
            rel_emotions = sentiment_result.get("emotion", [])

            words_entries.extend([
                Word(
                    store_id=store_id,
                    branch_id=branch_id,
                    datasource_id=datasource_id,
                    feedback_id=feedback_id,
                    words=word,
                    sentiment=sentiment_result["sentiment"],
                    created_at=datetime.utcnow()
                ) for word in rel_words
            ])

            for topic in rel_topics:
                topic_id, topic_name = get_topic_info(db, topic)
                topics_entries.append(ReviewTopic(
                    datasource_id=datasource_id,
                    store_id=store_id,
                    branch_id=branch_id,
                    feedback_id=feedback_id,
                    topic_id=topic_id,
                    topic_name=topic_name,
                    topic_sentiment=sentiment_result["sentiment"],
                    created_at=datetime.utcnow()
                ))

            emotions_entries.extend([
                Emotion(
                    store_id=store_id,
                    branch_id=branch_id,
                    datasource_id=datasource_id,
                    feedback_id=feedback_id,
                    emotions=emotion,
                    created_at=datetime.utcnow()
                ) for emotion in rel_emotions
            ])

        if words_entries:
            db.bulk_save_objects(words_entries)
        if topics_entries:
            db.bulk_save_objects(topics_entries)
        if emotions_entries:
            db.bulk_save_objects(emotions_entries)

        db.commit()

    except Exception as e:
        db.rollback()
        print(f"[Service] Error inserting related data: {str(e)}")
        raise

def store_reviews(db: Session, payload: dict):
    try:
        feedback_entries = insert_feedback_entries(db, payload)
        insert_related_data(db, feedback_entries, payload)
    except Exception as e:
        print(f"[Service] Error storing reviews: {str(e)}")
        raise
    finally:
        db.close()
