import zlib
import pickle

from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from rest_framework import status
from rest_framework.response import Response
from django.views.decorators.gzip import gzip_page
from django.utils.decorators import method_decorator

from common.utils import views
from common.utils.exceptions import ValidationError
from common.utils.return_structure import general_message
from common.utils.serializers import serializer_assembly
from common.utils.excel_operations import ExcelOperator
from .models import PowerStation
from .repositories import (powerstation_queryset, powerstation_repo,
                           outline_queryset, outline_repo)
from .serializers import (PowerStationSerializer, PowerStationListSerializer,
                          PowerstationDetailSerializer, OutlineSerializer,
                          CircuitsSerializer, OutlineInfoSerializer)
from .services import powerstation_service
from .filters import PowerStationFilter


# Create your views here.


class PowerStationView(views.BaseApiView):
    """powerstation view"""
    queryset = powerstation_queryset.get_all_power_station
    serializer_class = PowerStationSerializer
    filter_class = PowerStationFilter

    @swagger_auto_schema(operation_description="电站列表",
                         manual_parameters=[
                             openapi.Parameter("customer",
                                               openapi.IN_QUERY,
                                               description="客户",
                                               required=False,
                                               type=openapi.TYPE_STRING),
                             openapi.Parameter("electricityuser",
                                               openapi.IN_QUERY,
                                               description="户号",
                                               required=False,
                                               type=openapi.TYPE_INTEGER),
                             openapi.Parameter("area",
                                               openapi.IN_QUERY,
                                               description="区域",
                                               required=False,
                                               type=openapi.TYPE_STRING),
                             openapi.Parameter("postcode",
                                               openapi.IN_QUERY,
                                               description="邮编",
                                               required=False,
                                               type=openapi.TYPE_STRING),
                         ],
                         tags=["PowerStation"],
                         responses={
                             status.HTTP_200_OK:
                                 serializer_assembly(PowerStationSerializer,
                                                     many=True)
                         })
    def get(self, request, *args, **kwargs):
        pk = kwargs.get('id')
        if not pk:
            queryset = self.filter_queryset(self.get_queryset())
            # 管理员账号，按公司数据隔离
            if self.is_manager:
                queryset = queryset.filter(
                    service_enterprise_id__in=self.enterprise_ids)
            page = self.paginate_queryset(queryset)
            if page:
                serializer = PowerStationListSerializer(page, many=True)
                return self.get_paginated_response(serializer.data)
            serializer = PowerStationListSerializer(queryset, many=True)
            data = general_message(msg='success',
                                   msg_show='获取列表成功',
                                   list=serializer.data)
            return Response(data, status=status.HTTP_200_OK)
        else:

            queryset = powerstation_repo.get_powerstation(pk)
            serializer = PowerstationDetailSerializer(queryset)
            data = general_message(msg='success',
                                   msg_show='获取详情成功',
                                   bean=serializer.data)
            return Response(data, status=status.HTTP_200_OK)

    @swagger_auto_schema(operation_description="添加电站",
                         request_body=PowerStationSerializer,
                         tags=['PowerStation'],
                         responses={
                             status.HTTP_200_OK:
                                 serializer_assembly(PowerStationSerializer)
                         })
    def post(self, request, *args, **kwargs):
        request.data.update({"enterprise": self.enterprise})
        serializer = self.get_serializer(data=request.data,
                                         context={"request": request})
        serializer.is_valid(raise_exception=True)
        serializer.save()
        queryset = powerstation_service.bind_elecrical_info(
            request_data=request.data, serializer_data=serializer.data)
        res_serializer = PowerstationDetailSerializer(queryset)
        data = general_message(code=100000,
                               msg="success",
                               msg_show="创建成功",
                               bean=res_serializer.data)
        return Response(data, status=status.HTTP_201_CREATED)

    @swagger_auto_schema(operation_description="修改电站",
                         request_body=PowerStationSerializer,
                         tags=['PowerStation'],
                         responses={
                             status.HTTP_200_OK:
                                 serializer_assembly(PowerStationSerializer)
                         })
    def put(self, request, *args, **kwargs):
        pk = kwargs.get('id')
        if not pk:
            raise ValidationError("参数错误")
        else:
            instance = powerstation_repo.get_powerstation(pk)
            if not instance:
                raise ValidationError("参数错误")
            else:
                serializer = self.get_serializer(instance, request.data)
                serializer.is_valid(raise_exception=True)
                serializer.save()
                queryset = powerstation_repo.get_powerstation(
                    serializer.data['id'])
                res_serializer = PowerstationDetailSerializer(queryset)
                # 同步修改电源编号的户号和客户信息
                powerstation_service.update_ele_info(res_serializer.data)
                data = general_message(msg='success',
                                       msg_show='修改成功',
                                       bean=res_serializer.data)
                return Response(data, status=status.HTTP_200_OK)

    @swagger_auto_schema(operation_description="删除电站",
                         manual_parameters=[
                             openapi.Parameter("id",
                                               openapi.IN_QUERY,
                                               description="电站ID",
                                               required=True,
                                               type=openapi.TYPE_INTEGER),
                         ],
                         tags=['PowerStation'],
                         responses={status.HTTP_200_OK: "删除成功"})
    def delete(self, request, *args, **kwargs):
        service = powerstation_service
        pk_list = request.data['id'].strip(',').split(',')

        if not pk_list:
            raise ValidationError("没有id")
        if not isinstance(pk_list, list):
            raise ValidationError('需要一个列表')
        try:
            service.delete_powerstation(pk_list)
            data = general_message(msg='success', msg_show='删除成功')
            return Response(data, status=status.HTTP_200_OK)
        except Exception as e:
            data = general_message(msg='fail', msg_show=e)
            return Response(data, status=status.HTTP_400_BAD_REQUEST)


class PowerStationFileView(views.BaseApiView):
    queryset = powerstation_queryset.get_all_power_station
    serializer_class = PowerStationSerializer

    def get(self, request, *args, **kwargs):
        pk = kwargs.get('id')
        excel_operator_obj = ExcelOperator()
        if pk:
            raise ValidationError('无效参数id')
        else:
            queryset = self.filter_queryset(self.get_queryset())
            # page = self.paginate_queryset(queryset)
            # if page:
            #     serializer = PowerStationListSerializer(page, many=True)
            #     url = excel_operator_obj.excel_export(
            #         serializer.data,
            #         'PowerstationList',
            #         key_map='Powerstation_list_map')
            #     data = general_message(msg='success',
            #                            msg_show='导出列表成功',
            #                            bean=url)
            #     return Response(data, status=status.HTTP_200_OK)
            serializer = PowerStationListSerializer(queryset, many=True)
            url = excel_operator_obj.excel_export(
                serializer.data,
                'PowerstationList',
                key_map='Powerstation_list_map')
            data = general_message(msg='success', msg_show='导出列表成功', bean=url)
            return Response(data, status=status.HTTP_200_OK)

    def post(self, request, *args, **kwargs):
        url = kwargs.get('url')
        data = ExcelOperator.excel_import(url, '')
        try:
            powerstation_obj = PowerStation.objects.create(data)
            serializer = self.get_serializer(powerstation_obj)
            data = general_message(msg='success',
                                   msg_show='获取详情成功',
                                   list=serializer.data)
            return Response(data, status=status.HTTP_200_OK)
        except Exception as e:
            data = general_message(msg='fail', msg_show=e)
            return Response(data, status=status.HTTP_400_BAD_REQUEST)


class OutlineView(views.BaseApiView):
    """
    Outline view
    """
    queryset = outline_queryset.get_outline
    serializer_class = OutlineSerializer

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

    def post(self, request, *args, **kwargs):
        data = request.data.get('outline_list')
        if not data:
            raise ValidationError('请传入出线侧数据')
        if not isinstance(data, list):
            raise ValidationError('需要传入一个数组')
        serializer = OutlineInfoSerializer(data=data, many=True)
        serializer.is_valid(raise_exception=True)
        instance = serializer.save()[0]
        data = general_message(code=100000,
                               msg="success",
                               msg_show="创建成功",
                               bean=OutlineSerializer(instance).data)
        return Response(data, status=status.HTTP_201_CREATED)

    def put(self, request, *args, **kwargs):
        pk = kwargs.get('id')
        if not pk:
            raise ValidationError('需要传入id')
        else:
            instance = outline_repo.get_outline(pk).first()
            serializer = OutlineInfoSerializer(instance, request.data)
            serializer.is_valid(raise_exception=True)
            instance = serializer.save()
            data = general_message(code=100000,
                                   msg="success",
                                   msg_show="更新成功",
                                   bean=OutlineSerializer(instance).data)
            return Response(data, status=status.HTTP_201_CREATED)

    def delete(self, request, *args, **kwargs):
        service = powerstation_service
        pk_list = request.data['id'].strip(',').split(',')
        if not pk_list:
            raise ValidationError("没有id")
        if not isinstance(pk_list, list):
            raise ValidationError('需要一个列表')
        try:
            service.delete_outline(pk_list)
            data = general_message(msg='success', msg_show='删除成功')
            return Response(data, status=status.HTTP_200_OK)
        except Exception as e:
            data = general_message(msg='fail', msg_show=e)
            return Response(data, status=status.HTTP_400_BAD_REQUEST)


@method_decorator(gzip_page, name='dispatch')
class CircuitLCView(views.BaseApiView):
    serializer_class = CircuitsSerializer

    def get(self, request, power_station_id, *args, **kwargs):
        circuits = powerstation_repo.get_power_station_circuit(
            power_station_id)
        serializer = self.get_serializer(instance=circuits, many=True)
        data = general_message(list=serializer.data)
        return Response(data, status=status.HTTP_200_OK)

    def post(self, request, power_station_id, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        data = general_message(code=100000,
                               msg="success",
                               msg_show="创建成功",
                               list=serializer.data)
        return Response(data, status=status.HTTP_201_CREATED)


@method_decorator(gzip_page, name='dispatch')
class CircuitRUDView(views.BaseApiView):
    serializer_class = CircuitsSerializer

    def get(self, request, power_station_id, circuit_id, *args, **kwargs):
        circuit = powerstation_repo.get_power_station_circuit(
            power_station_id, circuit_id).first()
        serializer = self.get_serializer(instance=circuit)
        data = general_message(bean=serializer.data)
        return Response(data, status=status.HTTP_200_OK)

    def put(self, request, power_station_id, circuit_id, *args, **kwargs):
        circuit = powerstation_repo.get_power_station_circuit(
            power_station_id, circuit_id).first()
        if not circuit:
            serializer = self.get_serializer(data=request.data)
            serializer.is_valid(raise_exception=True)
            serializer.save()
        else:
            circuit.draw = str(
                zlib.compress(pickle.dumps(request.data.get(
                    "draw")))) if request.data.get("draw") else None
            circuit.save()
            serializer = self.get_serializer(instance=circuit)
        data = general_message(bean=serializer.data)
        return Response(data, status=status.HTTP_200_OK)

    def delete(self, request, power_station_id, circuit_id, *args, **kwargs):
        powerstation_repo.get_power_station_circuit(power_station_id,
                                                    circuit_id).delete()
        data = general_message(msg_show="删除成功")
        return Response(data, status=status.HTTP_200_OK)


class StationMonitorPointsLView(views.BaseApiView):
    def get(self, request, station_id):
        points = powerstation_service.get_monitor_points(station_id)
        data = general_message(list=points)
        return Response(data, status=status.HTTP_200_OK)
