"""
Chat managers for session and message management.
"""

from typing import Optional

from django.contrib.auth import get_user_model
from django.db import models
from django.db.models import Avg, Count, Q, Sum

User = get_user_model()


class ChatSessionManager(models.Manager):
    """Custom manager for ChatSession model."""

    def for_user(self, user):
        """Explicitly filter by specific user."""
        return self.get_queryset().filter(user=user)

    def all_users(self):
        """Get unfiltered queryset (admin use)."""
        return self.get_queryset()

    def active(self):
        """Get only active chat sessions."""
        return self.get_queryset().filter(is_active=True)

    def inactive(self):
        """Get only inactive chat sessions."""
        return self.get_queryset().filter(is_active=False)

    def recent(self, limit: int = 10):
        """Get recent sessions ordered by update time."""
        return self.get_queryset().order_by('-updated_at')[:limit]

    def by_model(self, model_name: str):
        """Get sessions using specific model."""
        return self.get_queryset().filter(model_name=model_name)

    def with_message_count(self):
        """Get sessions with message count annotation."""
        return self.get_queryset().annotate(
            message_count=Count('messages')
        )

    def with_stats(self):
        """Get sessions with full statistics."""
        return self.get_queryset().select_related('user').prefetch_related('messages')

    def search_by_title(self, query: str):
        """Search sessions by title."""
        return self.get_queryset().filter(
            title__icontains=query
        ).order_by('-updated_at')

    def get_user_statistics(self, user=None):
        """Get user's chat statistics."""
        queryset = self.for_user(user) if user else self.get_queryset()

        return queryset.aggregate(
            total_sessions=Count('id'),
            active_sessions=Count('id', filter=Q(is_active=True)),
            total_messages=Sum('messages_count'),
            total_tokens=Sum('total_tokens_used'),
            total_cost=Sum('total_cost_usd'),
            avg_messages_per_session=Avg('messages_count'),
            avg_cost_per_session=Avg('total_cost_usd')
        )


class ChatMessageManager(models.Manager):
    """Custom manager for ChatMessage model."""

    def for_user(self, user):
        """Explicitly filter by specific user."""
        return self.get_queryset().filter(user=user)

    def all_users(self):
        """Get unfiltered queryset (admin use)."""
        return self.get_queryset()

    def for_session(self, session_id: str):
        """Get messages for specific session."""
        return self.get_queryset().filter(session_id=session_id).order_by('created_at')

    def user_messages(self):
        """Get only user messages."""
        return self.get_queryset().filter(role='user')

    def assistant_messages(self):
        """Get only assistant messages."""
        return self.get_queryset().filter(role='assistant')

    def system_messages(self):
        """Get only system messages."""
        return self.get_queryset().filter(role='system')

    def by_model(self, model_name: str):
        """Get messages generated by specific model."""
        return self.get_queryset().filter(model_name=model_name)

    def recent(self, limit: int = 50):
        """Get recent messages."""
        return self.get_queryset().order_by('-created_at')[:limit]

    def with_context(self):
        """Get messages that have context chunks."""
        return self.get_queryset().exclude(context_chunks=[])

    def expensive_messages(self, min_cost: float = 0.01):
        """Get messages above certain cost threshold."""
        return self.get_queryset().filter(cost_usd__gte=min_cost)

    def slow_messages(self, min_time_ms: int = 5000):
        """Get messages that took long to process."""
        return self.get_queryset().filter(processing_time_ms__gte=min_time_ms)

    def get_conversation_history(self, session_id: str, limit: Optional[int] = None):
        """Get conversation history for session."""
        queryset = self.for_session(session_id)
        if limit:
            # Get last N messages
            queryset = queryset.order_by('-created_at')[:limit]
            # Reverse to get chronological order
            queryset = reversed(queryset)
        return list(queryset)

    def get_usage_statistics(self, user=None):
        """Get message usage statistics."""
        queryset = self.for_user(user) if user else self.get_queryset()

        return queryset.aggregate(
            total_messages=Count('id'),
            user_messages=Count('id', filter=Q(role='user')),
            assistant_messages=Count('id', filter=Q(role='assistant')),
            total_tokens=Sum('tokens_used'),
            total_cost=Sum('cost_usd'),
            avg_tokens_per_message=Avg('tokens_used'),
            avg_cost_per_message=Avg('cost_usd'),
            avg_processing_time=Avg('processing_time_ms')
        )
