from django.db.models import Q

from rest_framework import permissions, viewsets
from rest_framework.decorators import action

from ichec_django_core.models import Member
from ichec_django_core.views import (
    ObjectFileUploadView,
    BaseModelViewSet,
    CustomDjangoModelPermissions,
)

from ..models import (
    AccessApplicationBoardReview,
)

from ..serializers import (
    AccessApplicationBoardReviewSerializer,
)


def is_board_chair(application, user):
    return user.id == application.call.board_chair.id


def is_on_access_board(application, user):
    if user.id == application.call.board_chair.id:
        return True

    for member in application.call.board_members.all():
        if member.id == user.id:
            return True
    return False


def is_call_coordinator(application, user):
    return application.call.coordinator.id == user.id


def is_on_board(application, user):
    return is_call_coordinator(application, user) or is_on_access_board(
        application, user
    )


class BoardReviewPermissions(CustomDjangoModelPermissions):

    intercept_methods: list = ["GET"]
    safe_methods: list = ["HEAD", "OPTIONS"]

    def object_perm_check(self, obj, request) -> bool:
        return (
            obj.reviewer.id == request.user.id
            or is_call_coordinator(obj.application, request.user)
            or is_board_chair(obj.application, request.user)
        )


class AccessApplicationBoardReviewViewSet(BaseModelViewSet):
    model = AccessApplicationBoardReview
    queryset = AccessApplicationBoardReview.objects.all().order_by("id")
    serializer_class = AccessApplicationBoardReviewSerializer
    permission_classes = [
        permissions.IsAuthenticated,
        BoardReviewPermissions,
    ]

    filterset_fields = ("application__id",)

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

    def perform_create(self, serializer):
        serializer.save(reviewer=Member.objects.get(id=self.request.user.id))

    def get_queryset(self):
        """
        If user has explicit Django view permissions return
        all reviews.

        Otherwise return reviews where the user is the coordinator,
        chair or permored the review themselves
        """

        if self.has_model_view_permission():
            return viewsets.ModelViewSet.get_queryset(self)

        queryset = viewsets.ModelViewSet.get_queryset(self)
        queryset = queryset.filter(
            Q(application__call__board_chair__id=self.request.user.id)
            | Q(reviewer__id=self.request.user.id)
            | Q(application__call__coordinator__id=self.request.user.id)
        ).distinct()
        return queryset


class AccessApplicationBoardReviewSupportingDocumentUploadView(ObjectFileUploadView):
    model = AccessApplicationBoardReview
    queryset = AccessApplicationBoardReview.objects.all()
    file_field = "supporting_document"
    extensions = (".odt", ".doc", ".docx", ".pdf", ".ods", ".xls", ".xlsx")
    permission_classes = [
        permissions.IsAuthenticated,
        BoardReviewPermissions,
    ]
