from src import db 
from src.models import Chat, Message, Agente
from flask_login import current_user
from sqlalchemy import func, case
from datetime import datetime, timedelta, date

class StatsService:  
    @staticmethod
    def get_dashboard_stats(period_days: int = 7):
        try:
            start_date = datetime.now() - timedelta(days=period_days)

            total_conversations = db.session.query(func.count(Chat.id))\
                .filter(Chat.user_id == current_user.id, Chat.created_at >= start_date)\
                .scalar() or 0

            total_messages = db.session.query(func.count(Message.id))\
                .join(Chat, Message.chat_id == Chat.id)\
                .filter(Chat.user_id == current_user.id, Message.created_at >= start_date)\
                .scalar() or 0

            avg_response_time_val = 0.0
            if hasattr(Message, 'response_time') and hasattr(Message, 'is_user'): 
                avg_response_time_query = db.session.query(func.avg(Message.response_time))\
                    .join(Chat, Message.chat_id == Chat.id)\
                    .filter(
                        Chat.user_id == current_user.id,
                        Message.created_at >= start_date,
                        Message.is_user == False, 
                        Message.response_time.isnot(None)
                    )\
                    .scalar()
                avg_response_time_val = round(avg_response_time_query, 2) if avg_response_time_query else 0.0

            total_tokens = db.session.query(func.sum(Message.tokens))\
                .join(Chat, Message.chat_id == Chat.id)\
                .filter(
                    Chat.user_id == current_user.id,
                    Message.created_at >= start_date,
                    Message.is_user == False, 
                    Message.tokens.isnot(None)  
                )\
                .scalar() or 0
            model_usage_dict = {}
            if hasattr(Agente, 'nome'): 
                messages_subquery = db.session.query(
                    Message.chat_id,
                    func.count(Message.id).label('message_count_for_chat'),
                    func.avg(case((Message.is_user == False, Message.response_time), else_=None)).label('avg_response_time_for_chat'),
                    func.sum(case((Message.is_user == False, Message.tokens), else_=0)).label('total_tokens_for_chat')
                ).filter(Message.created_at >= start_date).group_by(Message.chat_id).subquery()

                model_usage_query = db.session.query(
                    Agente.nome.label('model_name'), 
                    func.count(Chat.id).label('conversations'),
                    func.sum(messages_subquery.c.message_count_for_chat).label('messages'),
                    func.avg(messages_subquery.c.avg_response_time_for_chat).label('avg_time'),
                    func.sum(messages_subquery.c.total_tokens_for_chat).label('total_tokens')
                ).join(Agente, Chat.agent_id == Agente.id)\
                 .outerjoin(messages_subquery, Chat.id == messages_subquery.c.chat_id)\
                 .filter(Chat.user_id == current_user.id, Chat.created_at >= start_date)\
                 .group_by(Agente.nome)\
                 .all()

                for row in model_usage_query:
                    model_name_key = row.model_name or "Desconhecido"
                    model_usage_dict[model_name_key] = {
                        "conversations": row.conversations or 0,
                        "messages": int(row.messages or 0),
                        "tokens": int(row.total_tokens or 0),
                        "avg_time": round(row.avg_time, 2) if row.avg_time else 0.0
                    }
            activity_data = {} 
            date_func_chat = func.date(Chat.created_at) 
            date_func_msg = func.date(Message.created_at)

            daily_conversations = db.session.query(
                date_func_chat.label('day'),
                func.count(Chat.id).label('num_conversations')
            ).filter(
                Chat.user_id == current_user.id,
                Chat.created_at >= start_date
            ).group_by('day').order_by('day').all()

            for row in daily_conversations:
                day_str = row.day.isoformat() if isinstance(row.day, (datetime, date)) else str(row.day)
                if day_str not in activity_data: activity_data[day_str] = {'conversations': 0, 'messages': 0}
                activity_data[day_str]['conversations'] = row.num_conversations

            daily_messages = db.session.query(
                date_func_msg.label('day'),
                func.count(Message.id).label('num_messages')
            ).join(Chat, Message.chat_id == Chat.id)\
             .filter(
                Chat.user_id == current_user.id,
                Message.created_at >= start_date
            ).group_by('day').order_by('day').all()

            for row in daily_messages:
                day_str = row.day.isoformat() if isinstance(row.day, (datetime, date)) else str(row.day)
                if day_str not in activity_data: activity_data[day_str] = {'conversations': 0, 'messages': 0}
                activity_data[day_str]['messages'] = row.num_messages

            stats_result = {
                "total_conversations": total_conversations,
                "total_messages": total_messages,
                "avg_response_time": avg_response_time_val,
                "total_tokens": total_tokens, 
                "model_usage": model_usage_dict,
                "activity_data": activity_data,
                "period_days": period_days
            }
            return stats_result, None

        except Exception as e:
            print(f"Erro ao calcular estatísticas: {str(e)}")
            return None, str(e)