from app.entities import enums
from django.db import transaction
from rest_framework import viewsets, status
from rest_framework.response import Response
from app.applicationlayer.utils import model_to_dict
from rest_framework.filters import SearchFilter, OrderingFilter
from django_filters import rest_framework as filters
from app.entities.models import Department, EntityLog
from app.applicationlayer.utils import (
    CustomPagination, status_message_response, log_save
)
from django_filters.rest_framework import DjangoFilterBackend
from app.applicationlayer.management.department import serializer
from app.applicationlayer.management.department.table_filters import DepartmentFilterSet
from app.helper import decorators


class DepartmentViewSet(viewsets.ModelViewSet):
    queryset = Department.objects.all().order_by('-created')
    serializer_class = serializer.DepartmentSerializer
    pagination_class = CustomPagination
    lookup_field = 'code'
    filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
    filterset_class = DepartmentFilterSet
    ordering_fields = ('name', 'company__name', 'code')
    search_fields = ('name', 'company__name', 'code')

    @decorators.rms.department_crate
    @transaction.atomic
    def create(self, request, *args, **kwargs):

        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)

        message = status_message_response(
            201, 'success',
            'New Department created', serializer.data
        )

        return Response(
            message
        )

    @decorators.rms.department_list
    def list(self, request, *args, **kwargs):

        queryset = self.filter_queryset(self.get_queryset())
        queryset = queryset.exclude(id=1)
        page = self.paginate_queryset(queryset)

        if page is not None:
            serializer = self.get_serializer(page, many=True)

            message = status_message_response(
                200,
                'success',
                'list of Department found',
                serializer.data
            )
            return self.get_paginated_response(message)

        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

    @decorators.error_safe
    @transaction.atomic
    def destroy(self, request, *args, **kwargs):
        
        instance = self.get_object()
        new_instance = model_to_dict(instance)
        self.perform_destroy(instance)

        log_save(
            enums.LogEnum.DELETED.value,
            enums.LogEntitiesEnum.DEPARTMENT.value,
            new_instance['id'],
            new_instance,
            ''
        )

        return Response(status=status.HTTP_204_NO_CONTENT)

    @transaction.atomic
    def update(self, request, *args, **kwargs):

        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)

        old_instance = model_to_dict(instance)
        self.perform_update(serializer)
        new_instance = serializer.data

        log_save(
            enums.LogEnum.DELETED.value,
            enums.LogEntitiesEnum.DEPARTMENT.value,
            old_instance['id'],
            old_instance,
            new_instance
        )

        return Response(serializer.data)
