from django.contrib.auth.models import Group
from rest_framework.permissions import BasePermission

from apps.usuarios.permissions import is_admin_user


TECNICOS_GROUP_NAME = "Técnicos"
LABORATORISTAS_GROUP_NAME = "Laboratoristas"
PESADOR_GROUP_NAME = "Pesador"
CALIDAD_GROUP_NAME = "Calidad"
EXTERNO_GROUP_NAME = "Externo"


def is_in_group(user, group_name: str) -> bool:
    if not user or not user.is_authenticated:
        return False
    if user.is_superuser:
        return True
    return Group.objects.filter(user=user, name=group_name).exists()


class CanTakeSample(BasePermission):
    def has_permission(self, request, view):
        user = getattr(request, "user", None)
        return bool(
            user
            and user.is_authenticated
            and (
                is_admin_user(user)
                or is_in_group(user, PESADOR_GROUP_NAME)
                or is_in_group(user, TECNICOS_GROUP_NAME)
            )
        )

    def has_object_permission(self, request, view, obj):
        user = getattr(request, "user", None)
        if not user or not user.is_authenticated:
            return False
        if is_admin_user(user):
            return True
        if is_in_group(user, PESADOR_GROUP_NAME):
            return True
        if not is_in_group(user, TECNICOS_GROUP_NAME):
            return False
        tecnico_id = getattr(obj, "tecnico_asignado_id", None)
        return tecnico_id is None or tecnico_id == user.id


class CanLabWork(BasePermission):
    def has_permission(self, request, view):
        user = getattr(request, "user", None)
        return bool(
            user
            and user.is_authenticated
            and (
                is_admin_user(user)
                or is_in_group(user, PESADOR_GROUP_NAME)
                or is_in_group(user, LABORATORISTAS_GROUP_NAME)
                or is_in_group(user, CALIDAD_GROUP_NAME)
            )
        )


class CanAccessMuestreoModule(BasePermission):
    def has_permission(self, request, view):
        user = getattr(request, "user", None)
        return bool(
            user
            and user.is_authenticated
            and (
                is_admin_user(user)
                or is_in_group(user, PESADOR_GROUP_NAME)
                or is_in_group(user, TECNICOS_GROUP_NAME)
                or is_in_group(user, LABORATORISTAS_GROUP_NAME)
                or is_in_group(user, CALIDAD_GROUP_NAME)
                or is_in_group(user, EXTERNO_GROUP_NAME)
                or user.has_perm("muestreo_laboratorio.view_resultadolaboratorio")
            )
        )
