"""
REST API Views for Jingles Application

This module contains Django REST Framework views for managing
jingle detection, ad break analysis, and related operations
through a RESTful API interface.
"""

from rest_framework import viewsets, status, permissions
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.pagination import PageNumberPagination
from django_filters.rest_framework import DjangoFilterBackend
from django.utils import timezone
from django.db.models import Count, Avg, Q
from datetime import timedelta

from apps.jingles.models import JingleTemplate, JingleDetection, AdBreak, DetectionStatistics
from apps.jingles.api.serializers import (
    JingleTemplateSerializer, JingleDetectionSerializer, AdBreakSerializer,
    DetectionStatisticsSerializer, DetectionSummarySerializer
)
from apps.streams.tasks import extract_iframes_from_segment


class JingleTemplateViewSet(viewsets.ModelViewSet):
    """
    ViewSet for managing jingle templates via REST API.
    
    Provides CRUD operations for jingle templates along with
    custom actions for template management and statistics.
    """
    
    queryset = JingleTemplate.objects.all().select_related('created_by')
    serializer_class = JingleTemplateSerializer
    permission_classes = [permissions.IsAuthenticated]
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['is_active', 'category', 'created_by']
    search_fields = ['name', 'slug', 'description']
    ordering_fields = ['name', 'created_at', 'similarity_threshold']
    ordering = ['name']

    def perform_create(self, serializer):
        """Set the current user as the template creator."""
        serializer.save(created_by=self.request.user)

    @action(detail=True, methods=['get'])
    def detections(self, request, pk=None):
        """
        Get all detections for a specific template.
        
        Args:
            request: HTTP request with optional filters
            pk: Template primary key
            
        Returns:
            Response: List of detections for the template
        """
        template = self.get_object()
        detections = template.detections.select_related(
            'session__channel', 'segment'
        ).order_by('-detection_time')
        
        # Apply date filter if provided
        date_from = request.query_params.get('date_from')
        date_to = request.query_params.get('date_to')
        
        if date_from:
            detections = detections.filter(detection_time__gte=date_from)
        if date_to:
            detections = detections.filter(detection_time__lte=date_to)
        
        serializer = JingleDetectionSerializer(detections, many=True)
        return Response(serializer.data)

    @action(detail=True, methods=['get'])
    def statistics(self, request, pk=None):
        """
        Get detailed statistics for a specific template.
        
        Args:
            request: HTTP request
            pk: Template primary key
            
        Returns:
            Response: Template statistics data
        """
        template = self.get_object()
        detections = template.detections.all()
        
        # Calculate statistics
        total_detections = detections.count()
        confirmed_detections = detections.filter(is_confirmed=True).count()
        
        if total_detections > 0:
            accuracy_rate = (confirmed_detections / total_detections) * 100
            avg_confidence = detections.aggregate(avg=Avg('confidence_score'))['avg']
            
            # Recent activity (last 7 days)
            recent_detections = detections.filter(
                detection_time__gte=timezone.now() - timedelta(days=7)
            ).count()
        else:
            accuracy_rate = 0
            avg_confidence = 0
            recent_detections = 0
        
        stats = {
            'total_detections': total_detections,
            'confirmed_detections': confirmed_detections,
            'accuracy_rate': round(accuracy_rate, 2),
            'avg_confidence': round(avg_confidence, 3) if avg_confidence else 0,
            'recent_detections': recent_detections
        }
        
        return Response(stats)

    @action(detail=False, methods=['get'])
    def active(self, request):
        """Get all active jingle templates."""
        active_templates = self.queryset.filter(is_active=True)
        serializer = self.get_serializer(active_templates, many=True)
        return Response(serializer.data)


class JingleDetectionViewSet(viewsets.ModelViewSet):
    """
    ViewSet for managing jingle detections via REST API.
    
    Provides access to detection data with filtering and
    confirmation capabilities.
    """
    
    queryset = JingleDetection.objects.all().select_related(
        'template', 'session__channel', 'segment'
    )
    serializer_class = JingleDetectionSerializer
    permission_classes = [permissions.IsAuthenticated]
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['template', 'session', 'is_confirmed']
    ordering_fields = ['detection_time', 'confidence_score']
    ordering = ['-detection_time']

    @action(detail=True, methods=['post'])
    def confirm(self, request, pk=None):
        """
        Confirm a jingle detection as accurate.
        
        Args:
            request: HTTP request
            pk: Detection primary key
            
        Returns:
            Response: Updated detection data
        """
        detection = self.get_object()
        detection.is_confirmed = True
        detection.save()
        
        serializer = self.get_serializer(detection)
        return Response(serializer.data)

    @action(detail=True, methods=['post'])
    def reject(self, request, pk=None):
        """
        Mark a detection as false positive.
        
        Args:
            request: HTTP request
            pk: Detection primary key
            
        Returns:
            Response: Updated detection data
        """
        detection = self.get_object()
        detection.is_confirmed = False
        detection.save()
        
        # Update statistics if they exist
        try:
            stats = DetectionStatistics.objects.get(
                session=detection.session,
                template=detection.template
            )
            stats.false_positives += 1
            stats.save()
        except DetectionStatistics.DoesNotExist:
            pass
        
        serializer = self.get_serializer(detection)
        return Response(serializer.data)

    @action(detail=False, methods=['get'])
    def recent(self, request):
        """Get recent detections across all templates."""
        recent_detections = self.queryset.order_by('-detection_time')[:50]
        serializer = self.get_serializer(recent_detections, many=True)
        return Response(serializer.data)

    @action(detail=False, methods=['get'])
    def summary(self, request):
        """
        Get detection summary statistics.
        
        Args:
            request: HTTP request
            
        Returns:
            Response: Summary statistics data
        """
        # Time ranges
        now = timezone.now()
        today = now.date()
        last_7_days = now - timedelta(days=7)
        
        # Basic counts
        total_detections = self.queryset.count()
        detections_today = self.queryset.filter(detection_time__date=today).count()
        confirmed_detections = self.queryset.filter(is_confirmed=True).count()
        
        # Accuracy rate
        accuracy_rate = 0
        if total_detections > 0:
            accuracy_rate = (confirmed_detections / total_detections) * 100
        
        # Top templates (by detection count in last 7 days)
        top_templates = list(
            JingleTemplate.objects.filter(
                detections__detection_time__gte=last_7_days
            ).annotate(
                detection_count=Count('detections')
            ).order_by('-detection_count')[:5].values(
                'name', 'detection_count'
            )
        )
        
        # Recent activity
        recent_activity = list(
            self.queryset.filter(
                detection_time__gte=last_7_days
            ).select_related(
                'template', 'session__channel'
            ).order_by('-detection_time')[:10].values(
                'template__name', 'session__channel__name',
                'detection_time', 'confidence_score'
            )
        )
        
        summary_data = {
            'total_detections': total_detections,
            'detections_today': detections_today,
            'confirmed_detections': confirmed_detections,
            'accuracy_rate': round(accuracy_rate, 2),
            'top_templates': top_templates,
            'recent_activity': recent_activity
        }
        
        serializer = DetectionSummarySerializer(summary_data)
        return Response(serializer.data)


class AdBreakViewSet(viewsets.ModelViewSet):
    """
    ViewSet for managing ad breaks via REST API.
    
    Provides access to ad break data with external API
    integration capabilities.
    """
    
    queryset = AdBreak.objects.all().select_related(
        'session__channel', 'start_detection__template', 'end_detection__template'
    )
    serializer_class = AdBreakSerializer
    permission_classes = [permissions.IsAuthenticated]
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['status', 'region', 'is_sent_to_api']
    ordering_fields = ['start_time', 'duration_seconds']
    ordering = ['-start_time']

    @action(detail=True, methods=['post'])
    def send_to_api(self, request, pk=None):
        """
        Send ad break data to external API.
        
        Args:
            request: HTTP request
            pk: Ad break primary key
            
        Returns:
            Response: API submission result
        """
        ad_break = self.get_object()
        
        if not ad_break.is_complete():
            return Response(
                {'error': 'Ad break is not complete'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        if ad_break.is_sent_to_api:
            return Response(
                {'error': 'Ad break already sent to API'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        try:
            # Import the task here to avoid circular imports
            from ..tasks import send_ad_break_notification
            
            # Queue the notification task
            task = send_ad_break_notification.delay(str(ad_break.id))
            
            return Response({
                'success': True,
                'message': 'Ad break queued for API submission',
                'task_id': task.id
            }, status=status.HTTP_202_ACCEPTED)
            
        except Exception as e:
            return Response(
                {'error': str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )

    @action(detail=False, methods=['get'])
    def active(self, request):
        """Get all active ad breaks."""
        active_breaks = self.queryset.filter(status='active')
        serializer = self.get_serializer(active_breaks, many=True)
        return Response(serializer.data)

    @action(detail=False, methods=['get'])
    def today(self, request):
        """Get ad breaks from today."""
        today = timezone.now().date()
        today_breaks = self.queryset.filter(start_time__date=today)
        serializer = self.get_serializer(today_breaks, many=True)
        return Response(serializer.data)


class DetectionStatisticsViewSet(viewsets.ReadOnlyModelViewSet):
    """
    ViewSet for detection statistics (read-only).
    
    Provides access to performance metrics and analysis
    data for jingle detection accuracy.
    """
    
    queryset = DetectionStatistics.objects.all().select_related(
        'template', 'session__channel'
    )
    serializer_class = DetectionStatisticsSerializer
    permission_classes = [permissions.IsAuthenticated]
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['template', 'session']
    ordering_fields = ['last_detection', 'total_detections', 'accuracy_rate']
    ordering = ['-last_detection']

    @action(detail=False, methods=['get'])
    def performance(self, request):
        """
        Get overall performance statistics.
        
        Args:
            request: HTTP request
            
        Returns:
            Response: Performance summary data
        """
        stats = self.queryset.all()
        
        if not stats.exists():
            return Response({
                'overall_accuracy': 0,
                'total_detections': 0,
                'active_templates': 0,
                'best_performers': []
            })
        
        # Calculate overall metrics
        total_detections = sum(s.total_detections for s in stats)
        total_confirmed = sum(s.confirmed_detections for s in stats)
        overall_accuracy = (total_confirmed / total_detections * 100) if total_detections > 0 else 0
        
        # Best performing templates
        best_performers = []
        for stat in stats.filter(total_detections__gte=10).order_by('-accuracy_rate')[:5]:
            best_performers.append({
                'template_name': stat.template.name,
                'accuracy_rate': stat.accuracy_rate(),
                'total_detections': stat.total_detections
            })
        
        performance_data = {
            'overall_accuracy': round(overall_accuracy, 2),
            'total_detections': total_detections,
            'active_templates': JingleTemplate.objects.filter(is_active=True).count(),
            'best_performers': best_performers
        }
        
        return Response(performance_data)
