package controllers

import (
	"encoding/json"
	"eta/eta_api/models"
	"eta/eta_api/models/system"
	"eta/eta_api/services"
	"eta/eta_api/utils"
	"fmt"
	"github.com/rdlucklib/rdluck_tools/paging"
	"strconv"
	"strings"
	"time"
)

type SysRoleController struct {
	BaseAuthController
}

// @Title 新增角色
// @Description 新增角色接口
// @Param	request	body system.SysRoleAddReq true "type json string"
// @Success 200 新增成功
// @router /role/add [post]
func (this *SysRoleController) Add() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	var req system.SysRoleAddReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}
	if req.RoleName == "" {
		br.Msg = "角色名称不能为空"
		return
	}
	count, err := system.GetSysRoleCount(req.RoleName)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = "获取数据失败"
		br.ErrMsg = "获取数据失败,Err:" + err.Error()
		return
	}
	if count > 0 {
		br.Msg = "角色已存在,请重新输入"
		return
	}
	item := new(system.SysRole)
	item.RoleName = req.RoleName
	item.RoleType = req.RoleType
	item.RoleTypeCode = services.GetRoleTypeCode(req.RoleType)
	item.CreateTime = time.Now()
	item.ModifyTime = time.Now()
	roleId, err := system.AddSysRole(item)
	if err != nil {
		br.Msg = "新增失败"
		br.ErrMsg = "新增失败,Err:" + err.Error()
		return
	}

	// 同步角色缓存
	if utils.BusinessCode == utils.BusinessCodeRelease {
		var syncData system.SyncRoleData
		syncData.Source = utils.SOURCE_ETA_FLAG
		syncData.RoleId = int(roleId)
		_ = utils.Rc.LPush(utils.CACHE_SYNC_ROLE, syncData)
	}

	br.Ret = 200
	br.Success = true
	br.Msg = "新增成功"
}

// @Title 修改角色
// @Description  修改角色接口
// @Param	request	body system.SysRoleEditReq true "type json string"
// @Success 200 修改成功
// @router /role/edit [post]
func (this *SysRoleController) Edit() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	var req system.SysRoleEditReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}
	if req.RoleId <= 0 {
		br.Msg = "参数错误"
		br.ErrMsg = "参数错误,GroupId 小于等于0 "
		return
	}
	if req.RoleName == "" {
		br.Msg = "分组名称不能为空"
		return
	}

	item, e := system.GetSysRoleById(req.RoleId)
	if e != nil {
		if e.Error() != utils.ErrNoRow() {
			br.Msg = "操作失败"
			br.ErrMsg = "获取角色失败, Err: " + e.Error()
			return
		}
		br.Msg = "角色不存在, 请刷新页面"
		return
	}
	exists, e := system.GetSysRoleByName(req.RoleName)
	if e != nil && e.Error() != utils.ErrNoRow() {
		br.Msg = "操作失败"
		br.ErrMsg = "获取重名角色失败, Err: " + e.Error()
		return
	}
	if exists != nil && exists.RoleId != item.RoleId {
		br.Msg = "名称已存在,请重新输入"
		return
	}
	roleTypeCode := services.GetRoleTypeCode(req.RoleType)
	e = system.ModifySysRole(req.RoleName, req.RoleType, roleTypeCode, req.RoleId)
	if e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "更新角色信息失败, Err: " + e.Error()
		return
	}

	// 同步角色缓存
	if utils.BusinessCode == utils.BusinessCodeRelease {
		var syncData system.SyncRoleData
		syncData.Source = utils.SOURCE_ETA_FLAG
		syncData.RoleId = item.RoleId
		_ = utils.Rc.LPush(utils.CACHE_SYNC_ROLE, syncData)
	}

	br.Ret = 200
	br.Success = true
	br.IsAddLog = true
	br.Msg = "修改成功"
}

// @Title 删除角色
// @Description 删除角色接口
// @Param	request	body system.SysRoleDeleteReq true "type json string"
// @Success 200 删除成功
// @router /role/delete [post]
func (this *SysRoleController) Delete() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	var req system.SysRoleDeleteReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}
	if req.RoleId <= 0 {
		br.Msg = "参数错误"
		br.ErrMsg = "参数错误,GroupId 小于等于0 "
		return
	}

	role, e := system.GetSysRoleById(req.RoleId)
	if e != nil {
		if err.Error() == utils.ErrNoRow() {
			br.Msg = "角色不存在, 请刷新页面"
			return
		}
		br.Msg = "删除失败"
		br.ErrMsg = "获取角色信息失败, Err: " + e.Error()
		return
	}

	err = system.DeleteSysRole(req.RoleId)
	if err != nil {
		br.Msg = "删除失败"
		br.ErrMsg = "删除失败,Err:" + err.Error()
		return
	}

	// 同步角色缓存
	if utils.BusinessCode == utils.BusinessCodeRelease {
		var syncData system.SyncRoleData
		syncData.Source = utils.SOURCE_ETA_FLAG
		syncData.RoleId = role.RoleId
		_ = utils.Rc.LPush(utils.CACHE_SYNC_ROLE, syncData)
	}

	br.Ret = 200
	br.Success = true
	br.IsAddLog = true
	br.Msg = "删除成功"
}

// @Title 获取角色列表
// @Description 获取角色列表接口
// @Param   PageSize   query   int  true       "每页数据条数"
// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
// @Param   KeyWord   query   string  true       "搜索关键词"
// @Success 200 {object} system.SysRoleListResp
// @router /role/list [get]
func (this *SysRoleController) ListSysRole() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		return
	}
	pageSize, _ := this.GetInt("PageSize")
	currentIndex, _ := this.GetInt("CurrentIndex")
	keyWord := this.GetString("KeyWord")

	var startSize int
	if pageSize <= 0 {
		pageSize = utils.PageSize20
	}
	if currentIndex <= 0 {
		currentIndex = 1
	}
	startSize = utils.StartIndex(currentIndex, pageSize)

	var condition string
	var pars []interface{}

	if keyWord != "" {
		condition += ` AND role_name LIKE '%` + keyWord + `%'  `
	}

	total, err := system.GetSysRoleListCount(condition, pars)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取失败,Err:" + err.Error()
		return
	}

	list, err := system.GetSysRoleList(condition, pars, startSize, pageSize)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取失败,Err:" + err.Error()
		return
	}
	page := paging.GetPaging(currentIndex, pageSize, total)
	resp := new(system.SysRoleListResp)
	resp.List = list
	resp.Paging = page
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = resp
}

// SysRoleMenusList
// @Title 角色设置权限-菜单列表-CRM14.1弃用
// @Description 角色设置权限-菜单列表
// @Param   RoleId   query   int  true       "角色Id"
// @Success 200 {object} system.SysRoleListResp
// @router /role/menu/list [get]
func (this *SysRoleController) SysRoleMenusList() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	roleId, err := this.GetInt("RoleId")
	if err != nil {
		br.Msg = "获取角色失败"
		br.ErrMsg = "获取角色失败,Err:" + err.Error()
		return
	}
	fmt.Println("roleId", roleId)
	list := make([]*system.RoleMenuList, 0)

	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		return
	}
	list, err = system.GetRoleMenuList()
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取失败,Err:" + err.Error()
		return
	}
	lenList := len(list)
	for i := 0; i < lenList; i++ {
		item := list[i]
		child, err := system.GetRoleMenuByParentId(item.MenuId)
		if err != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取子菜单数据失败,Err:" + err.Error()
			return
		}
		list[i].Child = child

		checkList := make([]int, 0)
		if roleId > 0 {
			checkItem, err := system.GetCheckListRoleMenu(roleId, item.MenuId)
			if err != nil {
				br.Msg = "获取失败"
				br.ErrMsg = "获取选择数据失败,Err:" + err.Error()
				return
			}
			for _, v := range checkItem {
				checkList = append(checkList, v.MenuId)
			}
		}
		list[i].CheckList = checkList
	}
	resp := new(system.RoleMenuListResp)
	resp.List = list
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = resp
}

// SysRoleMenusAdd
// @Title 角色设置权限-CRM14.1弃用
// @Description 角色设置权限
// @Param	request	body system.RoleMenusAddReq true "type json string"
// @Success 200 {object} system.SysRoleListResp
// @router /role/menu/add [post]
func (this *SysRoleController) SysRoleMenusAdd() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	var req system.RoleMenusAddReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}
	roleId := req.RoleId
	if roleId <= 0 {
		br.Msg = "参数错误"
		br.ErrMsg = "参数错误,RoleId 小于等于0 "
		return
	}
	if req.MenuIdStr == "" {
		br.Msg = "请选择菜单"
		br.ErrMsg = "请选择菜单,MenuIdStr IS Empty "
		return
	}
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		return
	}
	err = system.DeleteRoleMenuByRoleId(roleId)
	if err != nil {
		br.Msg = "设置失败"
		br.ErrMsg = "清空原有设置失败,Err:" + err.Error()
		return
	}
	menuArr := strings.Split(req.MenuIdStr, ",")
	for _, v := range menuArr {
		menuId, err := strconv.Atoi(v)
		if err != nil {
			br.Msg = "设置失败"
			br.ErrMsg = "menuId 解析失败,Err:" + err.Error()
			return
		}
		item := new(system.SysRoleMenu)
		item.RoleId = roleId
		item.MenuId = menuId
		_, err = system.AddSysRoleMenu(item)
		if err != nil {
			br.Msg = "设置失败"
			br.ErrMsg = "新增设置失败,Err:" + err.Error()
			return
		}
	}
	if req.MenuButtonIdStr != "" {
		err = system.DeleteSysRoleButton(roleId)
		if err != nil {
			br.Msg = "设置失败"
			br.ErrMsg = "删除已设置数据失败,Err:" + err.Error()
			return
		}
		buttonMap := make(map[string]string)
		buttonArr := strings.Split(req.MenuButtonIdStr, ",")
		for _, v := range buttonArr {
			if _, ok := buttonMap[v]; !ok {
				buttonId, err := strconv.Atoi(v)
				count, err := system.GetSysRoleButtonCount(roleId, buttonId)
				if err != nil {
					br.Msg = "判断设置失败存在失败"
					br.ErrMsg = "判断设置失败存在失败,Err:" + err.Error()
					return
				}
				if count <= 0 {
					button := new(system.SysRoleButton)
					button.RoleId = roleId
					button.MenuButtonId = buttonId
					button.CreateTime = time.Now()
					_, err = system.AddSysRoleButton(button)
					if err != nil {
						br.Msg = "设置失败"
						br.ErrMsg = "按钮权限设置失败,Err:" + err.Error()
						return
					}
				}
			}
			buttonMap[v] = v
		}
	} else {
		err = system.DeleteSysRoleButton(roleId)
		if err != nil {
			br.Msg = "设置失败"
			br.ErrMsg = "删除已设置数据失败,Err:" + err.Error()
			return
		}
	}
	br.Ret = 200
	br.Success = true
	br.IsAddLog = true
	br.Msg = "设置成功"
}

// @Title 获取所有角色
// @Description 获取所有角色
// @Success 200 {object} system.SysRoleListResp
// @router /role/all [get]
func (this *SysRoleController) AllSysRole() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		return
	}
	levelFlag := false
	roleLevel := this.GetString("RoleLevel")
	if roleLevel != "" {
		levelFlag = true
	}
	list, err := system.GetSysRoleAll(levelFlag)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取失败,Err:" + err.Error()
		return
	}
	resp := new(system.SysRoleAllResp)
	resp.List = list
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = resp
}

// SysRoleMenuAuthList
// @Title 角色设置权限-菜单列表
// @Description 角色设置权限-菜单列表
// @Param   RoleId   query   int  true       "角色Id"
// @Success 200 {object} system.SysRoleListResp
// @router /role/menu/auth_list [get]
func (this *SysRoleController) SysRoleMenuAuthList() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		return
	}
	resp := new(system.SysMenuListResp)
	resp.ChoiceList = make([]int, 0)
	resp.HalfChoiceList = make([]int, 0)
	resp.List = make([]*system.SysMenuItem, 0)

	// 角色勾选的权限
	roleId, _ := this.GetInt("RoleId", 0)
	if roleId > 0 {
		relates, e := system.GetSysRoleMenuByRoleId(roleId)
		if e != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取角色关联菜单失败, Err: " + e.Error()
			return
		}
		for _, r := range relates {
			if r.Type == 1 {
				resp.HalfChoiceList = append(resp.HalfChoiceList, r.MenuId)
				continue
			}
			resp.ChoiceList = append(resp.ChoiceList, r.MenuId)
		}
	}

	order := `sort ASC, create_time DESC, menu_id DESC`
	list, e := system.GetSysMenuItemsByCondition(` AND hidden = 0`, make([]interface{}, 0), []string{}, order)
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取菜单列表失败, Err: " + e.Error()
		return
	}

	items := make([]*system.SysMenuItem, 0)
	for _, v := range list {
		t := &system.SysMenuItem{
			MenuId:     v.MenuId,
			ParentId:   v.ParentId,
			Name:       v.Name,
			Sort:       v.Sort,
			Path:       v.Path,
			IconPath:   v.IconPath,
			Component:  v.Component,
			Hidden:     v.Hidden,
			MenuType:   v.MenuType,
			ButtonCode: v.ButtonCode,
			Children:   make([]*system.SysMenuItem, 0),
		}
		items = append(items, t)
	}

	// 递归返回树形结构
	items = services.GetMenuTreeRecursive(items, 0)

	resp.List = items
	br.Data = resp
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
}

// SysRoleMenuAuthSave
// @Title 角色设置权限-保存
// @Description 角色设置权限-保存
// @Param	request	body RoleMenusSaveReq true "type json string"
// @Success 200 {object} system.SysRoleListResp
// @router /role/menu/auth_save [post]
func (this *SysRoleController) SysRoleMenuAuthSave() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}

	type RoleMenusSaveReq struct {
		RoleId      int   `description:"角色ID"`
		MenuIds     []int `description:"菜单IDs"`
		HalfMenuIds []int `description:"半选菜单IDs-仅供前端回显用的"`
	}
	var req RoleMenusSaveReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}
	if req.RoleId <= 0 {
		br.Msg = "参数有误"
		return
	}
	if len(req.MenuIds) == 0 {
		br.Msg = "请选择菜单"
		return
	}

	items := make([]*system.SysRoleMenu, 0)
	for _, v := range req.MenuIds {
		t := new(system.SysRoleMenu)
		t.MenuId = v
		t.RoleId = req.RoleId
		items = append(items, t)
	}
	for _, v := range req.HalfMenuIds {
		t := new(system.SysRoleMenu)
		t.MenuId = v
		t.Type = 1
		t.RoleId = req.RoleId
		items = append(items, t)
	}
	if e := system.CreateMultiSysRoleMenu(req.RoleId, items); e != nil {
		br.Msg = "保存失败"
		br.ErrMsg = "保存角色菜单权限失败, Err: " + e.Error()
		return
	}

	br.Ret = 200
	br.Success = true
	br.Msg = "设置成功"
}

// ButtonList
// @Title 角色-按钮权限列表
// @Description 角色-按钮权限列表
// @Param   RoleId   query   int  true       "角色Id"
// @Success 200 {object} system.SysRoleListResp
// @router /role/menu/buttons [get]
func (this *SysRoleController) ButtonList() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}

	roleId := sysUser.RoleId
	list, e := system.GetMenuButtonsByRoleId(roleId)
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取角色按钮权限失败, Err: " + e.Error()
		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)
	}

	br.Data = buttonList
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
}

// SystemConfig
// @Title 系统配置列表
// @Description 系统配置列表
// @Success 200 {object} []system.BusinessConf
// @router /config [get]
func (this *SysRoleController) SystemConfig() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}
	list := make([]system.BusinessConf, 0)

	// 获取基础配置, 若未配置则直接返回
	conf, e := models.GetBusinessConf()
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取基础配置失败, Err: " + e.Error()
		return
	}

	list = append(list, system.BusinessConf{
		ConfKey: "ReportViewUrl",
		ConfVal: conf["ReportViewUrl"],
	}, system.BusinessConf{
		ConfKey: "ChartViewUrl",
		ConfVal: conf["ChartViewUrl"],
	}, system.BusinessConf{
		ConfKey: "LoginUrl",
		ConfVal: conf["LoginUrl"],
	})

	osc := system.BusinessConf{
		ConfKey: "ObjectStorageClient",
		ConfVal: utils.ObjectStorageClient,
	}
	if osc.ConfVal == "" {
		osc.ConfVal = "oss"
	}

	// ppt上传走后端配置
	pptUpload := system.BusinessConf{
		ConfKey: "PptUpdateApi",
		ConfVal: utils.PptUpdateApi,
	}

	list = append(list, osc, pptUpload)

	// 获取审批流设置
	//confKey := "approval_flow"
	//confTmp, e := company.GetConfigDetailByCode(confKey)
	//if e != nil {
	//	br.Msg = "获取审批流配置失败"
	//	br.ErrMsg = "获取审批流配置失败, Err: " + e.Error()
	//	return
	//}
	//list = append(list, system.BusinessConf{
	//	ConfKey: "ApprovalFlow",
	//	ConfVal: confTmp.ConfigValue,
	//})

	br.Data = list
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
}