from tenant.models import TenantRoom
from utils.services import current_date
from django.db.models import Q
from .models import Room

def get_room_occupancy(room_id, date = current_date()):
    """
    Args:
        room_id (int): The ID of the room.
        date (datetime.date): The date to check occupancy for.

    Returns:
        int: The number of tenants currently occupying the room.
    """
    return TenantRoom.objects.filter(room_id=room_id, joined_on__lte=date, left_on__isnull=True).count() # type: ignore


def is_bed_available(room_id, date):
    room = Room.objects.get(id=room_id) # type: ignore
    occupied_beds = get_room_occupancy(room_id, date)
    return occupied_beds < room.capacity


def get_active_tenants(room_id, target_date=None):
    """
    Returns a list of tenants who were active in the given room on the specified date.

    :param room_id: The ID of the room.
    :param target_date: The date to check for active tenants (default is today).
    :return: QuerySet of active tenants.
    """
    if target_date is None:
        target_date = current_date()

    # Get all tenants who were in the room on target_date
    active_tenants = TenantRoom.objects.filter( # type: ignore
        room_id=room_id,
        joined_on__lte=target_date,  # Joined on or before target_date
    ).exclude(
        left_on__lt=target_date  # Exclude those who left before target_date
    ).select_related('tenant')

    return [entry.tenant for entry in active_tenants]

def get_tenant_room_on_date(tenant_id, date):
    """
        date should be timezone aware
    """

    tenant_room = TenantRoom.objects.filter( # type: ignore
        tenant_id=tenant_id,
        joined_on__lte=date,  # Tenant joined on or before this date
    ).filter(
        Q(left_on__gte=date) | Q(left_on__isnull=True)  # Still in the room or left after the date
    ).order_by('-joined_on').first()  # Get the latest record if multiple exist

    return tenant_room.room if tenant_room else None

def get_room_tenants(room_id):
    """
    Returns a list of tenants currently occupying the room.

    :param room_id: The ID of the room.
    :return: QuerySet of tenants currently occupying the room.
    """
    tenant_rooms = TenantRoom.objects.filter(room_id=room_id).select_related('tenant') # type: ignore
    return tenant_rooms
