from rest_framework import viewsets

from apps.authentication.mixins.region_filter import RegionFilterMixin, get_organization_by_user
from apps.authentication.services.service import get_all_org_child, get_all_org_type_child
from apps.authentication.services.visibility_services import apply_visibility_filter
from apps.authorization.services.role_child import get_all_role_child
from apps.core.models import MobileTest, SystemConfig
from apps.core.serializers import MobileTestSerializer, SystemConfigSerializer
from apps.core.services.visibility_service import apply_visibility_filter_by_org_type


class BaseViewSet(RegionFilterMixin, viewsets.ModelViewSet):
    """
    All view sets in the project should inherit from this class.
    It applies region-based filtering automatically to GET (list) requests.
    """

    def get_queryset(self, show_my_org: bool = None, visibility_by_org_scope: bool = None):
        queryset = super().get_queryset()
        request = self.request
        user = request.user
        org = get_organization_by_user(user)
        user_relation = user.user_relation.filter(organization=org)

        if self.request.method.lower() == 'get' and not self.kwargs.get('pk'):
            queryset = self.filter_by_region(queryset, org=True)

        if visibility_by_org_scope:
            """ if organization has free visibility by scope, apply visibility filter """
            queryset = apply_visibility_filter(queryset, org)
            return queryset

        if visibility_by_org_scope:
            """ if organization has free visibility by org type, apply visibility filter """
            queryset = apply_visibility_filter_by_org_type(queryset, org)
            return queryset

        if user_relation.exists():
            user_relation = user_relation.first()
            if not user_relation.role.type.key == 'ADM':
                # get all child orgs
                child_orgs = get_all_org_child(org)

                # if show_my_org is True, add current org to queryset
                if show_my_org:
                    child_orgs.append(org)

                model_name = queryset.model.__name__.lower()

                if model_name == 'userrelations':  # noqa
                    # add all users with my organization except my user
                    child_orgs.append(org)
                    child_roles = get_all_role_child(user_relation.role)
                    queryset = (queryset.filter(organization__in=child_orgs, role__in=child_roles).exclude(user=user))

                elif model_name == 'organization':
                    queryset = queryset.filter(id__in=[org.id for org in child_orgs])

                elif model_name == 'organizationtype':  # noqa

                    queryset = queryset.filter(id__in=[org_type.id for org_type in get_all_org_type_child(org.type)])

                elif model_name == 'role':
                    queryset = queryset.filter(id__in=[role.id for role in get_all_role_child(user_relation.role)])
        return queryset


class MobileTestViewSet(viewsets.ModelViewSet):
    queryset = MobileTest.objects.all()
    serializer_class = MobileTestSerializer


class SystemConfigViewSet(viewsets.ModelViewSet):
    queryset = SystemConfig.objects.all()
    serializer_class = SystemConfigSerializer
