'''
Author: your name
Date: 2021-07-27 16:19:06
LastEditTime: 2021-07-28 09:23:23
LastEditors: your name
Description: In User Settings Edit
FilePath: \evm-store\tools\build_out\models\menu.py
'''
#!/usr/bin/env python
# -*- coding: utf_8 -*-

import copy
from application.app import db, ma
from .base import PrimaryModel 
from marshmallow import Schema, fields, INCLUDE, EXCLUDE

class MenuModel(PrimaryModel):
    __tablename__ = 'evm_menu'

    name = db.Column(db.String(100), nullable = True)
    parent_id = db.Column(db.Integer, default=0, nullable = True)
    path = db.Column(db.String(100), nullable = True)
    disabled = db.Column(db.Boolean, nullable = True, default = False)
    fixed = db.Column(db.Boolean, nullable = False, default = False)
    has_children = db.Column(db.Boolean, nullable = True, default = False)
    icon = db.Column(db.String(100), nullable = True, default = '')

    # __table_args__ = (
    #     db.Index('idx_xxx', 'xxx', mysql_using='btree'),
    # )

    def __init__(self, name, parentId, path, disabled=False, fixed=False, hasChildren=False, icon=''):
        self.name = name
        self.parent_id = parentId
        self.path = path
        self.disabled = disabled
        self.fixed = fixed
        self.has_children = hasChildren
        self.icon = icon

    def __repr__(self):
        return '<MenuModel %r>' % (self.name)

    def to_dict(self):
        return {
            'id': self.id,
            'name': self.name,
            'parentId': self.parent_id,
            'path': self.path,
            'disabled': self.disabled,
            'fixed': self.fixed,
            'hasChildren': self.has_children,
            'icon': self.icon,
            'sort': self.sort,
            'remark': self.remark,
            'deleted': self.is_delete,
            'createUser': self.create_by,
            'updateUser': self.update_by,
            'createTime': self.create_at.strftime("%Y-%m-%d %H:%M:%S") if self.create_at else None,
            "updateTime": self.update_at.strftime("%Y-%m-%d %H:%M:%S") if self.update_at else None,
        }

class TreeMenuNode:
    """树形菜单节点"""

    def __init__(self, pk, title, code, icon_class, url, order, child, parent):
        self.pk = pk
        self.title = title
        self.code = code
        self.icon_class = icon_class
        self.url = url
        self.order = order
        self.child = child
        self.parent = parent

    def count(self):
        if not self.child:
            return 0
        return len(self.child)


class HandleTreeMenu:
    """处理树形侧边栏菜单"""

    def __init__(self, menus):
        self.menus = menus
        self.tree_menu = []

    def __iter__(self):
        if self.tree_menu:
            return iter(self.tree_menu)
        return iter([])

    @staticmethod
    def get_complete_menu_structure(_menu_list):
        """得到完整的菜单结构"""
        menu_list = copy.copy(_menu_list)
        for menu in menu_list:
            if menu.parent and menu.parent not in menu_list:
                menu_list.append(menu.parent)
                menu_list.extend(HandleTreeMenu.get_complete_menu_structure(menu_list))
        return menu_list

    def convert_to_tree(self):
        """转换BaseQuery为MenuTree结构"""
        complete_menu = HandleTreeMenu.get_complete_menu_structure(self.menus)
        # 所有顶级菜单
        top_menu = [menu for menu in complete_menu if not menu.parent]
        for menu in top_menu:
            current_menu = TreeMenuNode(menu.pk, menu.title, menu.code, menu.icon_class, menu.url, menu.order, [], None)
            current_menu = self._recursive_menu(menu, current_menu)
            self.tree_menu.append(current_menu)

    def _recursive_menu(self, base_menu, base_tree_menu):
        """由上往下递归菜单得到所有菜单并转换为TreeMenuNode格式"""
        complete_menu = HandleTreeMenu.get_complete_menu_structure(self.menus)
        child_menu = [menu for menu in complete_menu if menu.parent == base_menu]  # 父节点为base_menu的子节点

        for menu in child_menu:
            current_menu = TreeMenuNode(menu.pk, menu.title, menu.code, menu.icon_class, menu.url, menu.order, [], base_tree_menu)
            current_menu = self._recursive_menu(menu, current_menu)
            base_tree_menu.child.append(current_menu)
        return base_tree_menu

if __name__ == '__main__':
    # 使用方法
    menus = MenuModel.query.all()  # 这里是直接在数据库里面查询出来的, 用户私有权限表
    tree_menu = HandleTreeMenu(menus)# 创建一个对象
    tree_menu.convert_to_tree() # 执行转换方法
    print(tree_menu.tree_menu) # 得到已经转换的菜单