import logging
from itertools import chain

from django.conf import settings
from django.db.models import Case, When
from django.db.models import Q
from rest_framework.mixins import RetrieveModelMixin, ListModelMixin, UpdateModelMixin, CreateModelMixin, \
    DestroyModelMixin
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet

from assets.models.assets import Asset
from assets.serializers.assets import AssetActiveProblemsSerializer
from core.mixins import ApiPermissionCheckMixin, ExportToCsvMixin
from incident.filters import IncidentFilters
from incident.models import Incident, IncidentCategory, IncidentEffect, IncidentRecommendations
from incident.serializers.incident import (IncidentSerializer, IncidentsCsvExportSerializer,
                                           IncidentCategorySerializer, IncidentEffectSerializer,
                                           IncidentRecommendationsSerializer)
from incident.serializers.incident_edit_serializer import IncidentEditSerializer
from incident.services.ws_incidents import incident_count_notification_to_ws
from ncircc.services.utils import get_incident_notification_mapper
from perms.models import Perm

LICENSE_FEATURE_EVENT_PROCESSING = getattr(settings, 'LICENSE_FEATURE_EVENT_PROCESSING')

_log = logging.getLogger()


class AssetProblemsViewSet(ApiPermissionCheckMixin, RetrieveModelMixin, GenericViewSet):  # deprecared mast be delete
    serializer_class = AssetActiveProblemsSerializer
    queryset = Asset.objects.all()
    console_permissions = {'retrieve': [Perm.can_view_incidents_list]}

    class Meta:
        model = Asset


class IncidentViewSet(ApiPermissionCheckMixin,
                      ListModelMixin,
                      RetrieveModelMixin,
                      UpdateModelMixin,
                      ExportToCsvMixin,
                      GenericViewSet):
    """Incident API View"""
    serializer_class = IncidentSerializer
    column_titles = IncidentsCsvExportSerializer.Meta.fields
    console_permissions = {"list": [Perm.can_view_incidents_list], "retrieve": [Perm.can_view_incidents],
                           'csv_export': [Perm.can_export_incidents_list], 'update': [Perm.can_view_incidents],
                           'partial_update': [Perm.can_view_incidents]}
    filterset_class = IncidentFilters
    filters = []

    def update(self, request, *args, **kwargs) -> Response:
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = IncidentEditSerializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)

        self.perform_update(serializer)
        incident_count_notification_to_ws()

        if getattr(instance, '_prefetched_objects_cache', None):
            instance._prefetched_objects_cache = {}
        response_data = IncidentSerializer(instance).data
        return Response(response_data)

    def get_serializer_context(self) -> dict:
        context = super().get_serializer_context()
        context['incident_notification_id_map'] = get_incident_notification_mapper()
        return context

    def get_queryset(self):
        queryset = Incident.objects
        user = self.request.user
        queryset = queryset.annotate(ordering=Case(
            When(assigned_to=user, status__in=[Incident.Status.ASSIGNED, Incident.Status.DELAYED], then=1),
            When(~Q(assigned_to=user), status__in=[Incident.Status.ASSIGNED, Incident.Status.DELAYED], then=2),
            When(assigned_to=None, status__in=[Incident.Status.NOT_ASSIGNED, Incident.Status.DELAYED], then=3),
            When(assigned_to=user, status=Incident.Status.RESOLVED, then=4),
            When(~Q(assigned_to=user), status=Incident.Status.RESOLVED, then=5),
            When(assigned_to=None, status=Incident.Status.RESOLVED, then=6),
            When(status=Incident.Status.FALSE_ALARM, then=7),
            default=8
        ))
        queryset = queryset.order_by('ordering', 'assigned_to', 'status')
        return queryset


class IncidentCategoryViewSet(ApiPermissionCheckMixin, ListModelMixin,
                              GenericViewSet):  # deprecated api mast be removed in 1.4.x relase
    serializer_class = IncidentCategorySerializer
    queryset = IncidentCategory.objects.order_by('name')
    console_permissions = [Perm.can_view_incidents_list]

    class Meta:
        model = IncidentCategory


class IncidentEffectViewSet(ApiPermissionCheckMixin,
                            ListModelMixin,
                            RetrieveModelMixin,
                            UpdateModelMixin,
                            CreateModelMixin,
                            DestroyModelMixin,
                            GenericViewSet):
    serializer_class = IncidentEffectSerializer
    queryset = IncidentEffect.objects.order_by('name')
    console_permissions = [Perm.can_view_incidents_list]

    class Meta:
        model = IncidentEffect


class IncidentRecommendationsViewSet(ApiPermissionCheckMixin,
                                     ListModelMixin,
                                     DestroyModelMixin,
                                     CreateModelMixin,
                                     UpdateModelMixin,
                                     RetrieveModelMixin,
                                     GenericViewSet):
    serializer_class = IncidentRecommendationsSerializer
    queryset = IncidentRecommendations.objects.order_by('name')
    console_permissions = [Perm.can_work_with_incidents]

    class Meta:
        model = IncidentRecommendations
