import json

from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from django.shortcuts import render
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from rest_framework.decorators import api_view
from rest_framework import status
from .models import (TableAllDevCmdDefine, TableDevCmdNamePoll, 
                     TableSoftLimitAngle, TableXproAllDevinfo)
from .serializers import (TableAllDevCmdDefineSerializer, TableDevCmdNamePollSerializer, 
                          TableSoftLimitAngleSerializer, TableXproAllDevinfoSerializer)
from .utils import tree_data


class TableAllDevCmdDefineView(ModelViewSet):
    queryset = TableAllDevCmdDefine.objects.all()
    serializer_class = TableAllDevCmdDefineSerializer

    def list(self, request):
        serializer = self.get_serializer(self.get_queryset(), many=True)
        data = tree_data(serializer.data, 'cmd_name')
        return Response(data)
    
    def perform_destroy(self, instance):
        """
        删除某个字段，需要将字段的 index 更新
        TODO: 返回更新后的数据（不能做完一个操作之后，页面就刷新）
        """
        
        # 获取改字段的 cmd_name
        cmd_name = instance.cmd_name
        super().perform_destroy(instance)
        fields = self.get_queryset().filter(cmd_name=cmd_name).all()

        # 更新字段的 index
        for i in range(len(fields)):
            print(fields[i])
            fields[i].fieldindex = i + 1
            fields[i].save()


class TableDevCmdNamePollView(ModelViewSet):
    queryset = TableDevCmdNamePoll.objects.all()
    serializer_class = TableDevCmdNamePollSerializer

    def list(self, request):
        serializer = self.get_serializer(self.get_queryset(), many=True)
        data = tree_data(serializer.data, 'protocol_name')
        return Response(data)
    

class TableSoftLimitAngleView(ModelViewSet):
    queryset = TableSoftLimitAngle.objects.all()
    serializer_class = TableSoftLimitAngleSerializer


class TableXproAllDevinfoView(ModelViewSet):
    queryset = TableXproAllDevinfo.objects.all()
    serializer_class = TableXproAllDevinfoSerializer


@swagger_auto_schema(method='post', request_body=openapi.Schema(
    type=openapi.TYPE_OBJECT,
    properties={
        'cmds': openapi.Schema(type=openapi.TYPE_OBJECT, properties={
            'protocol_name': openapi.Schema(type=openapi.TYPE_STRING),
            'cmd_name': openapi.Schema(type=openapi.TYPE_STRING),
            'cmd_type': openapi.Schema(type=openapi.TYPE_STRING),
            'encode': openapi.Schema(type=openapi.TYPE_STRING),
            'timing_cmd_cycle_period': openapi.Schema(type=openapi.TYPE_INTEGER),
            'cmd_explain': openapi.Schema(type=openapi.TYPE_STRING),
            'fields': openapi.Schema(type=openapi.TYPE_ARRAY, items=openapi.Items(type=openapi.TYPE_OBJECT, properties={
                "cmd_name": openapi.Schema(type=openapi.TYPE_STRING),
                "cmd_type": openapi.Schema(type=openapi.TYPE_STRING),
                "fieldindex": openapi.Schema(type=openapi.TYPE_INTEGER),
                "fieldname": openapi.Schema(type=openapi.TYPE_STRING),
                "fieldsize": openapi.Schema(type=openapi.TYPE_INTEGER),
                "value": openapi.Schema(type=openapi.TYPE_STRING),
                "minvalue": openapi.Schema(type=openapi.TYPE_STRING),
                "maxvalue": openapi.Schema(type=openapi.TYPE_STRING),
                "datatype": openapi.Schema(type=openapi.TYPE_INTEGER),
                "operation_in": openapi.Schema(type=openapi.TYPE_INTEGER),
                "operation_in_num": openapi.Schema(type=openapi.TYPE_INTEGER),
                "operation_out": openapi.Schema(type=openapi.TYPE_INTEGER),
                "operation_out_num": openapi.Schema(type=openapi.TYPE_INTEGER),
                "operabo_in": openapi.Schema(type=openapi.TYPE_INTEGER),
                "operabo_out": openapi.Schema(type=openapi.TYPE_INTEGER),
                "lua_script_in": openapi.Schema(type=openapi.TYPE_STRING),
                "lua_script_out": openapi.Schema(type=openapi.TYPE_STRING)
            }))
        })
    }
))
@api_view(['POST'])
def test(request):
    protocol_cmd = TableDevCmdNamePollView()
    cmd_fields = TableAllDevCmdDefineView()
    # print(request.data)
    protocol_cmd.request = request
    protocol_cmd.format_kwarg = None  # 设置 format_kwarg 属性
    
    cmd_fields.request = request
    cmd_fields.format_kwarg = None  # 设置 format_kwarg 属性

    cmds = request.data.get('cmds')
    for cmd in cmds.values():
        # 将指令的字段属性从字典中弹出
        fields = cmd.pop('fields')

        # 创建协议指令
        protocol_cmd_serializer = protocol_cmd.get_serializer(data=cmd)
        protocol_cmd_serializer.is_valid(raise_exception=True)
        cmd_explain = protocol_cmd_serializer.validated_data.get('cmd_explain')
        try:
            json.loads(cmd_explain)
        except json.JSONDecodeError:
            cmd_explain_dict = {
                'explain': cmd_explain,
                'version': "20230101"
            }
            cmd_explain = json.dumps(cmd_explain_dict)
        protocol_cmd_serializer.validated_data['cmd_explain'] = cmd_explain
        protocol_cmd.perform_create(protocol_cmd_serializer)
        # 创建指令
        for field in fields:
            cmd_fields_serializer = cmd_fields.get_serializer(data=field)
            cmd_fields_serializer.is_valid(raise_exception=True)
            cmd_fields.perform_create(cmd_fields_serializer)
    return Response(status=status.HTTP_201_CREATED)
