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"
	"time"
)

type SysAdminController struct {
}

func (a *SysAdminController) Add(c *gin.Context) {
	req := new(system.SysAdminAddReq)
	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.SysAdmin)
	_, err = item.GetAdminByAdminName(req.AdminName)
	if err != nil && err != utils.ErrNoRow {
		resp.FailMsg("查询管理员信息失败", "查询管理员信息失败,Err:"+err.Error(), c)
		return
	}
	if err == nil {
		resp.Fail("用户名重复,请重新设置", c)
		return
	}
	// 判断手机号是否已存在
	_, err = item.GetAdminByMobile(req.Mobile)
	if err != nil && err != utils.ErrNoRow {
		resp.FailMsg("查询管理员信息失败", "查询管理员信息失败,Err:"+err.Error(), c)
		return
	}
	if err == nil {
		resp.Fail("手机号已被其他账号绑定,请重新设置", c)
		return
	}

	item = &system.SysAdmin{
		AdminName: req.AdminName,
		RealName:  req.RealName,
		Password:  req.Password,
		Enabled:   req.Enabled,
		Email:     req.Email,
		Mobile:    req.Mobile,
		DeptId:    req.DeptId,
		RoleId:    req.RoleId,
		Position:  req.Position,
		Remark:    req.Remark,
	}
	if req.Enabled == 0 {
		item.DisableTime = time.Now()
	}
	err = item.Add()
	if err != nil {
		resp.FailMsg("保存失败", "保存失败,Err:"+err.Error(), c)
		return
	}
	resp.Ok("保存成功", c)
}

// List 部门列表
func (a *SysAdminController) List(c *gin.Context) {
	req := new(system.SysAdminListReq)
	err := c.BindQuery(&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
	}
	page := new(base.Page)
	page.SetPageSize(req.PageSize)
	page.SetCurrent(req.Current)
	item := new(system.SysAdmin)

	condition := "1=1"
	var pars []interface{}
	var total int64
	var tmpList []system.SysAdminListTmpItem
	var list []*system.SysAdminListItem

	if req.DeptId > 0 {
		deptIdMap, err, errMsg := systemService.GetChildDeptIds(0)
		if err != nil {
			resp.FailMsg(errMsg, err.Error(), c)
			return
		}
		if deptIds, ok := deptIdMap[req.DeptId]; ok {
			condition += " and sys_admin.dept_id IN (?)"
			pars = append(pars, deptIds)
		} else {
			page.SetTotal(total)
			baseData := new(base.BaseData)
			baseData.SetPage(page)
			baseData.SetList(list)
			resp.OkData("获取成功", baseData, c)
		}
	}
	if req.KeyWord != "" {
		keyLike := `%` + req.KeyWord + `%`
		condition += " AND (sys_admin.real_name LIKE ? OR sys_admin.mobile LIKE ? OR sys_admin.admin_name LIKE ?) "
		pars = append(pars, keyLike, keyLike, keyLike)
	}

	if req.Enabled != "" {
		condition += " AND sys_admin.enabled = ? "
		pars = append(pars, req.Enabled)
	}
	page.AddOrderItem(base.OrderItem{Column: "sys_admin.create_time", Asc: false})
	total, tmpList, err = item.SelectPage(page, condition, pars)
	if err != nil {
		resp.FailData("获取失败", "获取失败,Err:"+err.Error(), c)
		return
	}
	if len(tmpList) > 0 {
		deptNameMap, err, errMsg := systemService.GetChildDeptNames()
		if err != nil {
			resp.FailMsg(errMsg, err.Error(), c)
			return
		}
		for _, v := range tmpList {
			tmp := &system.SysAdminListItem{
				AdminId:    v.AdminId,
				AdminName:  v.AdminName,
				RealName:   v.RealName,
				Enabled:    v.Enabled,
				Email:      v.Email,
				Mobile:     v.Mobile,
				DeptId:     v.DeptId,
				RoleId:     v.RoleId,
				RoleName:   v.RoleName,
				Position:   v.Position,
				Remark:     v.Remark,
				CreateTime: utils.TimeTransferString(utils.FormatDateTime, v.CreateTime),
				ModifyTime: utils.TimeTransferString(utils.FormatDateTime, v.ModifyTime),
			}

			if name, ok := deptNameMap[v.DeptId]; ok {
				tmp.DeptFullName = name
			}
			list = append(list, tmp)
		}
	}
	page.SetTotal(total)
	baseData := new(base.BaseData)
	baseData.SetPage(page)
	baseData.SetList(list)
	resp.OkData("获取成功", baseData, c)
}

// @Title 修改密码
// @Description 修改密码
// @Param	request	body models.ModifyPwdReq true "type json string"
// @Success 200 {object} models.LoginResp
// @router /modify/pwd [post]
func (a *SysAdminController) ModifyPwd(c *gin.Context) {
	req := new(system.ModifyPwdReq)
	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
	}
	//获取jwt数据失败
	var adminInfo *system.SysAdmin
	// 判断账号名是否已存在
	admin := new(system.SysAdmin)
	//查询账号是否存在
	adminInfo, err = admin.GetAdminByAdminId(req.AdminId)
	if err != nil {
		if err == utils.ErrNoRow {
			resp.Fail("账号不存在", c)
			return
		}
		resp.FailMsg("查询管理员信息失败", "查询管理员信息失败,Err:"+err.Error(), c)
		return
	}
	if req.Pwd != req.ConfirmPwd {
		resp.Fail("新密码两次输入不一致,请核对", c)
		return
	}
	if adminInfo.Password == req.Pwd {
		resp.Fail("新密码不能与旧密码一致,请重试", c)
		return
	}
	adminInfo.Password = req.Pwd
	err = adminInfo.Update([]string{"password"})
	if err != nil {
		resp.FailData("密码更新失败", "Err:"+err.Error(), c)
		return
	}

	resp.Ok("修改成功", c)
	return
}

// @Title 修改密码
// @Description 修改密码
// @Param	request	body models.ModifyPwdReq true "type json string"
// @Success 200 {object} models.LoginResp
// @router /modify/my/pwd [post]
func (a *SysAdminController) ModifyMyPwd(c *gin.Context) {
	req := new(system.ModifyMyPwdReq)
	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
	}
	claims, _ := c.Get("adminInfo")
	adminInfo := claims.(*system.SysAdmin)
	if req.NewPwd != req.ConfirmPwd {
		resp.Fail("新密码两次输入不一致,请核对", c)
		return
	}
	if adminInfo.Password != req.OldPwd {
		resp.Fail("旧密码错误,请重新输入", c)
		return
	}
	if adminInfo.Password == req.NewPwd {
		resp.Fail("新密码不能与旧密码一致,请重试", c)
		return
	}
	adminInfo.Password = req.NewPwd
	err = adminInfo.Update([]string{"password"})
	if err != nil {
		resp.FailData("密码更新失败", "Err:"+err.Error(), c)
		return
	}

	resp.Ok("修改成功", c)
	return
}

// @Title 修改初始密码
// @Description 修改初始密码
// @Param	request	body models.ModifyPwdReq true "type json string"
// @Success 200 {object} models.LoginResp
// @router /modify/my/init_pwd [post]
func (a *SysAdminController) ModifyMyInitPwd(c *gin.Context) {
	req := new(system.ModifyMyInitPwdReq)
	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
	}
	claims, _ := c.Get("adminInfo")
	adminInfo := claims.(*system.SysAdmin)
	if req.NewPwd != req.ConfirmPwd {
		resp.Fail("新密码两次输入不一致,请核对", c)
		return
	}
	if adminInfo.Password == req.NewPwd {
		resp.Fail("新密码不能与旧密码一致,请重试", c)
		return
	}
	adminInfo.Password = req.NewPwd
	err = adminInfo.Update([]string{"password"})
	if err != nil {
		resp.FailData("密码更新失败", "Err:"+err.Error(), c)
		return
	}

	resp.Ok("修改成功", c)
	return
}

// Delete 删除用户
func (a *SysAdminController) Delete(c *gin.Context) {
	req := new(system.SysAdminReq)
	err := c.ShouldBind(&req)
	if err != nil {
		resp.FailData("参数解析失败", "Err:"+err.Error(), c)
		return
	}
	item := new(system.SysAdmin)
	item.AdminId = req.AdminId
	err = item.Delete()
	if err != nil {
		resp.FailData("删除失败", "删除失败,Err:"+err.Error(), c)
		return
	}
	resp.Ok("删除成功", c)
}

// Edit 编辑用户
func (a *SysAdminController) Edit(c *gin.Context) {
	req := new(system.SysAdminEditReq)
	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
	}
	// 判断账号名是否已存在
	admin := new(system.SysAdmin)
	//查询账号是否存在
	item, err := admin.GetAdminByAdminId(req.AdminId)
	if err != nil {
		if err == utils.ErrNoRow {
			resp.Fail("账号不存在", c)
			return
		}
		resp.FailData("查询管理员信息失败", "查询管理员信息失败,Err:"+err.Error(), c)
		return
	}
	if item.AdminName != req.AdminName {
		_, err = item.GetAdminByAdminName(req.AdminName)
		if err != nil && err != utils.ErrNoRow {
			resp.FailData("查询管理员信息失败", "查询管理员信息失败,Err:"+err.Error(), c)
			return
		}
		if err == nil {
			resp.Fail("用户名重复,请重新设置", c)
			return
		}
	}
	if item.Mobile != req.Mobile {
		// 判断手机号是否已存在
		_, err = item.GetAdminByMobile(req.Mobile)
		if err != nil && err != utils.ErrNoRow {
			resp.FailData("查询管理员信息失败", "查询管理员信息失败,Err:"+err.Error(), c)
			return
		}
		if err == nil {
			resp.Fail("手机号已被其他账号绑定,请重新设置", c)
			return
		}
	}

	updateStr := []string{"admin_name", "real_name", "enabled", "email", "mobile", "dept_id", "role_id", "position", "remark"}
	item.AdminName = req.AdminName
	item.RealName = req.RealName
	item.Enabled = req.Enabled
	item.Email = req.Email
	item.Mobile = req.Mobile
	item.DeptId = req.DeptId
	item.RoleId = req.RoleId
	item.Position = req.Position
	item.Remark = req.Remark
	if req.Enabled == 0 {
		item.DisableTime = time.Now()
	}
	err = item.Update(updateStr)
	if err != nil {
		resp.FailData("保存失败", "保存失败,Err:"+err.Error(), c)
		return
	}
	resp.Ok("修改成功", c)
	return
}

// @Title 修改管理员状态
// @Description 修改管理员状态
// @Param	request	body models.ModifyPwdReq true "type json string"
// @Success 200 {object} models.LoginResp
// @router /modify/enabled [post]
func (a *SysAdminController) ModifyEnabled(c *gin.Context) {
	req := new(system.SysAdminModifyEnabledReq)
	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
	}

	admin := new(system.SysAdmin)
	admin.AdminId = req.AdminId
	admin.Enabled = req.Enabled
	err = admin.Update([]string{"enabled"})
	if err != nil {
		resp.FailData("更新失败", "Err:"+err.Error(), c)
		return
	}

	resp.Ok("修改成功", c)
	return
}