from perm.models import HierarchyModel, UserModel
from utils.decorators import cache_result, cache_remove


# 数据操作类
class UserHierarchy:
    SupportDepartment = "员工"

    @classmethod
    @cache_result(3600, 'user_hierarchy')
    def load(cls):
        records = HierarchyModel.objects.all()
        id_obj_map = {item.id: item for item in records}
        uid_obj_map = {item.user_id: item for item in records}
        return id_obj_map, uid_obj_map

    @classmethod
    @cache_remove('user_hierarchy')
    def add_child_node(cls, parent_id, child_uid):
        node = HierarchyModel()
        node.department = cls.SupportDepartment
        node.parent_id = parent_id
        node.user_id = child_uid
        node.is_leaf = True
        user = UserModel.objects.get(id=child_uid)
        node.user_name = user.real_name
        node.save()
        return node

    @classmethod
    @cache_remove('user_hierarchy')
    def del_child_node(cls, parent_id, child_id):
        node = HierarchyModel.objects.get(id=child_id)
        node.delete()
        return

    @classmethod
    @cache_remove('user_hierarchy')
    def edit_node(cls, node_id, uid):
        node = HierarchyModel.objects.get(id=node_id)
        user = UserModel.objects.get(id=uid)
        node.user_id = user.id
        node.user_name = user.real_name
        node.save(update_fields=['user_id', 'user_name'])
        return node


# 配合id_obj_map
# 使用的树处理工具类
class UserHierarchyTree:
    def __init__(self):
        self.nodes, self.users = UserHierarchy.load()

    # 从树形记录中，获取指定节点的直接子节点
    def get_children(self, parent_node=2):
        nodes = self._get_children(parent_node)
        return [self.to_dict(node) for node in nodes]

    def _get_children(self, parent_node=2):
        ret = [node for node_id, node in self.nodes.items() if node.parent_id == parent_node]
        return ret

    # 递归获取节点的所有子节点
    def __recursive_get_children(self, top_id, parent_id, lst):
        children = self._get_children(parent_id)
        if len(children) == 0 and top_id != parent_id:  # 终止条件，进入叶子节点，除去第一次调用遇到叶子节点
            lst.append(parent_id)
            return

        for child in children:
            lst.append(child.id)
            self.__recursive_get_children(top_id, child.id, lst)
        return

    # 获取parent的所有子孙节点
    def get_all_children_id(self, parent_id):
        ret = []
        self.__recursive_get_children(parent_id, parent_id, ret)
        return set(ret)

    # 获取节点的直接父节点
    def get_parent(self, node_id):
        node = self.nodes.get(node_id)
        parent = self.nodes.get(node.parent_id)
        return parent

    # 获取节点的所有父节点
    def get_offset_parent(self, node_id):
        parents = []
        parent = self.get_parent(node_id)
        while parent and parent.id != 0:
            parents.append(parent)
            parent = self.get_parent(parent.id)

        return parents

    # 假定用户必须存在
    def get_uname_biz_depart(self, uid):
        user_node = self.users[uid]
        dpmt_leaders = self.get_offset_parent(user_node.id)
        # 只定位第三级boss，即事业部leader
        big_dpmt_leader = [leader for leader in dpmt_leaders if leader.parent_id==2]

        node = big_dpmt_leader[0] if big_dpmt_leader else user_node
        return user_node.user.real_name, node.department

    @staticmethod
    def to_dict(node):
        d = {
            'id': node.id,
            'department': node.department,
            'user_id': node.user_id,
            'user_name': node.user_name,
            'is_leaf': node.is_leaf,
            'create_time': node.create_time
        }
        return d



