"""
Availability Service - Resource capacity checking with concurrency management
"""
from django.contrib.contenttypes.models import ContentType
from .models import Event, Participant, Resource


class AvailabilityService:
    """
    Service for checking resource availability with concurrency limits.
    
    CRITICAL Features:
    - Handles max_concurrent_events==0 as unlimited capacity
    - Filters out CANCELED events to prevent ghost bookings
    - Uses correct overlap logic: start < query_end AND end > query_start
    """
    
    @staticmethod
    def check_availability(resource, start_time, end_time, exclude_event_id=None):
        """
        Check if resource has capacity for a new/updated event.
        
        Args:
            resource (Resource): The resource to check
            start_time (datetime): Proposed event start
            end_time (datetime): Proposed event end
            exclude_event_id (int, optional): Event ID to exclude (when updating)
        
        Returns:
            tuple: (is_available: bool, reason: str)
        """
        # Step 1: Calculate search window with buffer
        query_start = start_time - resource.buffer_duration
        query_end = end_time + resource.buffer_duration
        
        # Step 2: Find all events for this resource
        resource_content_type = ContentType.objects.get_for_model(Resource)
        
        resource_participants = Participant.objects.filter(
            content_type=resource_content_type,
            object_id=resource.id,
            role=Participant.Role.RESOURCE
        ).select_related('event')
        
        # Step 3: Filter for overlapping events
        overlapping_events = []
        for participant in resource_participants:
            event = participant.event
            
            # Skip if this is the event being updated
            # CRITICAL: Convert exclude_event_id to int for comparison (frontend may send string)
            if exclude_event_id and event.id == int(exclude_event_id):
                continue
            
            # CRITICAL: Skip cancelled events (prevents ghost bookings)
            if event.status == Event.Status.CANCELED:
                continue
            
            # CRITICAL: Check overlap using correct logic
            # Overlap exists when: event.start < query_end AND event.end > query_start
            if event.start_time < query_end and event.end_time > query_start:
                overlapping_events.append(event)
        
        current_count = len(overlapping_events)
        
        # Step 4: Check capacity limit
        
        # CRITICAL: Handle infinite capacity (0 = unlimited)
        if resource.max_concurrent_events == 0:
            return True, "Unlimited capacity resource"
        
        # Check if we've hit the limit
        if current_count >= resource.max_concurrent_events:
            return False, (
                f"Resource capacity exceeded. "
                f"{current_count}/{resource.max_concurrent_events} slots occupied."
            )
        
        # Available!
        return True, f"Available ({current_count + 1}/{resource.max_concurrent_events} slots)"
