package controller

import (
	"cold-delivery/app/admin/model"
	"cold-delivery/app/admin/service"
	"cold-delivery/app/admin/service/dto"
	"cold-delivery/common/actions"
	"cold-delivery/common/middleware/handler"
	"cold-delivery/conf"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"go.uber.org/zap"
	"gogs.baozhida.cn/zoie/OAuth-core/api"
	"gogs.baozhida.cn/zoie/OAuth-core/pkg"
	"gogs.baozhida.cn/zoie/OAuth-core/pkg/jwtauth/user"
	_ "gogs.baozhida.cn/zoie/OAuth-core/pkg/response"
	"gogs.baozhida.cn/zoie/OAuth-core/pkg/sms"
	"golang.org/x/crypto/bcrypt"
	"net/http"
)

// SysUser 定义用户控制器
type SysUser struct {
	api.Api
}

// GetPage 获取系统用户列表
// @Summary 获取系统用户列表
// @Description 获取系统用户列表
// @Tags 用户
// @Param username query string false "用户名"
// @Param status query string false "状态 1-停用 2-正常"
// @Param pageSize query int false "页条数"
// @Param page query int false "页码"
// @Success 200 {object} response.Response{data=response.Page{list=[]model.SysUser}}  "{"code": 200, "data": [...]}"
// @Router /api/sys-user [get]
// @Security Bearer
func (e SysUser) GetPage(c *gin.Context) {
	s := service.SysUser{}
	req := dto.SysUserGetPageReq{}
	err := e.MakeContext(c).
		MakeOrm().
		Bind(&req, binding.Query).
		MakeService(&s.Service).
		Errors

	if err != nil {
		e.Logger.Error(err)
		e.Error(500, err, err.Error())
		return
	}

	//数据权限检查
	p := actions.GetPermissionFromContext(c)

	list := make([]model.SysUser, 0)
	var count int64

	err = s.GetPage(&req, p, &list, &count)
	if err != nil {
		e.Error(500, err, err.Error())
		return
	}

	e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
}

// Get 通过id获取用户
// @Summary 通过id获取用户
// @Description 通过id获取用户
// @Tags 用户
// @Param id path int true "用户id"
// @Success 200 {object} response.Response{data=model.SysUser}  "{"code": 200, "data": [...]}"
// @Router /api/sys-user/{id} [get]
// @Security Bearer
func (e SysUser) Get(c *gin.Context) {
	s := service.SysUser{}
	req := dto.SysUserGetReq{}
	err := e.MakeContext(c).
		MakeOrm().
		Bind(&req, nil).
		MakeService(&s.Service).
		Errors
	if err != nil {
		e.Logger.Error(err)
		e.Error(500, err, err.Error())
		return
	}

	//数据权限检查
	//p := actions.GetPermissionFromContext(c)

	var object model.SysUser
	err = s.Get(&req, nil, &object)
	if err != nil {
		e.Error(http.StatusUnprocessableEntity, err, err.Error())
		return
	}
	e.OK(object, "查询成功")
}

// Insert 创建用户
// @Summary 创建用户
// @Description 创建用户
// @Tags 用户
// @Accept  application/json
// @Product application/json
// @Param data body dto.SysUserInsertReq true "用户数据"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/sys-user [post]
// @Security Bearer
func (e SysUser) Insert(c *gin.Context) {
	s := service.SysUser{}
	req := dto.SysUserInsertReq{}
	err := e.MakeContext(c).
		MakeOrm().
		Bind(&req, binding.JSON).
		MakeService(&s.Service).
		Errors
	if err != nil {
		e.Logger.Error(err)
		e.Error(500, err, err.Error())
		return
	}
	p := actions.GetPermissionFromContext(c)
	// 设置创建人
	req.SetCreateBy(user.GetUserId(c))
	err = s.Insert(&req, p)
	if err != nil {
		e.Error(500, err, err.Error())
		return
	}

	e.OK(req.GetId(), "添加成功")
}

// Update 修改用户数据
// @Summary 修改用户数据
// @Description 修改用户数据
// @Tags 用户
// @Accept  application/json
// @Product application/json
// @Param data body dto.SysUserUpdateReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/sys-user [put]
// @Security Bearer
func (e SysUser) Update(c *gin.Context) {
	s := service.SysUser{}
	req := dto.SysUserUpdateReq{}
	err := e.MakeContext(c).
		MakeOrm().
		Bind(&req).
		MakeService(&s.Service).
		Errors
	if err != nil {
		e.Logger.Error(err)
		e.Error(500, err, err.Error())
		return
	}

	req.SetUpdateBy(user.GetUserId(c))

	//数据权限检查
	//p := actions.GetPermissionFromContext(c)

	err = s.Update(&req, nil)
	if err != nil {
		e.Error(500, err, err.Error())
		return
	}
	e.OK(req.GetId(), "修改成功")
}

// Delete 通过id删除用户数据
// @Summary 通过id删除用户数据
// @Description 通过id删除用户数据
// @Tags 用户
// @Param data body dto.SysUserDeleteReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/sys-user [delete]
// @Security Bearer
func (e SysUser) Delete(c *gin.Context) {
	s := service.SysUser{}
	req := dto.SysUserDeleteReq{}
	err := e.MakeContext(c).
		MakeOrm().
		Bind(&req, binding.JSON).
		MakeService(&s.Service).
		Errors
	if err != nil {
		e.Logger.Error(err)
		e.Error(500, err, err.Error())
		return
	}
	userId := user.GetUserId(c)
	if userId == req.Id {
		err := errors.New("禁止删除自己")
		e.Error(500, err, err.Error())
		return
	}

	// 设置编辑人
	req.SetUpdateBy(userId)
	//数据权限检查
	p := actions.GetPermissionFromContext(c)

	err = s.Remove(&req, p)
	if err != nil {
		e.Error(500, err, err.Error())
		return
	}
	e.OK(req.GetId(), "删除成功")
}

// UpdateStatus 修改用户状态
// @Summary 修改用户状态
// @Description 修改用户状态
// @Tags 用户
// @Accept  application/json
// @Product application/json
// @Param data body dto.UpdateSysUserStatusReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/user/status [put]
// @Security Bearer
func (e SysUser) UpdateStatus(c *gin.Context) {
	s := service.SysUser{}
	req := dto.UpdateSysUserStatusReq{}
	err := e.MakeContext(c).
		MakeOrm().
		Bind(&req, binding.JSON, nil).
		MakeService(&s.Service).
		Errors
	if err != nil {
		e.Logger.Error(err)
		e.Error(500, err, err.Error())
		return
	}

	req.SetUpdateBy(user.GetUserId(c))

	//数据权限检查
	p := actions.GetPermissionFromContext(c)

	err = s.UpdateStatus(&req, p)
	if err != nil {
		e.Logger.Error(err)
		e.Error(500, err, err.Error())
		return
	}
	e.OK(req.GetId(), "修改成功")
}

// ResetPwd 重置用户密码
// @Summary 重置用户密码
// @Description 重置用户密码
// @Tags 用户
// @Accept  application/json
// @Product application/json
// @Param data body dto.ResetSysUserPwdReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/user/pwd/reset [put]
// @Security Bearer
func (e SysUser) ResetPwd(c *gin.Context) {
	s := service.SysUser{}
	req := dto.ResetSysUserPwdReq{}
	err := e.MakeContext(c).
		MakeOrm().
		Bind(&req, binding.JSON).
		MakeService(&s.Service).
		Errors
	if err != nil {
		e.Logger.Error(err)
		e.Error(500, err, err.Error())
		return
	}

	req.SetUpdateBy(user.GetUserId(c))

	//数据权限检查
	//p := actions.GetPermissionFromContext(c)

	err = s.ResetPwd(&req, nil)
	if err != nil {
		e.Logger.Error(err)
		e.Error(500, err, err.Error())
		return
	}

	e.OK(req.GetId(), "修改成功")

}

// UpdatePwd 修改密码
// @Summary 修改密码
// @Description 修改密码
// @Tags 个人中心
// @Accept  application/json
// @Product application/json
// @Param data body dto.SysUserPassWord true "body"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/user/pwd/set [put]
// @Security Bearer
func (e SysUser) UpdatePwd(c *gin.Context) {
	s := service.SysUser{}
	req := dto.SysUserPassWord{}
	err := e.MakeContext(c).
		MakeOrm().
		Bind(&req).
		MakeService(&s.Service).
		Errors
	if err != nil {
		e.Logger.Error(err)
		e.Error(500, err, err.Error())
		return
	}

	var hash []byte
	if hash, err = bcrypt.GenerateFromPassword([]byte(req.NewPassword), bcrypt.DefaultCost); err != nil {
		req.NewPassword = string(hash)
	}

	err = s.UpdatePwd(user.GetUserId(c), req.OldPassword, req.NewPassword)
	if err != nil {
		e.Error(http.StatusForbidden, err, err.Error())
		return
	}

	e.OK(nil, "密码修改成功")

}

// GetProfile 获取个人中心用户
// @Summary 获取个人中心用户
// @Description 获取个人中心用户
// @Tags 个人中心
// @Success 200 {object} response.Response{user=model.SysUser,role=model.SysRole}  "{"code": 200, "data": {"user":[...],"role":[...]}}"
// @Router /api/user/profile [get]
// @Security Bearer
func (e SysUser) GetProfile(c *gin.Context) {
	s := service.SysUser{}
	req := dto.SysUserById{}
	err := e.MakeContext(c).
		MakeOrm().
		MakeService(&s.Service).
		Errors
	if err != nil {
		e.Logger.Error(err)
		e.Error(500, err, err.Error())
		return
	}

	req.Id = user.GetUserId(c)

	sysUser := model.SysUser{}
	err = s.GetProfile(&req, &sysUser)
	if err != nil {
		e.Logger.Errorf("get user profile error, %s", err.Error())
		e.Error(500, err, "获取用户信息失败")
		return
	}
	// 获取岗位菜单树
	var menus interface{}
	var menuIds []int
	if sysUser.PostId > 0 {
		postSvc := service.SysPost{}
		postSvc.Orm = s.Orm
		postSvc.Log = s.Log
		menuTree, _ := postSvc.GetMenuTree()
		menuIds, _ = postSvc.GetPostMenuIds(sysUser.PostId)
		menus = postSvc.FilterMenuTree(menuTree, menuIds)
	}
	e.OK(gin.H{
		"user":        sysUser,
		"menus":       menus,
		"postMenuIds": menuIds,
	}, "查询成功")
}

// GetInfo 获取个人信息
// @Summary 获取个人信息
// @Description 获取个人信息
// @Tags 个人中心
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/user/info [get]
// @Security Bearer
func (e SysUser) GetInfo(c *gin.Context) {
	req := dto.SysUserGetReq{}
	s := service.SysUser{}
	r := service.SysRole{}
	err := e.MakeContext(c).
		MakeOrm().
		MakeService(&r.Service).
		MakeService(&s.Service).
		Errors
	if err != nil {
		e.Logger.Error(err)
		e.Error(500, err, err.Error())
		return
	}
	var roles = make([]string, 1)
	roles[0] = user.GetRoleName(c)
	var permissions = make([]string, 1)
	permissions[0] = "*:*:*"
	var buttons = make([]string, 1)
	buttons[0] = "*:*:*"

	var mp = make(map[string]interface{})
	mp["roles"] = roles
	list, _ := r.GetById(user.GetRoleId(c))
	mp["permissions"] = list
	mp["buttons"] = list

	sysUser := model.SysUser{}
	req.Id = user.GetUserId(c)

	err = s.Get(&req, nil, &sysUser)
	if err != nil {
		e.Logger.Errorf("get user info error, %s", err.Error())
		e.Error(http.StatusUnauthorized, err, err.Error())
		return
	}

	mp["userName"] = sysUser.Username
	mp["userId"] = sysUser.Id
	mp["deptId"] = sysUser.DeptId
	mp["name"] = sysUser.NickName
	mp["postId"] = sysUser.PostId
	mp["code"] = 200
	e.OK(mp, "查询成功")
}

// VerifyCode 获取短信验证码
// @Summary 获取短信验证码
// @Description 获取短信验证码
// @Tags 登录
// @Accept  application/json
// @Product application/json
// @Success 200 {string} string "{"code": 200, "data": "18888888888"}"
// @Router /verify-code [get]
// @Security Bearer
func (e SysUser) VerifyCode(c *gin.Context) {
	s := service.SysUser{}
	req := dto.SysUserGetSMSVerifyCodeReq{}
	err := e.MakeContext(c).
		MakeService(&s.Service).
		Bind(&req, binding.Query).
		Errors
	if err != nil {
		e.Logger.Error(err)
		e.Error(500, err, err.Error())
		return
	}
	key := handler.GetVerifyCodeCacheKey(req.Phone)
	_, err = e.Cache.Get(key)
	// 验证吗缓存已存在
	if err == nil {
		e.Error(500, err, "验证吗已发送，请注意查收")
		return
	}

	code := pkg.GenerateRandomFigureKey6()

	ss := sms.NewSMS(conf.ExtConfig.SubMail.Appid, conf.ExtConfig.SubMail.Signature)
	content := fmt.Sprintf("【气瓶追溯管理系统】您的短信验证码：%s，请在10分钟内输入", code)
	res, err := ss.Send(req.Phone, content)
	if err != nil || res.Status != sms.SUCCESS {
		e.Logger.Error("发送短信验证码出现异常", zap.Any("res", res), zap.Error(err))
		e.Error(500, err, "验证码发送失败，请重试")
		return
	}
	_ = e.Cache.Set(key, code, 600)
	e.OK(req.Phone, "发送成功")

}
