package system

import (
	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator/v10"
	"hongze/fms_api/controller/resp"
	"hongze/fms_api/global"
	"hongze/fms_api/models/base"
	"hongze/fms_api/models/system"
	systemService "hongze/fms_api/services/system"
	"hongze/fms_api/utils"
)

type SysMenuController struct {
}

func (m *SysMenuController) Add(c *gin.Context) {
	req := new(system.SysMenuAddReq)
	err := c.ShouldBind(&req)
	if err != nil {
		errs, ok := err.(validator.ValidationErrors)
		if !ok {
			resp.FailData("参数解析失败", "Err:"+err.Error(), c)
			return
		}
		resp.FailData("参数解析失败", errs.Translate(global.Trans), c)
		return
	}
	item := new(system.SysMenu)
	item.ParentId = req.ParentId
	item.Name = req.Name
	item.Sort = req.Sort
	item.Hidden = req.Hidden
	item.HiddenLayout = req.HiddenLayout
	item.Component = req.Component
	item.IconPath = req.IconPath
	item.MenuType = req.MenuType
	item.Path = req.Path
	item.PathName = req.PathName
	item.ButtonCode = req.ButtonCode
	//添加校验,如果是按钮类型,则父级菜单不允许为0
	if req.MenuType == 1 {
		if req.ParentId == 0 {
			resp.Fail("请设置按钮的父级菜单", c)
			return
		}
		if req.ButtonCode == "" {
			resp.Fail("请设置按钮标识", c)
			return
		}
	}
	if req.ParentId > 0 {
		parentInfo, tErr := item.GetMenuByMenuId(req.ParentId)
		if tErr != nil {
			if tErr == utils.ErrNoRow {
				resp.Fail("上级菜单不存在", c)
				return
			}
			resp.FailMsg("查询上级菜单出错", tErr.Error(), c)
			return
		}
		// 按钮只能挂在二级菜单下面
		/*if req.MenuType == 1 && parentInfo.ParentId == 0{
			resp.Fail("按钮只允许挂在二级菜单下面", c)
			return
		}*/
		if parentInfo.RootId == 0 {
			item.RootId = parentInfo.MenuId
		} else {
			item.RootId = parentInfo.RootId
		}

		item.Level = parentInfo.Level + 1
		if item.Level >= 3 {
			resp.Fail("不允许设置四级菜单", c)
			return
		}
	}
	// 判断是否存在相同的菜单名称
	cond := "parent_id = ? and name = ? and menu_type=?"
	pars := make([]interface{}, 0)
	pars = append(pars, item.ParentId, item.Name, item.MenuType)
	exitList, err := item.GetMenuListByCondition(cond, pars, "")
	if err != nil {
		resp.FailMsg("查询菜单出错", err.Error(), c)
		return
	}
	if len(exitList) > 0 {
		resp.Fail("该菜单名称已存在", c)
		return
	}
	err = item.Add()
	if err != nil {
		resp.FailMsg("保存失败", "保存失败,Err:"+err.Error(), c)
		return
	}
	resp.Ok("保存成功", c)
}

func (m *SysMenuController) List(c *gin.Context) {
	//获取jwt数据失败
	claims, _ := c.Get("adminInfo")
	adminInfo := claims.(*system.SysAdmin)
	if adminInfo.RoleId <= 0 {
		resp.Ok("获取成功", c)
		return
	}
	list, err, errMsg := systemService.MenuList(adminInfo)
	if err != nil {
		resp.FailMsg(errMsg, err.Error(), c)
		return
	}
	resultPage := &base.BaseData{
		List: list,
	}
	resp.OkData("获取成功", resultPage, c)
}

func (m *SysMenuController) AllList(c *gin.Context) {
	req := new(system.MenuListReq)
	err := c.BindQuery(&req)
	if err != nil {
		resp.FailData("参数解析失败", "Err:"+err.Error(), c)
		return
	}
	page := new(base.Page)
	page.SetPageSize(req.PageSize)
	page.SetCurrent(req.Current)

	count, list, err, _ := systemService.AllMenuList(page, req)
	if err != nil {
		resp.FailMsg("获取失败", "获取失败,Err:"+err.Error(), c)
		return
	}
	page.SetTotal(count)
	resultPage := &base.BaseData{
		Page: page,
		List: list,
	}
	resp.OkData("获取成功", resultPage, c)
}

func (m *SysMenuController) ButtonList(c *gin.Context) {
	req := new(system.MenuShortListItem)
	err := c.BindQuery(&req)
	if err != nil {
		resp.FailData("参数解析失败", "Err:"+err.Error(), c)
		return
	}
	claims, _ := c.Get("adminInfo")
	adminInfo := claims.(*system.SysAdmin)
	if adminInfo.RoleId <= 0 {
		resp.Ok("获取成功", c)
		return
	}
	list, err, errMsg := systemService.ButtonList(adminInfo, req)
	if err != nil {
		resp.FailMsg(errMsg, err.Error(), c)
		return
	}
	buttonList := make([]*system.SysMenuButtonResp, 0)
	for _, v := range list {
		tmp := new(system.SysMenuButtonResp)
		tmp.MenuId = v.MenuId
		tmp.ParentId = v.ParentId
		tmp.MenuType = v.MenuType
		tmp.Name = v.Name
		tmp.ButtonCode = v.ButtonCode
		buttonList = append(buttonList, tmp)
	}

	resultPage := &base.BaseOnlyData{
		List: buttonList,
	}
	resp.OkData("获取成功", resultPage, c)
}

func (m *SysMenuController) Edit(c *gin.Context) {
	req := new(system.SysMenuEditReq)
	err := c.ShouldBind(&req)
	if err != nil {
		errs, ok := err.(validator.ValidationErrors)
		if !ok {
			resp.FailData("参数解析失败", "Err:"+err.Error(), c)
			return
		}
		resp.FailData("参数解析失败", errs.Translate(global.Trans), c)
		return
	}
	menu := new(system.SysMenu)
	item, err := menu.GetMenuByMenuId(req.MenuId)
	if err != nil {
		if err == utils.ErrNoRow {
			resp.Fail("该菜单不存在", c)
			return
		}
		resp.FailMsg("查询菜单出错", err.Error(), c)
		return
	}
	item.ParentId = req.ParentId
	item.Name = req.Name
	item.Sort = req.Sort
	item.Hidden = req.Hidden
	item.HiddenLayout = req.HiddenLayout
	item.Component = req.Component
	item.IconPath = req.IconPath
	item.MenuType = req.MenuType
	item.Path = req.Path
	item.PathName = req.PathName
	item.ButtonCode = req.ButtonCode

	updateCols := make([]string, 0)
	updateCols = append(updateCols, "parent_id", "name", "sort", "component", "icon_path", "menu_type", "path", "path_name", "button_code", "root_id", "level", "hidden", "hidden_layout")
	//添加校验,如果是按钮类型,则父级菜单不允许为0
	if req.MenuType == 1 {
		if req.ParentId == 0 {
			resp.Fail("请设置按钮的父级菜单", c)
			return
		}
		if req.ButtonCode == "" {
			resp.Fail("请设置按钮标识", c)
			return
		}
	}
	if req.ParentId > 0 {
		parentInfo, tErr := item.GetMenuByMenuId(req.ParentId)
		if tErr != nil {
			if tErr == utils.ErrNoRow {
				resp.Fail("上级菜单不存在", c)
				return
			}
			resp.FailMsg("查询上级菜单出错", tErr.Error(), c)
			return
		}
		// 按钮只能挂在二级菜单下面
		/*if req.MenuType == 1 && parentInfo.ParentId == 0{
			resp.Fail("按钮只允许挂在二级菜单下面", c)
			return
		}*/
		if parentInfo.RootId == 0 {
			item.RootId = parentInfo.MenuId
		} else {
			item.RootId = parentInfo.RootId
		}
		item.Level = parentInfo.Level + 1
		if item.Level >= 3 {
			resp.Fail("不允许设置四级菜单", c)
			return
		}
	} else if req.ParentId == 0 {
		item.RootId = 0
		item.Level = 0
	}
	// 判断是否存在相同的菜单名称
	if req.Name != item.Name {
		cond := "parent_id = ? and name = ? and menu_type=?"
		pars := make([]interface{}, 0)
		pars = append(pars, item.ParentId, item.Name, item.MenuType)
		exitList, err := item.GetMenuListByCondition(cond, pars, "")
		if err != nil {
			resp.FailMsg("查询菜单出错", err.Error(), c)
			return
		}
		if len(exitList) > 0 {
			resp.Fail("该菜单名称已存在", c)
			return
		}
	}

	err = item.Update(updateCols)
	if err != nil {
		resp.FailMsg("保存失败", "保存失败,Err:"+err.Error(), c)
		return
	}
	resp.Ok("保存成功", c)
}

// Delete 删除菜单
func (m *SysMenuController) Delete(c *gin.Context) {
	req := new(system.MenuShortListItem)
	err := c.ShouldBind(&req)
	if err != nil {
		resp.FailData("参数解析失败", "Err:"+err.Error(), c)
		return
	}
	if req.MenuId <= 0 {
		resp.Fail("请选择要删除的菜单", c)
		return
	}
	err, errMsg := systemService.DeleteMenu(req)
	if err != nil {
		resp.FailMsg(errMsg, err.Error(), c)
		return
	}
	resp.Ok("删除成功", c)
}