package course

import (
	"time"

	"courseSign/server/global"
	"courseSign/server/model/common/request"
	"courseSign/server/model/common/response"
	"courseSign/server/model/course"
	courseReq "courseSign/server/model/course/request"
	"courseSign/server/model/system"
	systemReq "courseSign/server/model/system/request"
	twiReq "courseSign/server/model/twi/request"
	"courseSign/server/service"
	"courseSign/server/utils"
	"courseSign/server/utils/chain33"
	"github.com/33cn/chain33/common/address"
	"github.com/gin-gonic/gin"
	"github.com/go-redis/redis/v8"
	"go.uber.org/zap"
	"gorm.io/gorm"
)

type CourseUsersApi struct {
}

var courseUsersService = service.ServiceGroupApp.CourseServiceGroup.CourseUsersService
var jwtService              = service.ServiceGroupApp.SystemServiceGroup.JwtService

// CreateCourseUsers 创建CourseUsers
// @Tags CourseUsers
// @Summary 创建CourseUsers
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body course.CourseUsers true "创建CourseUsers"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /courseUsers/createCourseUsers [post]
func (courseUsersApi *CourseUsersApi) CreateCourseUsers(c *gin.Context) {
	var courseUsers course.CourseUsers
	err := c.ShouldBindJSON(&courseUsers)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
    verify := utils.Rules{
        "Address":{utils.NotEmpty()},
        "Name":{utils.NotEmpty()},
        "Age":{utils.NotEmpty()},
        "Sex":{utils.NotEmpty()},
        "Phone":{utils.NotEmpty()},
        "Photo":{utils.NotEmpty()},
        "Invitor":{utils.NotEmpty()},
    }
	if err := utils.Verify(courseUsers, verify); err != nil {
    		response.FailWithMessage(err.Error(), c)
    		return
    	}
	if err := courseUsersService.CreateCourseUsers(courseUsers); err != nil {
        global.GVA_LOG.Error("创建失败!", zap.Error(err))
		response.FailWithMessage("创建失败", c)
	} else {
		response.OkWithMessage("创建成功", c)
	}
}

// DeleteCourseUsers 删除CourseUsers
// @Tags CourseUsers
// @Summary 删除CourseUsers
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body course.CourseUsers true "删除CourseUsers"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /courseUsers/deleteCourseUsers [delete]
func (courseUsersApi *CourseUsersApi) DeleteCourseUsers(c *gin.Context) {
	var courseUsers course.CourseUsers
	err := c.ShouldBindJSON(&courseUsers)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if err := courseUsersService.DeleteCourseUsers(courseUsers); err != nil {
        global.GVA_LOG.Error("删除失败!", zap.Error(err))
		response.FailWithMessage("删除失败", c)
	} else {
		response.OkWithMessage("删除成功", c)
	}
}

// DeleteCourseUsersByIds 批量删除CourseUsers
// @Tags CourseUsers
// @Summary 批量删除CourseUsers
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.IdsReq true "批量删除CourseUsers"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"批量删除成功"}"
// @Router /courseUsers/deleteCourseUsersByIds [delete]
func (courseUsersApi *CourseUsersApi) DeleteCourseUsersByIds(c *gin.Context) {
	var IDS request.IdsReq
    err := c.ShouldBindJSON(&IDS)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if err := courseUsersService.DeleteCourseUsersByIds(IDS); err != nil {
        global.GVA_LOG.Error("批量删除失败!", zap.Error(err))
		response.FailWithMessage("批量删除失败", c)
	} else {
		response.OkWithMessage("批量删除成功", c)
	}
}

// UpdateCourseUsers 更新CourseUsers
// @Tags CourseUsers
// @Summary 更新CourseUsers
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body course.CourseUsers true "更新CourseUsers"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
// @Router /courseUsers/updateCourseUsers [put]
func (courseUsersApi *CourseUsersApi) UpdateCourseUsers(c *gin.Context) {
	var courseUsers course.CourseUsers
	err := c.ShouldBindJSON(&courseUsers)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	verify := utils.Rules{
	  "Address":{utils.NotEmpty()},
	  "Name":{utils.NotEmpty()},
	  "Age":{utils.NotEmpty()},
	  "Sex":{utils.NotEmpty()},
	  "Phone":{utils.NotEmpty()},
	  "Photo":{utils.NotEmpty()},
	  "Invitor":{utils.NotEmpty()},
	}
    if err := utils.Verify(courseUsers, verify); err != nil {
      	response.FailWithMessage(err.Error(), c)
      	return
    }

    if !address.IsEthAddress(courseUsers.Invitor) {
    	global.GVA_LOG.Error("错误地址",zap.Any("invitor",courseUsers.Invitor))
		response.FailWithMessage("地址错误", c)
	}

	if err := courseUsersService.UpdateCourseUsers(courseUsers); err != nil {
        global.GVA_LOG.Error("更新失败!", zap.Error(err))
		response.FailWithMessage("更新失败", c)
	} else {
		response.OkWithMessage("更新成功", c)
	}
}

// FindCourseUsers 用id查询CourseUsers
// @Tags CourseUsers
// @Summary 用id查询CourseUsers
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query course.CourseUsers true "用id查询CourseUsers"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
// @Router /courseUsers/findCourseUsers [get]
func (courseUsersApi *CourseUsersApi) FindCourseUsers(c *gin.Context) {
	var courseUsers course.CourseUsers
	err := c.ShouldBindQuery(&courseUsers)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if recourseUsers, err := courseUsersService.GetCourseUsers(courseUsers.ID); err != nil {
        global.GVA_LOG.Error("查询失败!", zap.Error(err))
		response.FailWithMessage("查询失败", c)
	} else {
		response.OkWithData(gin.H{"recourseUsers": recourseUsers}, c)
	}
}

// GetCourseUsersList 分页获取CourseUsers列表
// @Tags CourseUsers
// @Summary 分页获取CourseUsers列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query courseReq.CourseUsersSearch true "分页获取CourseUsers列表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /courseUsers/getCourseUsersList [get]
func (courseUsersApi *CourseUsersApi) GetCourseUsersList(c *gin.Context) {
	var pageInfo courseReq.CourseUsersSearch
	err := c.ShouldBindQuery(&pageInfo)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if list, total, err := courseUsersService.GetCourseUsersInfoList(pageInfo); err != nil {
	    global.GVA_LOG.Error("获取失败!", zap.Error(err))
        response.FailWithMessage("获取失败", c)
    } else {
        response.OkWithDetailed(response.PageResult{
            List:     list,
            Total:    total,
            Page:     pageInfo.Page,
            PageSize: pageInfo.PageSize,
        }, "获取成功", c)
    }
}

// FindCourseUsersMM 用id查询CourseUsers
// @Tags CourseUsers
// @Summary 用id查询CourseUsers
// @accept application/json
// @Produce application/json
// @Param data query course.CourseUsers true "用id查询CourseUsers"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
// @Router /courseUsers/findUsers [get]
func (courseUsersApi *CourseUsersApi) FindCourseUsersMM(c *gin.Context) {
	var courseUsers course.CourseUsers
	err := c.ShouldBindQuery(&courseUsers)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if courseUsers.ID > 0 {
		if recourseUsers, err := courseUsersService.GetCourseUsers(courseUsers.ID); err != nil {
			global.GVA_LOG.Error("查询失败!", zap.Error(err))
			response.FailWithMessage("查询失败", c)
		} else {
			response.OkWithData(gin.H{"recourseUsers": recourseUsers}, c)
		}
	} else if courseUsers.Address != "" {
		if recourseUsers, err := courseUsersService.GetCourseUsersByAddr(courseUsers.Address); err != nil {
			global.GVA_LOG.Error("查询失败!", zap.Error(err))
			response.FailWithMessage("查询失败", c)
		} else {
			response.OkWithData(gin.H{"recourseUsers": recourseUsers}, c)
		}
	}

}


// MetaMaskLogin 创建CourseUsers
// @Tags CourseUsers
// @Summary 创建CourseUsers
// @accept application/json
// @Produce application/json
// @Param data body twiReq.TwiUserLogin true "创建CourseUsers"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /courseUsers/login [post]
func (courseUsersApi *CourseUsersApi) MetaMaskLogin(c *gin.Context) {
	var loginUser twiReq.TwiUserLogin
	err := c.ShouldBindJSON(&loginUser)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if err := utils.Verify(loginUser, utils.MetaMaskVerify); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	signTime,err := utils.GetTimeStampFromMsg(loginUser.Msg)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if time.Now().Unix() - 1800 > signTime/1000 {
		response.FailWithMessage("签名时间已过期，请重新签名", c)
		return
	}
	var eipSign chain33.EIP191
	eipSign.Signature = loginUser.Signature
	eipSign.Msg = loginUser.Msg
	eipSign.Address = loginUser.Addr
	pass,err := chain33.VerifyPersonalSign(eipSign)
	if err != nil {
		global.GVA_LOG.Error("VerifyPersonalSign",zap.Error(err))
		response.FailWithMessage("验签失败", c)
		return
	}
	if !pass {
		response.FailWithMessage("验签未通过", c)
		return
	}
	// device token
	deviceCode := utils.CreateDeviceCode(loginUser.Addr)

	j := &utils.JWT{SigningKey: []byte(global.GVA_CONFIG.JWT.SigningKey)} // 唯一签名
	claims := j.CreateClaims(systemReq.BaseClaims{
		//ID:          user.ID,
		NickName:    loginUser.Addr,
		Username:    loginUser.Addr,
		DeviceCode:   deviceCode,
	})
	token, err := j.CreateToken(claims)
	if err != nil {
		global.GVA_LOG.Error("获取token失败!", zap.Error(err))
		response.FailWithMessage("获取token失败", c)
		return
	}
	// jwt token
	if jwtStr, err := jwtService.GetRedisJWT(loginUser.Addr); err == redis.Nil {
		if err := jwtService.SetRedisJWT(token, loginUser.Addr); err != nil {
			global.GVA_LOG.Error("设置登录状态失败!", zap.Error(err))
			response.FailWithMessage("设置登录状态失败", c)
			return
		}
	} else if err != nil {
		global.GVA_LOG.Error("设置登录状态失败!", zap.Error(err))
		response.FailWithMessage("设置登录状态失败", c)
		return
	} else {
		var blackJWT system.JwtBlacklist
		blackJWT.Jwt = jwtStr
		if err := jwtService.JsonInBlacklist(blackJWT); err != nil {
			response.FailWithMessage("jwt作废失败", c)
			return
		}
		if err := jwtService.SetRedisJWT(token, loginUser.Addr); err != nil {
			response.FailWithMessage("设置登录状态失败", c)
			return
		}
	}


	if deviceStr, err := jwtService.GetRedisJWT(deviceCode); err == redis.Nil {
		if err := jwtService.SetRedisJWT(loginUser.Addr, deviceCode); err != nil {
			global.GVA_LOG.Error("设置登录状态失败!", zap.Error(err))
			response.FailWithMessage("设置登录状态失败", c)
			return
		}
	} else if err != nil {
		global.GVA_LOG.Error("设置设备码状态失败!", zap.Error(err))
		response.FailWithMessage("设置设备码状态失败", c)
		return
	} else {
		var blackJWT system.JwtBlacklist
		blackJWT.Jwt = deviceStr
		if err := jwtService.JsonInBlacklist(blackJWT); err != nil {
			response.FailWithMessage("device code作废失败", c)
			return
		}
		if err := jwtService.SetRedisJWT(loginUser.Addr, deviceCode); err != nil {
			response.FailWithMessage("设置设备码状态失败", c)
			return
		}
	}

	user,err := courseUsersService.GetCourseUsersByAddr(loginUser.Addr)
	if err != nil && err != gorm.ErrRecordNotFound {
		response.FailWithMessage(err.Error(), c)
		return
	} else if err != nil && err == gorm.ErrRecordNotFound {
		if loginUser.Invitor != "" {
			err = address.CheckAddress(loginUser.Invitor,-1)
			if err != nil {
				response.FailWithMessage(err.Error(), c)
				return
			}
		} else {
			response.FailWithMessage("邀请者不存在", c)
			return
		}
		_,err = courseUsersService.GetCourseUsersByAddr(loginUser.Invitor)
		if err != nil && err == gorm.ErrRecordNotFound{
			response.FailWithMessage("邀请者不存在", c)
			return
		} else if err != nil && err != gorm.ErrRecordNotFound {
			response.FailWithMessage(err.Error(), c)
			return
		}

		var courseUser course.CourseUsers
		courseUser.Invitor = loginUser.Invitor
		courseUser.Address = loginUser.Addr
		err = courseUsersService.CreateCourseUsers(courseUser)
		if err != nil {
			global.GVA_LOG.Error("生成用户信息失败!", zap.Error(err))
			response.FailWithMessage("创建用户信息失败", c)
			return
		}
		response.OkWithData(token, c)
		return
	}

	// 用户已存在 有邀请人  直接返回token
	if err == nil && user.Invitor != "" {
		response.OkWithData(token, c)
		return
	}  else if err == nil && user.Invitor == "" {  // 不存在邀请人 则更新邀请关系
		if loginUser.Invitor != "" {
			err = address.CheckAddress(loginUser.Invitor,-1)
			if err != nil {
				response.FailWithMessage(err.Error(), c)
				return
			}
		} else {
			response.FailWithMessage("邀请者不存在", c)
			return
		}
		_,err = courseUsersService.GetCourseUsersByAddr(loginUser.Invitor)
		if err != nil && err == gorm.ErrRecordNotFound{
			response.FailWithMessage("邀请者不存在", c)
			return
		} else if err != nil && err != gorm.ErrRecordNotFound {
			response.FailWithMessage(err.Error(), c)
			return
		}
		user.Invitor = loginUser.Invitor
		err = courseUsersService.UpdateCourseUsers(user)
		if err != nil {
			global.GVA_LOG.Error("更新用户信息失败!", zap.Error(err))
			response.FailWithMessage("更新用户信息失败", c)
			return
		}
		response.OkWithData(token, c)
	}


}

// GetDeviceCode 获取设备码
// @Tags DeviceCode
// @Summary 分页获取CourseUsers列表
// @accept application/json
// @Produce application/json
// @Param data query courseReq.ReqId true "获取设备码"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /courseUsers/getCode [get]
func (courseUsersApi *CourseUsersApi) GetDeviceCode(c *gin.Context) {
	var pageInfo courseReq.ReqId
	err := c.ShouldBindQuery(&pageInfo)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	var res course.ResponseDeviceCode
	deviceStr, err := jwtService.GetRedisJWT(c.Request.Header.Get("address"))
	if err == redis.Nil {
		response.FailWithMessage("code not exists",c)
		return
	}
	j := utils.NewJWT()
	claims,err := j.ParseToken(deviceStr)
	if err != nil {
		response.FailWithMessage(err.Error(),c)
		return
	}
	user,err := courseUsersService.GetCourseUsersByAddr(c.Request.Header.Get("address"))
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	res.Code = claims.DeviceCode
	if pageInfo.Aid > 0 {
		_,err = courseActionUsersService.GetCourseActionUsersByUidAndAid(pageInfo.Aid,int(user.ID))
		if err == nil {
			res.IsSign = true
		}
	}
	response.OkWithData(res,c)
}