from django.db.models import Q
from django.utils.decorators import method_decorator
from django.views.decorators.gzip import gzip_page
from drf_yasg.utils import swagger_auto_schema
from rest_framework import status

# Create your views here.

from common.utils.pagination import CustomPageNumberPagination
from console.order.filters import (OrderListFilter, ConsumableMaterialFilter,
                                   MaterialFilter)
from console.order.models import (Order, WorkTicket, PowerLog, Material,
                                  ConsumableMaterial)
from rest_framework.response import Response

from common.utils.return_structure import general_message, error_message
from common.utils.service_code import VERIFICATION_ERROR
from common.utils.views import BaseApiView, ManagerApiView
from console.order.serializers import (
    OrderAssignSerializer, OrderWorkTicketSerializer,
    OrderRecieveConfirmSerialzier, OrderTransferSerializer,
    OrderSignInSerializer, OrderHandlerSerializer, MaterialUpdateSerialzier,
    OrderListSerializer, MaterialInfoSerializer, OrderAddMaterialSerializer,
    ConsumableMaterialSerializer, OrderArriveSerializer,
    OrderStatisticSerializer, WorkTicketInfoSerializer,
    OrderWorkLogCreateSerializer, OrderInfoSerializer, OrderListInfoSerializer,
    OrderReceiveSerializer)

from common.utils.serializers import serializer_assembly

from common.utils.excel_operations import ExcelOperator

from console.team.models import Team

from console.order.services import order_transfer_notify, \
    order_data_filter

from console.order.serializers import OrderSelfAssignSerializer


class OrderListView(ManagerApiView):
    serializer_class = OrderListInfoSerializer
    queryset = Order.objects.filter().prefetch_related(
        "task", "recipient", "team", "handler", "task__customer",
        "task__customer__service_staff").order_by("-id")
    pagination_class = CustomPageNumberPagination
    filter_class = OrderListFilter

    def get(self, request, *args, **kwargs):
        queryset = self.get_queryset().filter(
            task__customer__service_enterprise__in=self.enterprise_ids)
        queryset = self.filter_queryset(queryset)
        queryset = order_data_filter(queryset, self.user)
        serializer = self.get_serializer(queryset, many=True)
        return Response(
            general_message(list=serializer.data,
                            count=queryset.count(),
                            bean={
                                "total":
                                    queryset.count(),
                                "finish_num":
                                    queryset.filter(status="completed").count()
                            }))


class OrderInfoView(ManagerApiView):
    serializer_class = OrderInfoSerializer
    queryset = Order.objects.filter()
    lookup_field = "id"

    @swagger_auto_schema(operation_description="工单详情",
                         tags=["order"],
                         responses={
                             status.HTTP_200_OK:
                                 serializer_assembly(OrderInfoSerializer)
                         })
    def get(self, request, *args, **kwargs):
        queryset = self.get_queryset().filter(id=kwargs.get("id")).first()
        serializer = self.get_serializer(queryset)
        return Response(
            data=general_message(bean=serializer.data, msg_show="数据请求成功"))


class OrderAssignView(BaseApiView):
    serializer_class = OrderAssignSerializer

    @swagger_auto_schema(operation_description="分派工单",
                         tags=["order"],
                         request_body=OrderAssignSerializer,
                         responses={status.HTTP_200_OK: {}})
    def put(self, request, *args, **kwargs):
        order = Order.objects.filter(id=kwargs.get("id")).first()
        serializer = OrderAssignSerializer(order,
                                           data=request.data,
                                           context={"request": request})

        if serializer.is_valid():
            serializer.save()
            return Response(data=general_message(msg_show="派发成功"))
        return Response(data=error_message(
            code=VERIFICATION_ERROR, msg_show="派发失败", msg=serializer.errors))


class OrderWorkTicketView(BaseApiView):
    serializer_class = OrderWorkTicketSerializer

    @swagger_auto_schema(operation_description="开具工作票",
                         tags=["order"],
                         request_body=OrderWorkTicketSerializer,
                         responses={status.HTTP_200_OK: {}})
    def post(self, request, *args, **kwargs):
        serializer = OrderWorkTicketSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(data=general_message(msg_show="添加成功"))
        return Response(data=error_message(
            code=VERIFICATION_ERROR, msg=serializer.errors, msg_show="添加失败"))


class OrderRecieveConfirmView(BaseApiView):
    serializer_class = OrderRecieveConfirmSerialzier

    @swagger_auto_schema(operation_description="工单确认",
                         tags=["order"],
                         request_body=OrderRecieveConfirmSerialzier,
                         responses={status.HTTP_200_OK: {}})
    def put(self, request, *args, **kwargs):
        order = Order.objects.filter(id=kwargs.get("id")).first()
        serializer = OrderRecieveConfirmSerialzier(order,
                                                   data=request.data,
                                                   context={"order": order})
        if serializer.is_valid():
            serializer.save()
            return Response(data=general_message(msg_show="已确认"))
        return Response(data=error_message(
            msg=serializer.errors, msg_show="确认失败", code=VERIFICATION_ERROR))


class OrderTranferView(BaseApiView):
    serializer_class = OrderTransferSerializer

    @swagger_auto_schema(operation_description="转单",
                         tags=["order"],
                         request_body=OrderRecieveConfirmSerialzier,
                         responses={status.HTTP_200_OK: {}})
    def put(self, request, *args, **kwargs):
        order = Order.objects.filter(id=kwargs.get("id")).first()
        if not order:
            return Response("工单{}不存在".format(kwargs.get("id")))
        serializer = OrderTransferSerializer(order,
                                             data=request.data,
                                             context={"request": request})
        if serializer.is_valid():
            serializer.save()
            # 发送站内消息
            order_transfer_notify(**{"order": order, "user": self.user})
            return Response(data=general_message(msg_show="转单成功"))
        return Response(data=error_message(
            msg=serializer.errors, msg_show="转单失败", code=VERIFICATION_ERROR))


class OrderSignInView(BaseApiView):
    serializer_class = OrderSignInSerializer

    @swagger_auto_schema(operation_description="签到",
                         tags=["order"],
                         request_body=OrderSignInSerializer,
                         responses={status.HTTP_200_OK: {}})
    def put(self, request, *args, **kwargs):
        order = Order.objects.filter(id=kwargs.get("id")).first()
        serializer = OrderSignInSerializer(order, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(general_message(msg_show="签到成功"))
        return Response(
            error_message(msg_show="签到失败",
                          msg=serializer.errors,
                          code=VERIFICATION_ERROR))


class OrderHandlerView(BaseApiView):
    serializer_class = OrderHandlerSerializer

    @swagger_auto_schema(operation_description="工单填报",
                         tags=["order"],
                         request_body=OrderHandlerSerializer,
                         responses={status.HTTP_200_OK: {}})
    def post(self, request, *args, **kwargs):
        order = Order.objects.filter(id=kwargs.get("id")).first()
        serialzier = OrderHandlerSerializer(data=request.data,
                                            context={
                                                "order": order,
                                                "user": request.user
                                            })
        if serialzier.is_valid():
            serialzier.save()
            return Response(data=general_message("提交成功"))
        return Response(data=error_message(
            msg=serialzier.errors, msg_show="提交失败", code=VERIFICATION_ERROR))


class OrderListRecent(ManagerApiView):
    serializer_class = OrderListInfoSerializer
    queryset = Order.objects.filter().exclude(
        receiving_time=None).prefetch_related("task", "recipient", "team",
                                              "handler", "task__customer",
                                              "task__station").order_by("-id")
    filter_class = OrderListFilter

    @method_decorator(gzip_page, name='dispatch')
    def get(self, request, *args, **kwargs):
        queryset = self.get_queryset().filter(
            task__customer__service_enterprise_id__in=self.enterprise_ids)
        queryset = self.filter_queryset(queryset)
        team = Team.objects.filter(Q(team_headman=self.user) | Q(member=self.user))
        if not team:
            return Response(
                general_message(list=[], bean={
                    "total": 0,
                    "finish_num": 0
                }))
        queryset = queryset.filter(team__in=team)
        serializer = self.get_serializer(queryset, many=True)
        return Response(
            general_message(list=serializer.data,
                            count=queryset.count(),
                            bean={
                                "total":
                                    queryset.count(),
                                "finish_num":
                                    queryset.filter(status="completed").count()
                            }))


class MaterialView(ManagerApiView):
    queryset = Material.objects.filter(deleted=False)
    serializer_class = MaterialInfoSerializer
    filter_class = MaterialFilter

    def get(self, request, *args, **kwargs):
        id = kwargs.get("id")
        if id:
            return self.get_info(request, *args, **kwargs)
        return self.get_list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        material = self.get_queryset().filter(id=kwargs.get("id")).first()
        serializer = self.get_serializer(material, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(general_message(msg_show="修改成功"))

    def delete(self, request, *args, **kwargs):
        material = self.get_queryset().filter(id=kwargs.get("id")).first()
        if not material:
            return Response(
                error_message(code=VERIFICATION_ERROR,
                              msg_show="材料%s不存在" % kwargs.get("id")))
        material.deleted = True
        material.save()
        return Response(general_message(msg_show="删除成功"))


class OrderAddMaterialView(ManagerApiView):
    queryset = ConsumableMaterial.objects.filter(deleted=False)
    serializer_class = OrderAddMaterialSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(general_message(msg_show="耗材添加成功"))
        return Response(
            error_message(msg_show=serializer.errors, code=VERIFICATION_ERROR))


class OrderRemoveMaterialView(ManagerApiView):
    queryset = ConsumableMaterial.objects.filter(deleted=False)

    def delete(self, request, *args, **kwargs):
        consumable_material = self.get_queryset().filter(
            id=kwargs.get("id")).first()
        if not consumable_material:
            return Response(
                error_message(msg_show="耗材不存在{}".format(kwargs.get("id")),
                              code=VERIFICATION_ERROR))
        consumable_material.delete()
        return Response(general_message(msg_show="删除成功"))


class OrderMaterialView(ManagerApiView):
    queryset = ConsumableMaterial.objects.filter(deleted=False)
    serializer_class = ConsumableMaterialSerializer
    filter_class = ConsumableMaterialFilter

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


class OrderWorkLogView(ManagerApiView):
    queryset = PowerLog.objects.filter()
    serializer_class = OrderWorkLogCreateSerializer

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)


class OrderExport(ManagerApiView):
    queryset = Order.objects.filter()
    serializer_class = OrderListSerializer
    filter_class = OrderListFilter

    def post(self, request, *args, **kwargs):
        if not request.data.get("order_ids"):
            orders = self.filter_queryset(self.get_queryset())
        else:
            orders = self.get_queryset().filter(
                id__in=request.data.get("order_ids"))
        serializer = self.get_serializer(orders, many=True)
        excel = ExcelOperator()
        data = excel.excel_export(serializer.data,
                                  "OrderList",
                                  key_map="OrderListMap")
        return Response(general_message(msg_show="导出成功", bean=data))


class MaterialUpdateView(ManagerApiView):
    queryset = ConsumableMaterial.objects.filter()
    serializer_class = MaterialUpdateSerialzier

    def put(self, request, *args, **kwargs):
        consumable_material = self.get_queryset().filter(
            id=kwargs.get("id")).first()
        if not consumable_material:
            return Response(
                error_message("耗材记录{}不存在".format(kwargs.get("id")),
                              code=VERIFICATION_ERROR))
        serializer = self.get_serializer(consumable_material, request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(general_message(msg_show="修改成功"))
        return Response(
            error_message(msg_show=serializer.errors,
                          msg=serializer.errors,
                          code=VERIFICATION_ERROR))


class WorkTicketInfoView(ManagerApiView):
    queryset = WorkTicket.objects.filter(deleted=False)
    serializer_class = WorkTicketInfoSerializer

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


class OrderArriveView(ManagerApiView):
    queryset = Order.objects.filter(deleted=False)
    serializer_class = OrderArriveSerializer

    def put(self, request, *args, **kwargs):
        order = self.get_queryset().filter(id=kwargs.get("id")).first()
        if not order:
            return Response(
                error_message(msg_show="工单{}不存在".format(kwargs.get("id")),
                              code=VERIFICATION_ERROR))
        serializer = self.get_serializer(order, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(general_message("签到成功"))
        return Response(
            error_message(msg_show=serializer.errors, code=VERIFICATION_ERROR))


class OrderStatisticView(ManagerApiView):
    queryset = Team.objects.filter(deleted=False)
    serializer_class = OrderStatisticSerializer

    def get(self, request, *args, **kwargs):
        team = Team.objects.filter(Q(team_headman=self.user) | Q(member=self.user),
                                   deleted=False).first()
        serializer = self.get_serializer(team)
        if not team:
            return Response(
                error_message(code=VERIFICATION_ERROR, msg_show="当前用户没有加入班组"))

        return Response(general_message(beam=serializer.data))


class OrderReceiveView(ManagerApiView):
    serializer_class = OrderReceiveSerializer
    queryset = Order.objects.filter(deleted=False, status="pending")

    def put(self, request, *args, **kwargs):
        order = Order.objects.filter(id=kwargs.get("id")).first()
        if not order:
            return Response(
                error_message(code=VERIFICATION_ERROR,
                              msg_show="工单{}不存在".format(kwargs.get("id"))))
        serializer = self.get_serializer(order, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(general_message("接单成功"))
        return Response(
            error_message(code=VERIFICATION_ERROR,
                          msg=serializer.errors,
                          msg_show="接单失败"))


class OrderReceiveListView(ManagerApiView):
    serializer_class = OrderListInfoSerializer
    queryset = Order.objects.filter(receiving_time=None,
                                    status="pending",
                                    deleted=False).prefetch_related(
        "task", "recipient", "team", "handler",
        "task__customer",
        "task__station").order_by("-id")
    filter_class = OrderListFilter

    def get(self, request, *args, **kwargs):
        queryset = self.get_queryset().filter(
            task__customer__service_enterprise_id__in=self.enterprise_ids)
        queryset = self.filter_queryset(queryset)
        team = Team.objects.filter(Q(team_headman=self.user) | Q(member=self.user))
        if not team:
            return Response(
                general_message(list=[], bean={
                    "total": 0,
                    "finish_num": 0
                }))
        queryset = queryset.filter(team__in=team)
        serializer = self.get_serializer(queryset, many=True)
        return Response(
            general_message(list=serializer.data,
                            count=queryset.count(),
                            bean={
                                "total":
                                    queryset.count(),
                                "finish_num":
                                    queryset.filter(status="completed").count()
                            }))


class GrabbingOrdersListView(BaseApiView):
    queryset = Order.objects.filter(status="waiting_dispatch", team_id=None)
    serializer_class = OrderListInfoSerializer

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


class OrderAssignSelfView(BaseApiView):
    queryset = Order.objects.filter()
    serializer_class = OrderSelfAssignSerializer

    def put(self, request, *args, **kwargs):
        order = self.get_queryset().filter(id=kwargs.get("id")).first()
        if not order or order.status != "waiting_dispatch":
            return Response(
                error_message(code=VERIFICATION_ERROR,
                              msg_show="工单%s不存在或者工单状态不可抢单" % kwargs.get("id")))
        serializer = self.get_serializer(order, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(general_message("抢单成功"))
        return Response(
            error_message(code=VERIFICATION_ERROR,
                          msg_show="抢单失败",
                          msg=serializer.errors))
