import typing

from django.db.models import Q

from apps.authentication.models import Organization
from apps.authentication.services.service import get_all_org_child
from apps.core.visibility_registry import VISIBILITY_MAP


def get_visible_organizations(org: Organization) -> typing.Any:
    """
    get visible organizations
    """
    if org.free_visibility_by_scope:

        # get data by organization field of activity
        # country
        if org.field_of_activity == 'CO':
            # admin control
            if org.type.key == 'ADM':
                return Organization.objects.all()
            else:
                return Organization.objects.all().exclude(id=org.id).exclude(type__key='ADM')
        # city
        elif org.field_of_activity == 'CI':
            return Organization.objects.filter(city=org.city)
        # province
        elif org.field_of_activity == 'PR':
            return Organization.objects.filter(province=org.province)

    elif not org.free_visibility_by_scope:

        # get data by organization child
        child_orgs = get_all_org_child(org)

        # add my organization in list
        child_orgs.append(org)
        return Organization.objects.filter(id__in=[org.id for org in child_orgs])

    return Organization.objects.filter(id=org.id)


def apply_visibility_filter(queryset, org):
    model_name = queryset.model.__name__.lower()
    org_fields = VISIBILITY_MAP.get(model_name)

    if not org_fields:
        return queryset

    visible_orgs = get_visible_organizations(org)
    org_ids = visible_orgs.values_list('id', flat=True)

    if isinstance(org_fields, str):
        return queryset.filter(**{f"{org_fields}__in": org_ids})

    q_obj = Q()
    for field in org_fields:
        q_obj |= Q(**{f"{field}__in": org_ids})

    return queryset.filter(q_obj)
