"""
API ViewSets for Social Media Comments app
"""
from rest_framework import viewsets, filters, status
from rest_framework.decorators import action
from rest_framework.response import Response
from django_filters.rest_framework import DjangoFilterBackend
from django.db.models import Q, Count, Avg
from datetime import datetime, timedelta

from .models import SocialMediaComment, SocialPlatform
from .serializers import SocialMediaCommentSerializer, SocialMediaCommentListSerializer


class SocialMediaCommentViewSet(viewsets.ModelViewSet):
    """
    ViewSet for SocialMediaComment model
    Provides CRUD operations and filtering for social media comments
    """
    
    queryset = SocialMediaComment.objects.all()
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ['platform', 'published_at']
    search_fields = ['comments', 'author', 'comment_id']
    ordering_fields = ['published_at', 'scraped_at', 'like_count', 'reply_count']
    ordering = ['-published_at']
    
    def get_serializer_class(self):
        """Use different serializers for list and detail views"""
        if self.action == 'list':
            return SocialMediaCommentListSerializer
        return SocialMediaCommentSerializer
    
    def get_queryset(self):
        """Optimize queryset with filters"""
        queryset = super().get_queryset()
        
        # Filter by date range
        start_date = self.request.query_params.get('start_date')
        end_date = self.request.query_params.get('end_date')
        
        if start_date:
            queryset = queryset.filter(published_at__gte=start_date)
        if end_date:
            queryset = queryset.filter(published_at__lte=end_date)
        
        # Filter by minimum sentiment score (from ai_analysis)
        min_sentiment = self.request.query_params.get('min_sentiment')
        if min_sentiment:
            # Need to filter on JSONField sentiment.score
            pass  # JSONField filtering is complex, skip for now
        
        # Filter by minimum likes
        min_likes = self.request.query_params.get('min_likes')
        if min_likes:
            queryset = queryset.filter(like_count__gte=min_likes)
        
        # Filter by analyzed status
        analyzed = self.request.query_params.get('analyzed')
        if analyzed == 'true':
            queryset = queryset.exclude(ai_analysis__isnull=True).exclude(ai_analysis={})
        elif analyzed == 'false':
            queryset = queryset.filter(ai_analysis__isnull=True) | queryset.filter(ai_analysis={})
        
        return queryset
    
    @action(detail=False, methods=['get'])
    def analytics(self, request):
        """
        Get analytics data for social media comments
        Returns sentiment distribution, platform distribution, and trends
        """
        queryset = self.filter_queryset(self.get_queryset())
        
        # Sentiment distribution (from ai_analysis)
        sentiment_data = {'positive': 0, 'negative': 0, 'neutral': 0}
        sentiment_scores = {'positive': [], 'negative': [], 'neutral': []}
        
        for comment in queryset:
            if comment.ai_analysis:
                sentiment = comment.ai_analysis.get('sentiment', {}).get('classification', {}).get('en', 'neutral')
                score = comment.ai_analysis.get('sentiment', {}).get('score', 0)
                if sentiment in sentiment_data:
                    sentiment_data[sentiment] += 1
                if score:
                    sentiment_scores[sentiment].append(score)
        
        sentiment_dist = []
        for sentiment, count in sentiment_data.items():
            scores = sentiment_scores[sentiment]
            avg_score = sum(scores) / len(scores) if scores else 0
            sentiment_dist.append({
                'sentiment': sentiment,
                'count': count,
                'avg_sentiment_score': avg_score
            })
        
        # Platform distribution (from ai_analysis)
        platform_dist = []
        for platform_code, platform_name in SocialPlatform.choices:
            platform_data = queryset.filter(platform=platform_code)
            if platform_data.exists():
                # Calculate avg sentiment from ai_analysis
                sentiment_scores = []
                for comment in platform_data:
                    if comment.ai_analysis:
                        score = comment.ai_analysis.get('sentiment', {}).get('score', 0)
                        if score:
                            sentiment_scores.append(score)
                avg_sentiment = sum(sentiment_scores) / len(sentiment_scores) if sentiment_scores else 0
                
                platform_dist.append({
                    'platform': platform_code,
                    'platform_display': platform_name,
                    'count': platform_data.count(),
                    'avg_sentiment': avg_sentiment,
                    'total_likes': int(platform_data.aggregate(total=Sum('like_count'))['total'] or 0),
                    'total_replies': int(platform_data.aggregate(total=Sum('reply_count'))['total'] or 0),
                })
        
        # Daily trends (last 30 days) - from ai_analysis
        thirty_days_ago = datetime.now() - timedelta(days=30)
        from collections import defaultdict
        
        daily_data = defaultdict(lambda: {'count': 0, 'positive': 0, 'negative': 0, 'neutral': 0})
        
        for comment in queryset.filter(published_at__gte=thirty_days_ago):
            if comment.published_at:
                day = comment.published_at.date()
                daily_data[day]['count'] += 1
                
                if comment.ai_analysis:
                    sentiment = comment.ai_analysis.get('sentiment', {}).get('classification', {}).get('en', 'neutral')
                    if sentiment in ['positive', 'negative', 'neutral']:
                        daily_data[day][sentiment] += 1
        
        daily_trends = [
            {
                'day': day,
                **stats
            }
            for day, stats in sorted(daily_data.items())
        ]
        
        # Top keywords (from ai_analysis)
        all_keywords = []
        for comment in queryset.exclude(ai_analysis__isnull=True).exclude(ai_analysis={}):
            keywords = comment.ai_analysis.get('keywords', {}).get('en', [])
            all_keywords.extend(keywords)
        
        from collections import Counter
        keyword_counts = Counter(all_keywords)
        top_keywords = [{'keyword': k, 'count': v} for k, v in keyword_counts.most_common(20)]
        
        # Top topics (from ai_analysis)
        all_topics = []
        for comment in queryset.exclude(ai_analysis__isnull=True).exclude(ai_analysis={}):
            topics = comment.ai_analysis.get('topics', {}).get('en', [])
            all_topics.extend(topics)
        
        topic_counts = Counter(all_topics)
        top_topics = [{'topic': k, 'count': v} for k, v in topic_counts.most_common(10)]
        
        return Response({
            'sentiment_distribution': list(sentiment_dist),
            'platform_distribution': list(platform_dist),
            'daily_trends': list(daily_trends),
            'top_keywords': top_keywords,
            'top_topics': top_topics,
            'total_comments': queryset.count(),
            'analyzed_comments': sum(1 for c in queryset if c.ai_analysis),
        })
    
    @action(detail=False, methods=['post'])
    def trigger_analysis(self, request):
        """
        Trigger AI analysis for unanalyzed comments
        """
        unanalyzed = SocialMediaComment.objects.filter(ai_analysis__isnull=True) | SocialMediaComment.objects.filter(ai_analysis={})
        count = unanalyzed.count()
        
        if count == 0:
            return Response({
                'message': 'No unanalyzed comments found',
                'count': 0
            })
        
        # Trigger Celery task for analysis
        from .tasks import analyze_comments_batch
        task = analyze_comments_batch.delay([c.id for c in unanalyzed[:100]])  # Batch of 100
        
        return Response({
            'message': f'Analysis triggered for {min(count, 100)} comments',
            'task_id': task.id,
            'count': min(count, 100),
            'remaining': max(0, count - 100)
        })
    
    @action(detail=True, methods=['post'])
    def reanalyze(self, request, pk=None):
        """
        Reanalyze a specific comment
        """
        comment = self.get_object()
        
        # Trigger Celery task for reanalysis
        from .tasks import analyze_comments_batch
        task = analyze_comments_batch.delay([comment.id])
        
        return Response({
            'message': f'Reanalysis triggered for comment {comment.id}',
            'task_id': task.id
        })


# Import Sum for analytics
from django.db.models import Sum
