from rest_framework import permissions
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.authtoken.models import Token
from rest_framework.response import Response
from rest_framework.generics import RetrieveAPIView
from rest_framework.decorators import action
from rest_framework.views import APIView

from ichec_django_core.models import Member

from ichec_django_core.serializers import (
    MemberListSerializer,
    MemberDetailSerializer,
    MemberSelfDetailSerializer,
)

from .core import SearchableModelViewSet
from .files import ObjectFileUploadView, DEFAULT_IMAGE_FORMATS
from .permissions import SelfEditOrDjangoModelPermissions


class MemberViewSet(SearchableModelViewSet):

    model = Member
    queryset = Member.objects.filter(active=True)
    serializer_class = MemberListSerializer
    permission_classes = [
        permissions.IsAuthenticated,
        SelfEditOrDjangoModelPermissions,
    ]
    ordering_fields = SearchableModelViewSet.ordering_fields + ("username",)
    ordering: tuple[str, ...] = ("username",)
    search_fields = ["username", "first_name", "last_name", "email"]
    filterset_fields = ("organizations__id", "groups__id")

    serializers = {
        "retrieve": MemberDetailSerializer,
        "list": MemberListSerializer,
        "create": MemberDetailSerializer,
        "update": MemberDetailSerializer,
        "partial_update": MemberDetailSerializer,
    }

    @action(detail=True, url_path="profile", url_name="profile")
    def profile(self, request, pk=None):
        return self.download(request, "profile")

    @action(detail=True, url_path="profile/thumbnail", url_name="profile-thumbnail")
    def profile_thumbnail(self, request, pk=None):
        return self.download(request, "profile_thumbnail")

    def get_serializer_class(self):
        if (
            self.action in ("retrieve", "update", "partial_update")
            and self.request.user.id == self.get_object().id
        ):
            return MemberSelfDetailSerializer
        return self.serializers.get(self.action, self.serializer_class)

    def get_queryset(self):
        queryset = self.queryset
        board_id = self.request.query_params.get("access_boards__id")
        if board_id is not None:
            queryset = queryset.filter(access_boards__id=board_id)
        return queryset


class MemberSelfView(RetrieveAPIView):

    serializer_class = MemberSelfDetailSerializer
    permission_classes = [
        permissions.IsAuthenticated,
    ]

    def get_object(self):
        return Member.objects.get(id=self.request.user.id)


class MemberProfileUploadView(ObjectFileUploadView):
    model = Member
    queryset = Member.objects.all()
    file_field = "profile"
    extensions = DEFAULT_IMAGE_FORMATS
    permission_classes = [
        permissions.IsAuthenticated,
        SelfEditOrDjangoModelPermissions,
    ]


class GetAuthToken(APIView):

    permission_classes = [permissions.IsAuthenticated]

    def get(self, request, *args, **kwargs):
        token = Token.objects.get(user__id=request.user.id)
        return Response({"token": token.key})


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})
