package controllers

import (
	"encoding/json"
	"fmt"
	"github.com/medivhzhan/weapp/v2"
	"hongze/hongze_mfyx/models"
	"hongze/hongze_mfyx/services"
	"hongze/hongze_mfyx/utils"
	"strconv"
	"time"
)

type WechatController struct {
	BaseAuthController
}

type WechatCommonController struct {
	BaseCommonController
}

// @Title 微信登录接口
// @Description 微信登录接口
// @Param   Code   query   string  true       "微信唯一编码code"
// @Success 200 {object} models.WxLoginResp
// @router /login [get]
func (this *WechatCommonController) WechatLogin() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	code := this.GetString("Code")
	if code == "" {
		br.Msg = "参数错误"
		br.ErrMsg = "Code 为空"
		return
	}
	wxInfo, err := weapp.Login(utils.WxAppId, utils.WxAppSecret, code)
	if err != nil {
		br.Msg = "获取用户信息失败"
		br.ErrMsg = "获取用户信息失败,Err:" + err.Error()
		return
	}
	if err = wxInfo.GetResponseError(); err != nil {
		br.Msg = "获取用户信息失败"
		br.ErrMsg = "获取用户信息失败,code:" + strconv.Itoa(wxInfo.ErrCode) + ",msg:" + wxInfo.ErrMSG
		return
	}

	wxUserInfo := new(services.WxUserInfo)
	wxUserInfo.Unionid = wxInfo.UnionID
	wxUserInfo.Openid = wxInfo.OpenID
	wxUserInfo.Errcode = wxInfo.ErrCode
	wxUserInfo.Errmsg = wxInfo.ErrMSG
	wxUserInfo.SessionKey = wxInfo.SessionKey
	token, userId, firstLogin, _, err := services.WxLogin(code, wxInfo.OpenID, wxInfo.UnionID, wxUserInfo)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = "微信登录失败"
		br.ErrMsg = "微信登录失败,err:" + err.Error()
		return
	}
	if token == "" {
		br.Msg = "微信登录失败"
		br.ErrMsg = "token:" + token + "" + code + " " + wxInfo.OpenID + " " + wxInfo.UnionID
		return
	}
	//新增登录日志
	{
		loginLog := new(models.WxUserLog)
		loginLog.UserId = userId
		loginLog.OpenId = wxInfo.OpenID
		loginLog.UnionId = wxInfo.UnionID
		loginLog.CreateTime = time.Now()
		loginLog.Handle = "wechat_login_mfyx"
		loginLog.Remark = token
		go models.AddWxUserLog(loginLog)
	}
	{
		codeLog := new(models.WxUserCode)
		codeLog.WxCode = code
		codeLog.UserId = userId
		codeLog.Code = 0
		codeLog.FirstLogin = firstLogin
		codeLog.Authorization = token
		codeLog.UserPermission = 1
		codeLog.CreateTime = time.Now()
		models.AddWxUserCode(codeLog)
	}

	resp := new(models.WxLoginResp)
	resp.UserId = userId
	resp.FirstLogin = firstLogin
	resp.Authorization = token
	br.Ret = 200
	br.Success = true
	br.Msg = "登录成功"
	br.Data = resp
}

// @Title 小程序获取用户信息
// @Description 小程序获取用户信息接口(需要登录)
// @Param	request	body models.WxGetUserInfoReq true "type json string"
// @Success 200 {object} models.WxGetUserInfoResp
// @router /getUserInfo [post]
func (this *WechatController) GetUserInfo() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	var req models.WxGetUserInfoReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}
	if req.RawData == "" || req.EncryptedData == "" || req.Signature == "" || req.Iv == "" {
		br.Msg = "参数错误"
		return
	}
	user := this.User
	if user == nil {
		br.Msg = "请登陆"
		br.Ret = 408
		return
	}
	userId := user.UserId
	sessionKey := user.SessionKey
	fmt.Println("sessionKey:", sessionKey)
	fmt.Println(sessionKey, req.RawData, req.EncryptedData, req.Signature, req.Iv)
	userInfo, err := weapp.DecryptUserInfo(sessionKey, req.RawData, req.EncryptedData, req.Signature, req.Iv)
	fmt.Println("weapp.DecryptUserInfo ", err)

	if err != nil {
		br.Msg = "解析用户信息失败"
		br.ErrMsg = "解析用户信息失败,DecryptUserInfo Err:" + err.Error()
		return
	}
	//修改用户微信信息
	err = models.ModifyUserRecordByDetail(userInfo.OpenID, userInfo.UnionID, userInfo.Nickname, userInfo.Avatar, userInfo.City, userInfo.Province, userInfo.Country, userInfo.Gender, userId)
	if err != nil {
		br.Msg = "授权失败"
		br.ErrMsg = "授权失败,修改用户信息失败:" + err.Error()
		return
	}
	var token string
	tokenItem, err := models.GetTokenByOpenId(userInfo.OpenID)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = "授权失败"
		br.ErrMsg = "授权失败,获取token失败:" + err.Error()
		return
	}

	if tokenItem == nil || (err != nil && err.Error() == utils.ErrNoRow()) {
		timeUnix := time.Now().Unix()
		timeUnixStr := strconv.FormatInt(timeUnix, 10)
		token = utils.MD5(userInfo.OpenID) + utils.MD5(timeUnixStr)
		//新增session
		{
			session := new(models.CygxSession)
			session.OpenId = userInfo.OpenID
			session.UnionId = userInfo.UnionID
			session.UserId = userId
			session.CreatedTime = time.Now()
			session.LastUpdatedTime = time.Now()
			session.ExpireTime = time.Now().AddDate(0, 3, 0)
			session.AccessToken = token
			err = models.AddSession(session)
			if err != nil {
				br.Msg = "授权失败"
				br.ErrMsg = "授权失败,新增用户session信息失败:" + err.Error()
				return
			}
		}
	} else {
		token = tokenItem.AccessToken
	}
	resp := new(models.WxGetUserInfoResp)
	resp.Authorization = token
	br.Msg = "获取成功!"
	br.Ret = 200
	br.Success = true
}

// @Title 小程序获取用户绑定手机号
// @Description 小程序获取用户绑定手机号接口(需要登录)
// @Param	request	body models.WxGetPhoneNumberReq true "type json string"
// @Success 200 {object} models.WxGetPhoneNumberResp
// @router /getPhoneNumber [post]
func (this *WechatController) GetPhoneNumber() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	var req models.WxGetPhoneNumberReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}
	if req.EncryptedData == "" || req.Iv == "" {
		br.Msg = "参数错误"
		return
	}
	user := this.User
	if user == nil {
		br.Msg = "请登陆"
		br.Ret = 408
		return
	}
	sessionKey := user.SessionKey
	wxMobile, err := weapp.DecryptMobile(sessionKey, req.EncryptedData, req.Iv)
	if err != nil {
		br.Msg = "解析用户手机号信息失败"
		br.ErrMsg = "解析用户手机号信息失败,Err:" + err.Error()
		return
	}
	err = models.ModifyUsersMobile(user.UserId, wxMobile.PurePhoneNumber)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取失败,Err:" + err.Error()
		return
	}

	resp := new(models.WxGetPhoneNumberResp)
	resp.PhoneNumber = wxMobile.PhoneNumber
	resp.PurePhoneNumber = wxMobile.PurePhoneNumber
	resp.CountryCode = wxMobile.CountryCode
	br.Msg = "获取成功!"
	br.Ret = 200
	br.Success = true
	br.Data = resp
}

// @Title 获取短信验证码
// @Description 获取短信验证码接口
// @Param   Mobile   query   string  true       "手机号码"
// @Param   AreaNum   query   string  true       "地区编码"
// @Success Ret=200 获取成功
// @router /getSmsCode [get]
func (this *WechatController) GetSmsCode() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	mobile := this.GetString("Mobile")
	if mobile == "" {
		br.Msg = "请输入手机号"
		return
	}
	areaNum := this.GetString("AreaNum")
	msgCode := utils.GetRandDigit(4)
	var result bool
	if areaNum == "86" || areaNum == "" || areaNum == "0" {
		result = services.SendSmsCode(mobile, msgCode)
	} else {
		result = services.SendSmsCodeGj(mobile, msgCode, areaNum)
	}
	//发送成功
	if result {
		item := new(models.MsgCode)
		item.OpenId = ""
		item.Code = msgCode
		item.Mobile = mobile
		item.ExpiredIn = time.Now().Add(15 * time.Minute).Unix()
		item.Enabled = 1
		item.CreatedTime = time.Now()
		err := models.AddMsgCode(item)
		if err != nil {
			br.Msg = "发送失败"
			br.ErrMsg = "发送失败,Err:" + err.Error()
			return
		}
		br.Msg = "发送成功"
	} else {
		br.Msg = "发送失败"
	}
	br.Ret = 200
	br.Success = true
}

// @Title 获取邮件验证码
// @Description 获取邮件验证码接口
// @Param   Email   query   string  true       "邮箱"
// @Success Ret=200 获取成功
// @router /getEmailCode [get]
func (this *WechatController) GetEmailCode() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	email := this.GetString("Email")
	if email == "" {
		br.Msg = "请输入邮箱地址"
		return
	}
	if !utils.ValidateEmailFormatat(email) {
		br.Msg = "邮箱格式错误,请重新输入"
		return
	}
	msgCode := utils.GetRandDigit(4)
	content := "尊敬的用户:</br>您好,感谢您使用弘则研究,您正在进行邮箱验证,本次请求的验证码为:" + msgCode + "(为了保障您账号的安全性,请在15分钟内完成验证。)</br>弘则研究团队 </br>2019年05月11日"
	title := "弘则研究登陆验证"
	//发送邮件
	result, err := utils.SendEmailByHz(title, content, email)
	if err != nil {
		br.Msg = "发送失败"
		br.ErrMsg = "发送失败,Err:" + err.Error()
		return
	}
	if result {
		item := new(models.MsgCode)
		item.OpenId = ""
		item.Code = msgCode
		item.Mobile = email
		item.ExpiredIn = time.Now().Add(15 * time.Minute).Unix()
		item.Enabled = 1
		item.CreatedTime = time.Now()
		err := models.AddMsgCode(item)
		if err != nil {
			br.Msg = "发送失败"
			br.ErrMsg = "发送失败,Err:" + err.Error()
			return
		}
		br.Msg = "发送成功"
	} else {
		br.Msg = "发送失败"
	}
	br.Ret = 200
	br.Success = true
}

// @Title 获取短信验证码(无需token)
// @Description 获取短信验证码接口(无需token)
// @Param   Mobile   query   string  true       "手机号码"
// @Param   AreaNum   query   string  true       "地区编码"
// @Success Ret=200 获取成功
// @router /getSmsCodePublic [get]
func (this *WechatCommonController) GetSmsCode() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	mobile := this.GetString("Mobile")
	if mobile == "" {
		br.Msg = "请输入手机号"
		return
	}
	areaNum := this.GetString("AreaNum")
	msgCode := utils.GetRandDigit(4)
	var result bool
	if areaNum == "86" || areaNum == "" || areaNum == "0" {
		result = services.SendSmsCode(mobile, msgCode)
	} else {
		result = services.SendSmsCodeGj(mobile, msgCode, areaNum)
	}
	//发送成功
	if result {
		item := new(models.MsgCode)
		item.OpenId = ""
		item.Code = msgCode
		item.Mobile = mobile
		item.ExpiredIn = time.Now().Add(15 * time.Minute).Unix()
		item.Enabled = 1
		item.CreatedTime = time.Now()
		err := models.AddMsgCode(item)
		if err != nil {
			br.Msg = "发送失败"
			br.ErrMsg = "发送失败,Err:" + err.Error()
			return
		}
		br.Msg = "发送成功"
	} else {
		br.Msg = "发送失败"
	}
	br.Ret = 200
	br.Success = true
}

//func init() {
//	itemToken, err := services.WxGetToken()
//	fmt.Println(err)
//	fmt.Println(itemToken.AccessToken)
//
//}

// @Title 微信获取用户绑定的手机号
// @Description 微信获取用户绑定的手机号接口
// @Param   Code   query   string  true       "微信唯一编码code"
// @Param   InviteShareCode   query   string  false       "销售账号邀请码"
// @Success 200 {object} models.WxLoginResp
// @router /getuserphonenumber [get]
func (this *WechatController) Getuserphonenumber() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	user := this.User
	if user == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录"
		br.Ret = 408
		return
	}
	code := this.GetString("Code")
	if code == "" {
		br.Msg = "参数错误"
		br.ErrMsg = "Code 为空"
		return
	}
	inviteShareCode := this.GetString("InviteShareCode")

	wxitem, err := services.Getuserphonenumber(code)
	if err != nil {
		br.Msg = "微信登录失败"
		br.ErrMsg = "微信登录失败,err:" + err.Error()
		return
	}

	var mobile string
	var countryCode string
	openId := this.User.OpenId
	mobile = wxitem.PhoneInfo.PhoneNumber
	countryCode = wxitem.PhoneInfo.CountryCode

	if mobile == "" {
		br.Msg = "微信登录失败"
		br.ErrMsg = "微信登录失败,手机号为空"
		return
	}

	user, err = services.BindWxUser(openId, mobile, "", countryCode, inviteShareCode)
	if err != nil {
		br.Msg = "登录失败"
		br.ErrMsg = "绑定手机号失败:" + err.Error()
		return
	}

	br.Ret = 200
	br.Success = true
	br.Msg = "登录成功"
	//br.Data = resp
}