package system

import (
	"errors"
	"hongze/fms_api/models/base"
	"hongze/fms_api/models/system"
	"hongze/fms_api/utils"
)

//MenuList 只返回当前登录管理员有权限的菜单列表,不返回按钮
func MenuList(adminInfo *system.SysAdmin) (list []*system.MenuListItemResp, err error, errMsg string) {
	//查询有权限的菜单
	roleMenu := new(system.SysRoleMenu)
	cond := " rm.role_id = ?"
	pars := make([]interface{}, 0)
	pars = append(pars, adminInfo.RoleId)
	roleHasMenuList, err := roleMenu.GetMenuListByCondition(cond, pars)
	if err != nil {
		errMsg = "查询角色绑定的菜单出错"
		err = errors.New(errMsg + "Err:" + err.Error())
		return
	}
	var menuIds []int64
	for _, v := range roleHasMenuList {
		menuIds = append(menuIds, v.MenuId)
	}
	//查询其他级别的菜单列表
	menu := new(system.SysMenu)
	var condition string
	par := make([]interface{}, 0)
	condition = " menu_type = 0 and menu_id in ?"
	par = append(par, menuIds)
	orderStr := "sort asc, create_time, menu_id desc"
	//遍历排序好的菜单列表,,返回每个菜单结点,不包含按钮类型
	childList, err := menu.GetMenuListByCondition(condition, par, orderStr)
	if err != nil {
		return
	}
	list = make([]*system.MenuListItemResp, 0)
	for _, v := range childList {
		tmp := &system.MenuListItemResp{
			MenuId:       v.MenuId,
			ParentId:     v.ParentId,
			Name:         v.Name,
			Sort:         v.Sort,
			Path:         v.Path,
			PathName:     v.PathName,
			IconPath:     v.IconPath,
			Component:    v.Component,
			Hidden:       v.Hidden,
			HiddenLayout: v.HiddenLayout,
			Level:        v.Level,
			MenuType:     v.MenuType,
			ButtonCode:   v.ButtonCode,
			CreateTime:   utils.TimeTransferString(utils.FormatDateTime, v.CreateTime),
			ModifyTime:   utils.TimeTransferString(utils.FormatDateTime, v.ModifyTime),
			HasBind:      true,
			Children:     nil,
		}
		list = append(list, tmp)
	}
	//组装返回值
	list = getMenuTreeRecursive(list, 0)
	return
}

func AllMenuList(page base.IPage, req *system.MenuListReq) (count int64, list []*system.MenuListItemResp, err error, errMsg string) {
	//查询一级菜单的数量和列表
	//查询其他级别的菜单列表
	menu := new(system.SysMenu)
	var condition string
	pars := make([]interface{}, 0)
	var finalRootIds []int64
	if req.Name != "" {
		var rootIds []int64
		name := "%" + req.Name + "%"
		relationList, tErr := menu.GetMenuByName(name)
		if tErr != nil {
			errMsg = "查询菜单出错"
			err = errors.New(errMsg + "Err:" + tErr.Error())
			return
		}
		if len(relationList) == 0 { //查不到相关记录
			return
		}
		for _, v := range relationList {
			if v.RootId == 0 {
				rootIds = append(rootIds, v.MenuId)
			} else {
				rootIds = append(rootIds, v.RootId)
			}
		}
		//分页处理 查询最顶层结点,得到最终的顶层结点
		condition = "parent_id=0 and menu_id in ?"
		pars = append(pars, rootIds)
	} else {
		condition = " parent_id = 0"
	}

	count, rootList, err := menu.SelectPage(page, condition, pars)
	if err != nil {
		errMsg = "查询菜单列表出错"
		err = errors.New(errMsg + "Err:" + err.Error())
		return
	}
	if len(rootList) == 0 { //查不到相关记录
		return
	}
	for _, v := range rootList {
		finalRootIds = append(finalRootIds, v.MenuId)
	}
	fCondition := " 1=1"
	fPars := make([]interface{}, 0)
	if req.HideLevel3 == 1 {
		fCondition += " and level <=1 "
	}
	if req.HideButton == 1 {
		fCondition += " and menu_type = 0"
	}
	//查询所有该顶层节点下的子节点
	fCondition += " and (root_id in ? or menu_id in ?)"
	fPars = append(fPars, finalRootIds, finalRootIds)
	orderStr := "sort asc, create_time, menu_id desc"
	childList, err := menu.GetMenuListByCondition(fCondition, fPars, orderStr)
	if err != nil {
		errMsg = "查询菜单列表出错"
		err = errors.New(errMsg + "Err:" + err.Error())
		return
	}
	list = make([]*system.MenuListItemResp, 0)
	for _, v := range childList {
		tmp := &system.MenuListItemResp{
			MenuId:       v.MenuId,
			ParentId:     v.ParentId,
			Name:         v.Name,
			Sort:         v.Sort,
			Path:         v.Path,
			PathName:     v.PathName,
			IconPath:     v.IconPath,
			Component:    v.Component,
			Hidden:       v.Hidden,
			HiddenLayout: v.HiddenLayout,
			Level:        v.Level,
			MenuType:     v.MenuType,
			ButtonCode:   v.ButtonCode,
			CreateTime:   utils.TimeTransferString(utils.FormatDateTime, v.CreateTime),
			ModifyTime:   utils.TimeTransferString(utils.FormatDateTime, v.ModifyTime),
			Children:     nil,
		}
		list = append(list, tmp)
	}

	//组装返回值
	list = getMenuTreeRecursive(list, 0)
	return
}

func getMenuTreeRecursive(list []*system.MenuListItemResp, parentId int64) []*system.MenuListItemResp {
	res := make([]*system.MenuListItemResp, 0)
	for _, v := range list {
		if v.ParentId == parentId {
			v.Children = getMenuTreeRecursive(list, v.MenuId)
			res = append(res, v)
		}
	}
	return res
}

//ButtonList 只返回当前登录管理员有权限的按钮列表,不返回按钮
func ButtonList(adminInfo *system.SysAdmin, req *system.MenuShortListItem) (list []*system.SysMenu, err error, errMsg string) {
	//查询有权限的菜单
	roleMenu := new(system.SysRoleMenu)
	cond := " rm.role_id = ?"
	pars := make([]interface{}, 0)
	pars = append(pars, adminInfo.RoleId)
	roleHasMenuList, err := roleMenu.GetMenuListByCondition(cond, pars)
	if err != nil {
		errMsg = "查询角色绑定的菜单出错"
		err = errors.New(errMsg + "Err:" + err.Error())
		return
	}
	var menuIds []int64
	for _, v := range roleHasMenuList {
		menuIds = append(menuIds, v.MenuId)
	}
	//查询其他级别的菜单列表
	menu := new(system.SysMenu)
	var condition string
	par := make([]interface{}, 0)
	condition = " menu_type = 1 and menu_id in ?"
	par = append(par, menuIds)
	if req.MenuId > 0 {
		condition += " and parent_id = ?"
		par = append(par, req.MenuId)
	}
	//遍历排序好的菜单列表,,返回每个菜单结点,不包含按钮类型
	list, err = menu.GetMenuListByCondition(condition, par, "")
	if err != nil {
		errMsg = "查询菜单按钮列表出错"
		err = errors.New(errMsg + "Err:" + err.Error())
		return
	}
	return
}

// DeleteMenu 删除菜单,连同删除子菜单
func DeleteMenu(req *system.MenuShortListItem) (err error, errMsg string) {
	menu := new(system.SysMenu)
	//找出当前层级,如果当前是最顶层,则批量删除和顶层相关的所有部门
	menuInfo, err := menu.GetMenuByMenuId(req.MenuId)
	if err != nil {
		if err == utils.ErrNoRow {
			errMsg = "菜单不存在或者已删除"
			err = errors.New(errMsg + "Err:" + err.Error())
			return
		}
		errMsg = "查询菜单出错"
		err = errors.New(errMsg + "Err:" + err.Error())
		return
	}
	if menuInfo.ParentId > 0 {
		//如果不是最顶层,则构建树形图,得到需要删除的menu_id
		//查询所有该顶层节点下的子节点
		fCondition := "root_id = ? or menu_id = ?"
		fPars := make([]interface{}, 0)
		fPars = append(fPars, menuInfo.RootId, menuInfo.RootId)
		orderStr := "level desc"
		childList, tErr := menu.GetMenuListByCondition(fCondition, fPars, orderStr)
		if tErr != nil {
			errMsg = "查询菜单列表出错"
			err = errors.New(errMsg + "Err:" + tErr.Error())
			return
		}

		menuIdMap := make(map[int64][]int64)
		for _, v := range childList {
			menuIdMap[v.MenuId] = append(menuIdMap[v.MenuId], v.MenuId)
			if v.ParentId > 0 {
				menuIdMap[v.ParentId] = append(menuIdMap[v.ParentId], menuIdMap[v.MenuId]...)
			}
		}
		cond := "menu_id in ?"
		pars := make([]interface{}, 0)
		pars = append(pars, menuIdMap[menuInfo.MenuId])
		err = menu.DeleteByCondition(cond, pars)
	} else {
		//如果是最顶层,则删除所有相关的menu_id
		cond := "menu_id = ? or root_id = ?"
		pars := make([]interface{}, 0)
		pars = append(pars, menuInfo.MenuId, menuInfo.MenuId)
		err = menu.DeleteByCondition(cond, pars)
	}
	return
}