from app.Model.Model import FlMenu
from app.Model.Access import Access
from sqlalchemy_serializer import SerializerMixin
from app.Vendor.Decorator import classTransaction
from sqlalchemy.orm import  relationship, foreign, remote
from app import dBSession
import math

class Menu(FlMenu, SerializerMixin):
    
    access = relationship('Access', uselist=True, primaryjoin=foreign(FlMenu.id) == remote(Access.menu_id))

    """ 
        列表
        @param set filters 查询条件
        @param obj order 排序
        @param tuple field 字段
        @param int offset 偏移量
        @param int limit 取多少条
        @return dict
    """
    def getList(self, filters, order, field=(), offset = 0, limit = 15):
        res = {}
        res['page'] ={}
        res['page']['count'] = dBSession.query(Menu).filter(*filters).count()
        res['list'] = []
        res['page']['total_page'] = self.get_page_number(res['page']['count'], limit)
        res['page']['current_page'] = offset
        if offset != 0:
            offset = (offset - 1) * limit

        if res['page']['count'] > 0:
            res['list'] = dBSession.query(Menu).filter(*filters)
            res['list'] = res['list'].order_by(order).offset(offset).limit(limit).all()
        if not field:
            res['list'] = [c.to_dict() for c in res['list']]
        else:
            res['list'] = [c.to_dict(only=field) for c in res['list']]
        return res

    """
        查询全部
        @param set filters 查询条件
        @param obj order 排序
        @param tuple field 字段
        @param int $limit 取多少条
        @return dict
    """
    def getAll(self, filters, order, field = (), limit = 0):
        res = dBSession.query(Menu).filter(*filters)
        if limit != 0:
            res = res.order_by(order).limit(limit).all()
        else:
            res = res.order_by(order).all()
        if not field:
            res = [c.to_dict() for c in res]
        else:
            res = [c.to_dict(only=field) for c in res]
        return res

    
    """
        获取一条
        @param set filters 查询条件
        @param obj order 排序
        @param tuple field 字段
        @return dict
    """
    def getOne(self, filters, order, field = ()):
        res = dBSession.query(Menu).filter(*filters)
        res = res.order_by(order).first()
        if res == None:
            return None
        if not field:
            res = res.to_dict()
        else:
           res = res.to_dict(only=field) 
        return res
  
    """
        添加
        @param obj data 数据
        @return bool
    """
    @classTransaction
    def add(self, data):
        menu = Menu(**data)
        dBSession.add(menu)
        dBSession.flush()
        return menu.id

    
    """
        修改
        @param dict data 数据
        @param set filters 条件
        @return bool
    """
    @classTransaction
    def edit(self, data, filters):
        dBSession.query(Menu).filter(*filters).update(data, synchronize_session=False)
        return True
    
    """
        删除
        @paramset filters 条件
        @return bool
    """
    @classTransaction
    def delete(self, filters):
        dBSession.query(Menu).filter(*filters).delete()
        return True
    
    """
        统计数量
        @param set filters 条件
        @param obj field 字段
        @return int
    """  
    def getCount(self, filters, field = None):
        if field == None:
            return dBSession.query(Menu).filter(*filters).count()
        else:
            return dBSession.query(Menu).filter(*filters).count(field)

    @staticmethod
    def get_page_number(count, page_size):
        count = float(count)
        page_size = abs(int(page_size))
        if page_size != 0:
            total_page = math.ceil(count / page_size)
        else:
            total_page = math.ceil(count / 5)
        return total_page

    #获取后台管理员所具有权限的菜单列表
    def getPermissionsMenu(self, role_id, parent_id=0, pad=0):
        res = []
        filters = {
            Access.role_id == role_id,
            Menu.parent_id == parent_id,
            Menu.status    == 0
        }
        menu = dBSession.query(Menu).filter(*filters).join(Menu.access).order_by(Menu.id.asc()).all()
        menu = [c.to_dict() for c in menu]
        if menu:
            for row in menu:
                row['deep'] = pad	
                PermissionsMenu = self.getPermissionsMenu( role_id, row['id'], pad+1)
                if PermissionsMenu:
                    row['child'] = PermissionsMenu	
                res.append(row)
        return res

    """
      将列表生成树形结构
      @param int parent_id 父级ID
      @param int deep 层级
      @return list
    """
    def get_category(self, parent_id=0, deep=0):
        arr= []
        filters = {
            Menu.parent_id == parent_id
        }
        cats = Menu().getAll(filters, Menu.listorder.asc())
        if cats:
            for row in cats:
                row['deep'] = deep
                #如果子级不为空
                child = self.get_category(row["id"], deep+1)
                if child:
                    row['child'] = child
                arr.append(row)
        return arr
    
    """
      树形结构转成列表
      @param array listData 数据
      @param int parent_id 父级ID
      @param list temp 空模板
      @return list
    """
    def category_tree(self, listData, parent_id=0, temp=[]):
        if listData:	
            for v in listData:
                data = {
                    "id":v['id'],
                    "deep":v['deep'],
                    "name":v['name'],
                    "parent_id":v['parent_id']
                }
                temp.append(data)
                if 'child' in v.keys():
                    self.category_tree(v['child'], v['parent_id'], temp)		
        return temp
    
	
        