package eta_business

import (
	"encoding/json"
	"hongze/hz_crm_api/controllers"
	"hongze/hz_crm_api/models"
	"hongze/hz_crm_api/models/eta_business"
	etaBusinessService "hongze/hz_crm_api/services/eta_business"
	"hongze/hz_crm_api/utils"
	"html/template"
	"sort"
	"strings"
	"time"
)

// EtaBusinessMenuController ETA商家菜单
type EtaBusinessMenuController struct {
	controllers.BaseAuthController
}

// List
// @Title 商家菜单列表
// @Description 商家菜单列表
// @Param   BusinessId	query	int		false	"商家ID"
// @Param   Keyword		query	string	false	"关键词: 菜单名称"
// @Success 200 Ret=200 获取成功
// @router /menu/list [get]
func (this *EtaBusinessMenuController) List() {
	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
	}

	resp := new(eta_business.EtaBusinessMenuListResp)
	resp.ChoiceList = make([]int, 0)
	resp.HalfChoiceList = make([]int, 0)
	resp.List = make([]*eta_business.EtaBusinessMenuItem, 0)
	// 权限校验
	ok, e := etaBusinessService.CheckEtaBusinessOperateAuth(sysUser.RoleTypeCode)
	if e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "操作权限校验失败, ErrMsg: " + e.Error()
		return
	}
	if !ok {
		br.Data = resp
		br.Ret = 200
		br.Success = true
		br.Msg = "获取成功"
		return
	}

	menuCond := ``
	menuPars := make([]interface{}, 0)
	// 商家勾选的权限
	{
		businessId, _ := this.GetInt("EtaBusinessId", 0)
		if businessId > 0 {
			relateOb := new(eta_business.EtaBusinessMenuRelate)
			cond := ` AND eta_business_id = ?`
			pars := make([]interface{}, 0)
			pars = append(pars, businessId)
			relates, e := relateOb.GetItemsByCondition(cond, pars, []string{}, "")
			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)
			}
			menuCond += ` AND hidden = 0`
		}
	}

	// 关键词
	keyword := this.GetString("Keyword")
	keyword = strings.TrimSpace(keyword)
	keyword = template.HTMLEscapeString(keyword)

	// 所有菜单列表
	menuOb := new(eta_business.EtaBusinessMenu)
	order := `sort ASC, create_time DESC, menu_id DESC`
	menus, e := menuOb.GetItemsByCondition(menuCond, menuPars, []string{}, order)
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取商家菜单列表失败, Err: " + e.Error()
		return
	}

	list := make([]*eta_business.EtaBusinessMenu, 0)
	if keyword != "" {
		menuMap := make(map[int]*eta_business.EtaBusinessMenu)
		parentMap := make(map[int]*eta_business.EtaBusinessMenu)
		existMap := make(map[int]bool)

		for _, m := range menus {
			menuMap[m.MenuId] = m
		}
		for _, m := range menus {
			if m.ParentId > 0 {
				parentMap[m.MenuId] = menuMap[m.ParentId]
			}
		}

		// 遍历菜单, 取出跟关键词匹配的菜单(层级比较深, 递归效率很低, 产品要这个需求暂时也没啥办法优化=_=!)
		for _, m := range menus {
			if !strings.Contains(m.Name, keyword) {
				continue
			}
			if existMap[m.MenuId] {
				continue
			}
			existMap[m.MenuId] = true
			list = append(list, m)

			// 取出关键词所匹配的所有父级菜单
			if m.ParentId > 0 {
				parents := etaBusinessService.GetMenuParentsRecursive(menus, m.ParentId)
				for _, p := range parents {
					if !existMap[p.MenuId] {
						existMap[p.MenuId] = true
						list = append(list, p)
					}
				}
			}
		}

		sort.Slice(list, func(i, j int) bool {
			return list[j].Sort > list[i].Sort
		})
	} else {
		list = menus
	}

	items := make([]*eta_business.EtaBusinessMenuItem, 0)
	for _, v := range list {
		t := &eta_business.EtaBusinessMenuItem{
			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,
			CreateTime: v.CreateTime.Format(utils.FormatDateTime),
			Children:   make([]*eta_business.EtaBusinessMenuItem, 0),
		}
		items = append(items, t)
	}

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

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

// SaveRelate
// @Title 保存商家菜单关联
// @Description 保存商家菜单关联
// @Param	request	body eta_business.EtaBusinessAddReq true "type json string"
// @Success 200 Ret=200 操作成功
// @router /menu/relate/save [post]
func (this *EtaBusinessMenuController) SaveRelate() {
	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
	}

	// 操作权限校验
	ok, e := etaBusinessService.CheckEtaBusinessOperateAuth(sysUser.RoleTypeCode)
	if e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "操作权限校验失败, ErrMsg: " + e.Error()
		return
	}
	if !ok {
		br.Msg = "无权操作"
		return
	}

	// 参数校验
	var req eta_business.EtaBusinessMenuRelateSaveReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + e.Error()
		return
	}
	if req.EtaBusinessId <= 0 {
		br.Msg = "参数有误"
		return
	}
	if len(req.MenuIds) == 0 {
		br.Msg = "请选择菜单"
		return
	}

	ob := new(eta_business.EtaBusinessMenuRelate)
	items := make([]*eta_business.EtaBusinessMenuRelate, 0)
	for _, v := range req.MenuIds {
		t := new(eta_business.EtaBusinessMenuRelate)
		t.MenuId = v
		t.EtaBusinessId = req.EtaBusinessId
		items = append(items, t)
	}
	for _, v := range req.HalfMenuIds {
		t := new(eta_business.EtaBusinessMenuRelate)
		t.MenuId = v
		t.Type = 1
		t.EtaBusinessId = req.EtaBusinessId
		items = append(items, t)
	}
	if e := ob.CreateMulti(req.EtaBusinessId, items); e != nil {
		br.Msg = "保存失败"
		br.ErrMsg = "保存商家菜单关联失败, Err: " + e.Error()
		return
	}

	br.Ret = 200
	br.Success = true
	br.Msg = "操作成功"
}

// Add
// @Title 新增菜单
// @Description 新增菜单
// @Param	request	body eta_business.EtaBusinessMenuAddReq true "type json string"
// @Success 200 Ret=200 操作成功
// @router /menu/add [post]
func (this *EtaBusinessMenuController) Add() {
	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
	}

	// 操作权限校验
	ok, e := etaBusinessService.CheckEtaBusinessOperateAuth(sysUser.RoleTypeCode)
	if e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "操作权限校验失败, ErrMsg: " + e.Error()
		return
	}
	if !ok {
		br.Msg = "无权操作"
		return
	}

	// 参数校验
	var req eta_business.EtaBusinessMenuAddReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + e.Error()
		return
	}
	req.Name = strings.TrimSpace(req.Name)
	if req.Name == "" {
		br.Msg = "请输入名称"
		return
	}
	if req.MenuType == 0 {
		req.Path = strings.TrimSpace(req.Path)
		if req.Path == "" {
			br.Msg = "请输入路由地址"
			return
		}
		req.Component = strings.TrimSpace(req.Component)
		if req.Component == "" {
			br.Msg = "请输入组件路径"
			return
		}
	} else {
		req.ButtonCode = strings.TrimSpace(req.ButtonCode)
		if req.ButtonCode == "" {
			br.Msg = "请输入按钮/字段ID"
			return
		}
	}

	// 重名校验
	{
		ob := new(eta_business.EtaBusinessMenu)
		cond := ` AND parent_id = ? AND name = ?`
		pars := make([]interface{}, 0)
		pars = append(pars, req.ParentId, req.Name)
		exist, e := ob.GetItemByCondition(cond, pars)
		if e != nil && e.Error() != utils.ErrNoRow() {
			br.Msg = "操作失败"
			br.ErrMsg = "获取同名菜单失败, Err: " + e.Error()
			return
		}
		if exist != nil {
			br.Msg = "名称已存在"
			return
		}
	}

	// 新增
	menuOb := new(eta_business.EtaBusinessMenu)
	menuOb.ParentId = req.ParentId
	menuOb.Name = req.Name
	menuOb.Sort = req.Sort
	menuOb.Path = req.Path
	menuOb.IconPath = req.IconPath
	menuOb.Component = req.Component
	menuOb.Hidden = req.Hidden
	menuOb.MenuType = req.MenuType
	menuOb.ButtonCode = req.ButtonCode
	menuOb.CreateTime = time.Now().Local()
	menuOb.ModifyTime = time.Now().Local()
	// TODO:多级菜单
	if menuOb.ParentId > 0 {
		menuOb.LevelPath = menuOb.Component
	}
	if e := menuOb.Create(); e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "新增菜单失败, Err: " + e.Error()
		return
	}

	br.Ret = 200
	br.Success = true
	br.Msg = "操作成功"
}

// Edit
// @Title 编辑菜单
// @Description 编辑菜单
// @Param	request	body eta_business.EtaBusinessMenuEditReq true "type json string"
// @Success 200 Ret=200 操作成功
// @router /menu/edit [post]
func (this *EtaBusinessMenuController) Edit() {
	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
	}

	// 操作权限校验
	ok, e := etaBusinessService.CheckEtaBusinessOperateAuth(sysUser.RoleTypeCode)
	if e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "操作权限校验失败, ErrMsg: " + e.Error()
		return
	}
	if !ok {
		br.Msg = "无权操作"
		return
	}

	// 参数校验
	var req eta_business.EtaBusinessMenuEditReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + e.Error()
		return
	}
	if req.MenuId <= 0 {
		br.Msg = "参数有误"
		br.ErrMsg = "参数有误, MenuId"
		return
	}
	req.Name = strings.TrimSpace(req.Name)
	if req.Name == "" {
		br.Msg = "请输入名称"
		return
	}
	if req.MenuType == 0 {
		req.Path = strings.TrimSpace(req.Path)
		if req.Path == "" {
			br.Msg = "请输入路由地址"
			return
		}
		req.Component = strings.TrimSpace(req.Component)
		if req.Component == "" {
			br.Msg = "请输入组件路径"
			return
		}
	} else {
		req.ButtonCode = strings.TrimSpace(req.ButtonCode)
		if req.ButtonCode == "" {
			br.Msg = "请输入按钮/字段ID"
			return
		}
	}

	menuOb := new(eta_business.EtaBusinessMenu)
	item, e := menuOb.GetItemById(req.MenuId)
	if e != nil {
		if e.Error() == utils.ErrNoRow() {
			br.Msg = "菜单不存在, 请刷新页面"
			return
		}
		br.Msg = "操作失败"
		br.ErrMsg = "获取菜单失败, Err: " + e.Error()
		return
	}

	// 重名校验
	{
		ob := new(eta_business.EtaBusinessMenu)
		cond := ` AND parent_id = ? AND name = ?`
		pars := make([]interface{}, 0)
		pars = append(pars, req.ParentId, req.Name)
		exist, e := ob.GetItemByCondition(cond, pars)
		if e != nil && e.Error() != utils.ErrNoRow() {
			br.Msg = "操作失败"
			br.ErrMsg = "获取同名菜单失败, Err: " + e.Error()
			return
		}
		if exist != nil && exist.MenuId != item.MenuId {
			br.Msg = "名称已存在"
			return
		}
	}

	// 更新
	item.Name = req.Name
	item.Sort = req.Sort
	item.Path = req.Path
	item.IconPath = req.IconPath
	item.Component = req.Component
	item.Hidden = req.Hidden
	item.ButtonCode = req.ButtonCode
	item.ParentId = req.ParentId
	item.ModifyTime = time.Now().Local()
	// TODO:多级菜单
	cols := make([]string, 0)
	cols = append(cols, "Name", "Sort", "Path", "IconPath", "Component", "Hidden", "ButtonCode", "ParentId", "ModifyTime")
	if item.ParentId > 0 {
		item.LevelPath = item.Component
		cols = append(cols, "LevelPath")
	}
	if e := item.Update(cols); e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "更新菜单失败, Err: " + e.Error()
		return
	}

	br.Ret = 200
	br.Success = true
	br.Msg = "操作成功"
}

// Remove
// @Title 删除菜单
// @Description 删除菜单
// @Param	request	body eta_business.EtaBusinessMenuRemoveReq true "type json string"
// @Success 200 Ret=200 操作成功
// @router /menu/remove [post]
func (this *EtaBusinessMenuController) Remove() {
	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
	}

	// 操作权限校验
	ok, e := etaBusinessService.CheckEtaBusinessOperateAuth(sysUser.RoleTypeCode)
	if e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "操作权限校验失败, ErrMsg: " + e.Error()
		return
	}
	if !ok {
		br.Msg = "无权操作"
		return
	}

	// 参数校验
	var req eta_business.EtaBusinessMenuRemoveReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + e.Error()
		return
	}
	if req.MenuId <= 0 {
		br.Msg = "参数有误"
		br.ErrMsg = "参数有误, MenuId"
		return
	}

	menuOb := new(eta_business.EtaBusinessMenu)
	_, e = menuOb.GetItemById(req.MenuId)
	if e != nil {
		if e.Error() == utils.ErrNoRow() {
			br.Msg = "菜单不存在, 请刷新页面"
			return
		}
		br.Msg = "操作失败"
		br.ErrMsg = "获取菜单失败, Err: " + e.Error()
		return
	}

	// 获取所有菜单列表, 筛选出该菜单及子菜单
	menus, e := menuOb.GetItemsByCondition(``, make([]interface{}, 0), []string{}, "")
	if e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "获取菜单列表失败, Err: " + e.Error()
		return
	}
	menuIds := etaBusinessService.GetMenuChildrenIdsRecursive(menus, req.MenuId)
	menuIds = append(menuIds, req.MenuId)

	// 删除菜单
	if e = menuOb.MultiDel(menuIds); e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "删除菜单及子菜单失败, Err: " + e.Error()
		return
	}

	br.Ret = 200
	br.Success = true
	br.Msg = "操作成功"
}

// IconList
// @Title 图标列表
// @Description 图标列表
// @Success 200 Ret=200 操作成功
// @router /menu/icon/list [get]
func (this *EtaBusinessMenuController) IconList() {
	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
	}

	iconOb := new(eta_business.EtaBusinessMenuIcon)
	icons, e := iconOb.GetItemsByCondition(``, make([]interface{}, 0), []string{}, "")
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取菜单列表失败, Err: " + e.Error()
		return
	}
	list := make([]*eta_business.EtaBusinessMenuIconItem, 0)
	for _, v := range icons {
		list = append(list, &eta_business.EtaBusinessMenuIconItem{
			IconId:   v.IconId,
			IconPath: v.IconPath,
		})
	}

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

// IconAdd
// @Title 新增图标
// @Description 新增图标
// @Success 200 Ret=200 操作成功
// @router /menu/icon/add [post]
func (this *EtaBusinessMenuController) IconAdd() {
	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
	}

	var req eta_business.EtaBusinessMenuIconAddReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + e.Error()
		return
	}
	req.IconPath = strings.TrimSpace(req.IconPath)
	if req.IconPath == "" {
		br.Msg = "请上传图片"
		return
	}

	iconOb := new(eta_business.EtaBusinessMenuIcon)
	iconOb.IconPath = req.IconPath
	iconOb.CreateTime = time.Now().Local()
	if e := iconOb.Create(); e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "新增菜单icon失败, Err: " + e.Error()
		return
	}

	br.Ret = 200
	br.Success = true
	br.Msg = "操作成功"
}

// SystemApiConfig
// @Title 系统配置接口列表
// @Description 系统配置接口列表
// @Success 200 {object} []system.BusinessConf
// @router /api/config/list [get]
func (this *EtaBusinessMenuController) SystemApiConfig() {
	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
	}
	var relates []*eta_business.EtaBusinessConfigRelate
	businessId, _ := this.GetInt("EtaBusinessId", 0)
	var err error
	if businessId > 0 {
		relateOb := new(eta_business.EtaBusinessConfigRelate)
		cond := ` AND eta_business_id = ?`
		pars := make([]interface{}, 0)
		pars = append(pars, businessId)
		relates, err = relateOb.GetItemsByCondition(cond, pars, []string{}, "")
		if err != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取商家菜单关联列表失败, Err: " + err.Error()
			return
		}
	}


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

// SystemApiConfig
// @Title 系统配置接口列表
// @Description 系统配置接口列表
// @Success 200 {object} []system.BusinessConf
// @router /api/config/set [post]
func (this *EtaBusinessMenuController) SystemApiConfigSet() {
	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
	}

	var req eta_business.SetBusinessConfReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + e.Error()
		return
	}
	ob := new(eta_business.EtaBusinessConfigRelate)
	items := make([]*eta_business.EtaBusinessConfigRelate, 0)
	for _, v := range req.List {
		t := new(eta_business.EtaBusinessConfigRelate)
		t.ConfigCode = v.ConfigCode
		t.ConfigValue = v.ConfigValue
		t.EtaBusinessId = req.EtaBusinessId
		items = append(items, t)
	}
	if e := ob.CreateMulti(req.EtaBusinessId, items); e != nil {
		br.Msg = "保存失败"
		br.ErrMsg = "保存商家菜单关联失败, Err: " + e.Error()
		return
	}

	br.Ret = 200
	br.Success = true
	br.Msg = "操作成功"

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