from rest_framework import permissions, viewsets
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.authtoken.models import Token
from rest_framework.response import Response
from rest_framework import filters

from ichec_django_core.models import Member

from ichec_django_core.serializers import MemberSerializer

from .files import ObjectFileDownloadView, ObjectFileUploadView


class SelfEditOrDjangoModelPermissions(permissions.DjangoModelPermissions):

    def has_permission(self, request, view):

        if not request.user or not request.user.is_authenticated:
            return False

        # Fall through to allow edit permission checks to happen at object level
        if request.method in ["PUT", "PATCH"]:
            return True

        return super().has_permission(request, view)

    def has_object_permission(self, request, view, obj):

        # Allow metadata checks on endpoint
        if request.method in ["HEAD", "OPTIONS"]:
            return True

        if not request.user or not request.user.is_authenticated:
            return False

        # Full permissions are only given to the creator of the object.
        if request.method in ["PUT", "PATCH"] and obj.id == request.user.id:
            return True

        # Fall back to Django model permissions for everyone else
        return super().has_permission(request, view)


class MemberViewSet(viewsets.ModelViewSet):
    queryset = Member.objects.all().order_by("id")
    serializer_class = MemberSerializer
    permission_classes = [
        permissions.IsAuthenticated,
        permissions.DjangoModelPermissions,
    ]
    filter_backends = [filters.OrderingFilter, filters.SearchFilter]
    ordering_fields = ["username"]
    ordering = ["username"]
    search_fields = ["username", "first_name", "last_name", "email"]

    def get_queryset(self):
        queryset = Member.objects.all().order_by("id")
        org_id = self.request.query_params.get("organization")
        if org_id is not None:
            queryset = queryset.filter(organizations__id=org_id)
        call_id = self.request.query_params.get("call")
        if call_id is not None:
            queryset = queryset.filter(access_boards__id=call_id)
        return queryset


class MemberProfileDownloadView(ObjectFileDownloadView):
    model = Member
    file_field = "profile"


class MemberProfileThumbnailDownloadView(ObjectFileDownloadView):
    model = Member
    file_field = "profile_thumbnail"


class MemberProfileUploadView(ObjectFileUploadView):
    model = Member
    queryset = Member.objects.all()
    file_field = "profile"


class CustomAuthToken(ObtainAuthToken):

    authentication_classes: list = []

    """
    This overrides DRFs built in api auth token view
    so we return some more user details. This helps clients
    fetch the user post auth.
    """

    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(
            data=request.data, context={"request": request}
        )
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data["user"]
        token, created = Token.objects.get_or_create(user=user)

        return Response({"token": token.key, "user_id": user.pk})
