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

// Customer 定义客户控制器
type Customer struct {
	api.Api
}

// GetPage 获取客户列表
// @Summary 获取客户列表
// @Description 获取客户列表
// @Tags 客户
// @Param username query string false "用户名"
// @Param name query string false "姓名"
// @Param type query int false "类型"
// @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/customer [get]
// @Security Bearer
func (e Customer) GetPage(c *gin.Context) {
	s := service.Customer{}
	req := dto.CustomerGetPageReq{}
	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/customer/{id} [get]
// @Security Bearer
func (e Customer) Get(c *gin.Context) {
	s := service.Customer{}
	req := dto.CustomerGetReq{}
	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.CustomerInsertReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/customer [post]
// @Security Bearer
func (e Customer) Insert(c *gin.Context) {
	s := service.Customer{}
	req := dto.CustomerInsertReq{}
	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)
	if p.DeptId == 0 {
		err = errors.New("无权添加，请联系管理员！")
		e.Error(500, err, err.Error())
		return
	}
	// 设置创建人
	req.SetCreateBy(user.GetUserId(c))
	req.SetDeptId(p.DeptId)
	err = s.Insert(&req)
	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.CustomerUpdateReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/customer [put]
// @Security Bearer
func (e Customer) Update(c *gin.Context) {
	s := service.Customer{}
	req := dto.CustomerUpdateReq{}
	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.CustomerDeleteReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/customer [delete]
// @Security Bearer
func (e Customer) Delete(c *gin.Context) {
	s := service.Customer{}
	req := dto.CustomerDeleteReq{}
	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, nil)
	if err != nil {
		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.ResetCustomerPwdReq true "body"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/user/pwd/reset [put]
// @Security Bearer
func (e Customer) ResetPwd(c *gin.Context) {
	s := service.Customer{}
	req := dto.ResetCustomerPwdReq{}
	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.CustomerPassWord true "body"
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/customer/pwd/set [put]
// @Security Bearer
func (e Customer) UpdatePwd(c *gin.Context) {
	s := service.Customer{}
	req := dto.CustomerPassWord{}
	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 Customer) GetProfile(c *gin.Context) {
	s := service.Customer{}
	req := dto.CustomerById{}
	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
	}
	e.OK(gin.H{
		"user": sysUser,
	}, "查询成功")
}

// GetInfo 获取个人信息
// @Summary 获取个人信息
// @Description 获取个人信息
// @Tags 个人中心
// @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
// @Router /api/user/info [get]
// @Security Bearer
func (e Customer) GetInfo(c *gin.Context) {
	req := dto.CustomerGetReq{}
	s := service.Customer{}
	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["code"] = 200
	e.OK(mp, "查询成功")
}

// VerifyCode 获取短信验证码
// @Summary 获取短信验证码
// @Description 获取短信验证码
// @Tags 登录
// @Param phone query string false "电话号码"
// @Success 200 {string} string "{"code": 200, "data": "18888888888"}"
// @Router /verify-code [get]
// @Security Bearer
func (e Customer) VerifyCode(c *gin.Context) {
	s := service.Customer{}
	req := dto.CustomerGetSMSVerifyCodeReq{}
	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, "发送成功")

}
