"""
Service for Event business logic and statistics.
"""
from typing import Dict, List, Any
from django.db.models import Count, Q
from ..models import Event, Occurrence


class EventStatistics:
    """Statistics for an event and its descendants."""
    
    def __init__(
        self,
        direct_occurrences_count: int,
        direct_taxa_count: int,
        child_occurrences_count: int,
        child_taxa_count: int,
        children_count: int,
    ):
        self.direct_occurrences_count = direct_occurrences_count
        self.direct_taxa_count = direct_taxa_count
        self.child_occurrences_count = child_occurrences_count
        self.child_taxa_count = child_taxa_count
        self.children_count = children_count


class EventService:
    """Service for Event-related business logic."""
    
    @staticmethod
    def get_occurrences_for_event(event: Event, include_descendants: bool = False):
        """
        Get occurrences for an event, optionally including descendants.
        
        Uses materialized path for efficient descendant queries.
        """
        if include_descendants:
            descendant_events = event.get_descendants()
            return Occurrence.objects.filter(
                Q(event=event) | Q(event__in=descendant_events)
            )
        return event.occurrences.all()
    
    @staticmethod
    def get_taxa_for_occurrences(occurrences):
        """
        Get distinct taxa from occurrences with occurrence counts.
        
        Returns QuerySet of distinct taxa with occurrence_count annotation.
        """
        return occurrences.values('taxon_name', 'taxon_id', 'common_name').annotate(
            occurrence_count=Count('id')
        ).order_by('taxon_name')
    
    @staticmethod
    def get_statistics(event: Event) -> EventStatistics:
        """
        Get statistics for an event and its descendants.
        
        Uses a single aggregate query to compute all counts efficiently,
        avoiding multiple QuerySet evaluations per cursorrules.
        """
        # Get direct occurrences stats in one query
        direct_occurrences = event.occurrences.all()
        direct_stats = direct_occurrences.aggregate(
            occurrences_count=Count('id'),
            taxa_count=Count('taxon_name', distinct=True)
        )
        
        # Get children count
        children_count = event.children.count()
        
        # Get descendant occurrences stats in one query
        # Use materialized path for efficient descendant queries
        descendant_events = event.get_descendants()
        descendant_occurrences = Occurrence.objects.filter(event__in=descendant_events)
        descendant_stats = descendant_occurrences.aggregate(
            occurrences_count=Count('id'),
            taxa_count=Count('taxon_name', distinct=True)
        )
        
        return EventStatistics(
            direct_occurrences_count=direct_stats['occurrences_count'],
            direct_taxa_count=direct_stats['taxa_count'],
            child_occurrences_count=descendant_stats['occurrences_count'],
            child_taxa_count=descendant_stats['taxa_count'],
            children_count=children_count,
        )
    

