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 (
    AccessApplicationBoardDecision,
)

from ..serializers import (
    AccessApplicationBoardDecisionSerializer,
)

from .core import DEFAULT_DOC_FORMATS
from .email import send_decision_email, send_decision_ack_email


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


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


class BoardDecisionPermissions(CustomDjangoModelPermissions):

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

    def object_perm_check(self, obj, request) -> bool:

        if request.method == "GET":
            return (
                is_call_coordinator(obj.application, request.user)
                or is_board_chair(obj.application, request.user)
                or obj.reviewer.id == request.user.id
            )
        else:
            return obj.reviewer.id == request.user.id


class AccessApplicationBoardDecisionViewSet(BaseModelViewSet):
    model = AccessApplicationBoardDecision
    queryset = AccessApplicationBoardDecision.objects.all().order_by("id")
    serializer_class = AccessApplicationBoardDecisionSerializer
    permission_classes = [permissions.IsAuthenticated, BoardDecisionPermissions]

    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):
        instance = serializer.save(reviewer=Member.objects.get(id=self.request.user.id))

        send_decision_ack_email(instance)
        send_decision_email(instance, self.request)

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

        Otherwise return reviews where the user is the coordinator or chair
        """

        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(application__call__coordinator__id=self.request.user.id)
        ).distinct()
        return queryset


class AccessApplicationBoardDecisionSupportingDocumentUploadView(ObjectFileUploadView):
    model = AccessApplicationBoardDecision
    queryset = AccessApplicationBoardDecision.objects.all()
    file_field = "supporting_document"
    extensions = DEFAULT_DOC_FORMATS
    permission_classes = [
        permissions.IsAuthenticated,
        BoardDecisionPermissions,
    ]
