import json

from django.core.exceptions import ValidationError
from ..models import RSVP, Activity, ActivitySelection, Event

def create_or_switch_activity_response(rsvp: RSVP, activity: Activity):
    """
    This function will:
    1. Check if there already is a ActivitySelection for this pair
        - then remove it (unselecting)
    2. Always make sure that the new selection will fit the number of guests
        - Adding guests will be blocked when a selection is active which is full
    3. Check if the new selection is illegal (choose one in same group)
        - then remove the old one
        - add the new selection (switch choice)
    """
    
    # Step 1: Remove existing selection for this activity pair (unselecting)
    existing_selection = ActivitySelection.objects.filter(rsvp=rsvp, activity=activity).first()
    if existing_selection:
        existing_selection.delete()
        return
    
    # Step 2: Check if adding guests will fit in the selected activity
    remaining_capacity = activity.remaining_capacity()
    if(remaining_capacity is None):
        # Hardcoded, because why not
        remaining_capacity = 100
    
    if rsvp.guest_count > remaining_capacity:
        return
    
    # Step 3: Check if new selection is illegal (choosing one in same group)
    # Get the activity's group if it exists
    activity_group = activity.group
    
    if activity_group and activity_group.single_choice:
        # Get all other activities in the same group that are already selected
        other_selections = ActivitySelection.objects.filter(
            rsvp=rsvp,
            activity__group=activity_group
        ).exclude(activity=activity)
        
        if other_selections.exists():
            # Remove the old selection (switch choice)
            for other_selection in other_selections:
                other_selection.delete()
    
    # Create and save the new selection
    selection = ActivitySelection(rsvp=rsvp, activity=activity)
    selection.save()
    
    return selection

def create_context(rsvp:RSVP, error:str="") -> dict:
    context = {
        "rsvp": rsvp,
        "event": rsvp.event
    }
    
    if(error != ""):
        context["page_error"] = error
    
    return context

def add_to_context(context:dict, key:str, value) -> dict:
    context[key] = value
    
    return context

def get_rsvp(context:dict) -> RSVP:
    rsvp = get_from_context(context, "rsvp")

    if not rsvp:
        raise KeyError
    
    return rsvp

def get_event(context:dict) -> Event:
    event = get_from_context(context, "event")

    if not event:
        raise KeyError
    
    return event

def get_from_context(context:dict, key:str):
    if key in context:
        return context[key]
    
    return False