import bpy
from ...component_utils import generateGuid

def deserializeAnimator(data: dict):
    node_tree = bpy.data.node_groups.new(data["name"], 'NEEDLE_AnimatorController')
    pass

class SerializationContext: 
    def __init__(self):
        self.parameters = []

class NEEDLE_NodeTreeBase(bpy.types.NodeTree):
    bl_idname = 'NEEDDLE_AnimatorControllerBase'
    bl_label = 'Needle Node Editor' 
    bl_icon = 'NODETREE'

    def update(self):
        pass

    def relink_socket(self, old_socket, new_socket):
        pass

    def execute(self, context):
        pass

    def serialize(self, serializer):
        pass


class NEEDLE_AnimatorController(NEEDLE_NodeTreeBase):
    bl_idname = 'NEEDLE_AnimatorController'
    bl_label = 'Needle Animator Controller'
    bl_icon = 'NODETREE'

    default_state: bpy.props.StringProperty()

    default_state_color = (0.69, 0.37, 0.01)

    def update(self):
        self.ensurePropertiesNode()
        self.ensureDefaultState()
    
    def ensurePropertiesNode(self):
        # ensure that we have a properties node
        animatorProperties = None
        nodes = self.nodes
        for node in nodes:
            if node.bl_idname == 'AnimatorProperties':
                animatorProperties = node
                break
        if not animatorProperties:
            animatorProperties = nodes.new('AnimatorProperties')
            animatorProperties.location = (self.view_center[0] - 10, self.view_center[1] - 20)
            animatorProperties.width = 300
        return animatorProperties

    def serialize(self, serializer):
        persistent = serializer.getExtension('NEEDLE_persistent_assets')
        
        properties = self.ensurePropertiesNode()
        parameters = properties.parameters

        serializationContext = SerializationContext()
        serializationContext.graph = self
        serializationContext.parameters = parameters
        serializer.animatorSerializationContext = serializationContext

        serializedParameters = properties.serialize(serializer)

        layers = []
        defaultLayerStates = []
        for node in self.nodes:
            if node.bl_idname == 'AnimatorState':
                defaultLayerStates.append(node.serialize(serializer))
        defaultStateMachine = {
            "name" : "default",
            "states" : defaultLayerStates,
            "defaultState" : self.getAnimatorStateIndex(self.default_state)
        }
        defaultLayer = {
            'name': 'default',
            'stateMachine': defaultStateMachine
        }
        layers.append(defaultLayer)

        obj = { 
            "name" : self.name,
            "guid": generateGuid(self, "animatorcontroller"),
            "__type": "AnimatorController",
            "parameters": serializedParameters,
            "layers": layers
        }   
        pointer = persistent.registerSerializedAsset(obj)
        return pointer

    
    def setDefaultState(self, nodeId):
        if self.default_state != None and self.default_state != "" and self.default_state != nodeId:
            for node in self.nodes:
                if hasattr(node, "state_id") and node.state_id == self.default_state:
                    # todo: handle state change
                    node.use_custom_color = False
                    break
        self.default_state = nodeId
        # find node
        for node in self.nodes:
            if hasattr(node, "state_id") and node.state_id == nodeId:
                node.use_custom_color = True
                node.color = self.default_state_color

    def getAnimatorStateIndex(self, stateId):
        animatorStatesFound = 0
        for i in range(len(self.nodes)):
            node = self.nodes[i]
            if node.bl_idname == 'AnimatorState':
                if node.state_id == stateId:
                    return animatorStatesFound
                animatorStatesFound += 1
        return None
    
    def ensureDefaultState(self):
        for node in self.nodes:
            if node.bl_idname == 'AnimatorState' and node.state_id == self.default_state:
                node.use_custom_color = True
                return
        for node in self.nodes:
            if node.bl_idname == 'AnimatorState':
                self.setDefaultState(node.state_id)
                break


class NEEDLE_AnimatorControllerGroup(NEEDLE_NodeTreeBase):
    bl_idname = 'NEEDLE_AnimatorControllerGroup'
    bl_label = "AnimatorLayer (groups)"
    bl_icon = 'NODETREE'

    @classmethod
    def poll(cls, context):
        return False
    


def register():
    try:
        unregister()
    except:
        pass
    bpy.utils.register_class(NEEDLE_AnimatorController)
    bpy.utils.register_class(NEEDLE_AnimatorControllerGroup)


def unregister():
    try:
        bpy.utils.unregister_class(NEEDLE_AnimatorController)
        bpy.utils.unregister_class(NEEDLE_AnimatorControllerGroup)
    except:
        pass