from django.contrib.contenttypes.models import ContentType
from rest_framework.exceptions import PermissionDenied

from intranet.femida.src.actionlog.decorators import action_logged
from intranet.femida.src.actionlog.models import actionlog
from intranet.femida.src.api.core.pagination import CursorPagination
from intranet.femida.src.api.core.views import BaseView, WorkflowViewMixin
from intranet.femida.src.comments.models import Comment
from intranet.femida.src.comments.workflow import CommentWorkflow
from intranet.femida.src.core.shortcuts import get_object_or_40x

from . import serializers, forms


class CommentListCreateBaseView(BaseView):

    model_class = Comment
    list_item_serializer_class = serializers.CommentSerializer
    detail_serializer_class = serializers.CommentSerializer
    validator_class = forms.CommentForm
    pagination_class = CursorPagination

    related_model_class = None
    related_workflow_class = None
    action_name = None
    actionlog_name = None

    def get_related_object(self):
        if not hasattr(self, '_related_object'):
            queryset = self.related_model_class.objects.all()
            self._related_object = get_object_or_40x(queryset, pk=self.kwargs['pk'])
            self.check_object_permissions(self.request, self._related_object)
        return self._related_object

    def filter_queryset(self, queryset):
        related_object = self.get_related_object()
        content_type = ContentType.objects.get_for_model(related_object)
        return queryset.filter(content_type=content_type, object_id=related_object.id)

    def perform_create(self, data):
        workflow = self.related_workflow_class(
            instance=self.get_related_object(),
            user=self.request.user,
        )
        action = workflow.get_action(self.action_name)
        if not action.is_available():
            raise PermissionDenied('workflow_error')

        return action.perform(**data)

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        with actionlog.init(self.actionlog_name, request.user):
            return self.create(request, *args, **kwargs)


class CommentDetailView(WorkflowViewMixin, BaseView):

    workflow_class = CommentWorkflow
    model_class = Comment
    detail_serializer_class = serializers.CommentSerializer
    validator_class = forms.CommentForm

    def get_validator_class(self):
        return forms.CommentForm if self.request.method == 'PUT' else None

    @action_logged('comment_update')
    def put(self, request, *args, **kwargs):
        return self.perform_action(action_name='update')

    @action_logged('comment_delete')
    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

    def perform_destroy(self, instance):
        return self.perform_action(action_name='delete')
