package controllers

import (
	"encoding/json"
	"encoding/xml"
	"eta/eta_mini_api/models"
	"eta/eta_mini_api/models/request"
	"eta/eta_mini_api/models/response"
	"eta/eta_mini_api/services/alarm_msg"
	"eta/eta_mini_api/services/wechat"
	"eta/eta_mini_api/services/wx_app"
	"eta/eta_mini_api/utils"
	"fmt"
	"strconv"
	"time"
)

type WechatController struct {
	BaseCommonController
}

// @Title 微信获取签名接口
// @Description 微信获取签名接口
// @Param   Url   query   string  true       "url地址"
// @Success 200 {object} models.WechatSign
// @router /notify [get,post]
func (this *WechatController) Notify() {
	echostr := this.GetString("echostr")
	method := this.Ctx.Input.Method()

	type Notify struct {
		ToUserName   string `xml:"ToUserName"`
		FromUserName string `xml:"FromUserName"`
		CreateTime   int    `xml:"CreateTime"`
		MsgType      string `xml:"MsgType"`
		Event        string `xml:"Event"`
		EventKey     string `xml:"EventKey"`
		Content      string `xml:"Content"`
	}
	if method == "POST" {
		body := this.Ctx.Input.RequestBody
		utils.FileLog.Info("wechat notify:" + string(body))
		item := new(Notify)
		err := xml.Unmarshal(body, &item)
		if err != nil {
			utils.FileLog.Info("xml.Unmarshal:" + err.Error())
		}
		contactMsg := "感谢关注东吴期货研究所\r\n公司地址:上海市黄浦区西藏南路1208号东吴证券大厦19楼\r\n\r\n业务合作:\r\n电话:021-6312 3065\r\n邮箱:lvan@dwqh88.com\r\n邮编:200001"

		var openId, returnResult string
		if item.MsgType != "" {
			openId = item.FromUserName
		}
		xmlTpl := `<xml>
		<ToUserName><![CDATA[%s]]></ToUserName>
		<FromUserName><![CDATA[%s]]></FromUserName>
		<CreateTime>%s</CreateTime>
		<MsgType><![CDATA[text]]></MsgType>
		<Content><![CDATA[%s]]></Content>
		</xml>`
		createTime := strconv.FormatInt(time.Now().Unix(), 10)
		// WxId := "gh_5dc508325c6f" // 弘则投研公众号原始id
		xmlTpl = fmt.Sprintf(xmlTpl, openId, utils.DW_WX_Id, createTime, contactMsg)

		if item.MsgType == "event" {
			switch item.Event {
			case "subscribe":
				fmt.Println("关注")
				go subscribe(openId)
			case "unsubscribe":
				fmt.Println("取消关注")
				go unsubscribe(openId)
			case "CLICK":
				returnResult = xmlTpl
			default:
				utils.FileLog.Info("wechat notify event:" + item.Event)
			}
			this.Ctx.WriteString(xmlTpl)
		} else {
			returnResult = xmlTpl
		}
		this.Ctx.WriteString(returnResult)
	} else {
		this.Ctx.WriteString(echostr)
	}
}

// subscribe 关注后的处理逻辑
func subscribe(openId string) {
	userRecord, err := models.GetUserRecordByOpenId(openId)
	if err != nil && err.Error() != utils.ErrNoRow() {
		fmt.Println("通过openid获取user_record记录失败,err:" + err.Error())
		return
	}
	err = nil

	// openId已存在
	if userRecord != nil {
		if userRecord.UserId > 0 && userRecord.UnionId != "" { //已经绑定了的话,那么就去修改用户状态
			models.UserSubscribe(1, openId)
		} else {
			// 没有绑定的话,那么校验下unionid,然后再去修改
			unionId := userRecord.UnionId
			if unionId == `` {
				wxUserItem, err := wechat.GetUserInfo(openId)
				if err != nil {
					fmt.Println("获取用户信息失败,err:" + err.Error())
					return
				}
				if wxUserItem.UnionID != `` {
					unionId = wxUserItem.UnionID
				}
			}
			userRecord.UnionId = unionId
			userRecord.Subscribe = 1
			userRecord.SubscribeTime = time.Now()
			err = userRecord.Update([]string{"union_id", "subscribe", "subscribe_time"})
			if err != nil {
				fmt.Println("关注后,通过openid更新user_record异常,err:", err)
				return
			}
			user, err := models.GetUserByUnionId(unionId)
			if err != nil {
				fmt.Println("关注后,通过unionid获取user记录失败,err:" + err.Error())
				return
			}
			if user != nil {
				user.IsSubscribed = true
				user.ModifyTime = time.Now()
				err = user.Update([]string{"modify_time", "is_subscribed"})
				if err != nil {
					fmt.Println("关注后,修改绑定用户状态异常,err:", err)
					return
				}
				userRecord.UserId = user.UserId
				userRecord.Update([]string{"user_id"})
			}
		}
		return
	}

	// 没有记录,那么需要获取下unionid
	wxUserItem, err := wechat.GetUserInfo(openId)
	if err != nil {
		fmt.Println("获取用户信息失败,err:" + err.Error())
		return
	}
	newUserRecord := &models.UserRecord{
		OpenId:        openId,
		UnionId:       wxUserItem.UnionID,
		Subscribe:     1,
		SubscribeTime: time.Now(),
		NickName:      wxUserItem.Nickname,
		Sex:           int(wxUserItem.Sex),
		Province:      wxUserItem.Province,
		City:          wxUserItem.City,
		Country:       wxUserItem.Country,
		Headimgurl:    wxUserItem.Headimgurl,
		CreateTime:    time.Now(),
	}
	insertId, err := newUserRecord.Insert()
	newUserRecord.UserRecordId = int(insertId)
	if err != nil {
		fmt.Println("关注后,添加user_record信息失败,err:" + err.Error())
		return
	}
	// 检测用户是否绑定小程序,如果绑定修改用户状态
	user, err := models.GetUserByUnionId(newUserRecord.UnionId)
	if err != nil {
		fmt.Println("修改绑定用户状态异常,ERR:", err)
		return
	}
	if user != nil {
		user.IsRegistered = true
		user.ModifyTime = time.Now()
		err = user.Update([]string{"is_registered", "modify_time"})
		if err != nil {
			fmt.Println("关注后,修改绑定用户状态异常,ERR:", err)
			return
		}
		newUserRecord.UserId = user.UserId
		newUserRecord.Update([]string{"user_id"})
	}

}

// unsubscribe 取消关注后的处理逻辑
func unsubscribe(openId string) {
	userRecord, err := models.GetUserRecordByOpenId(openId)
	if err != nil {
		return
	}
	userRecord.Subscribe = 0
	err = userRecord.Update([]string{"subscribe"})
	if err != nil {
		return
	}
	if userRecord.UnionId != "" {
		user, err := models.GetUserByUnionId(userRecord.UnionId)
		if err != nil {
			return
		}
		if user != nil {
			user.IsSubscribed = false
			user.ModifyTime = time.Now()
			err = user.Update([]string{"is_subscribed", "modify_time"})
			if err != nil {
				return
			}
		}
	}
}

// @Title 微信登录
// @Description 微信登录
// @Param	request	body models.LoginReq true "type json string"
// @Success 200 {object} models.LoginResp
// @router /login [post]
func (this *WechatController) Login() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if err := recover(); err != nil {
			fmt.Println(err)
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()

	var req request.WeChatLoginReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析失败"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}
	if req.Code == "" {
		br.Msg = "授权码不存在"
		return
	}

	userInfo, err := wx_app.GetSession(req.Code)
	if err != nil {
		br.Msg = "登录失败,请重新尝试"
		br.ErrMsg = "用户信息获取失败,系统错误,Err:" + err.Error()
		return
	}
	session, err := models.GetWxSessionByOpenId(userInfo.OpenID)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = "登录失败,请重新尝试"
		br.ErrMsg = "用户信息获取失败,系统错误,Err:" + err.Error()
		return
	}
	if session == nil {
		session = &models.WxSession{
			OpenId:     userInfo.OpenID,
			UnionId:    userInfo.UnionID,
			CreateTime: time.Now(),
		}
		insertId, er := session.Insert()
		session.WxSessionId = int(insertId)
		if er != nil {
			br.Msg = "用户登录失败"
			br.ErrMsg = "用户登录获取失败,系统错误,Err:" + er.Error()
			return
		}
	}
	var token string
	timeUnix := time.Now().Unix()
	timeUnixStr := strconv.FormatInt(timeUnix, 10)
	token = utils.MD5(session.OpenId) + utils.MD5(timeUnixStr)
	session.AccessToken = token
	session.LastUpdateTime = time.Now()
	err = session.Update([]string{"access_token", "last_update_time"})
	if err != nil {
		br.Msg = "微信登录失败"
		br.ErrMsg = "微信登录失败,更新用户信息失败:" + err.Error()
		return
	}
	token = session.AccessToken
	resp := new(response.WeChatLoginResp)
	resp.Authorization = token

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

// @Title 公众号绑定
// @Description 公众号绑定
// @Param	request	body request.WeChatLoginReq true "type json string"
// @Success 200 {object} models.LoginResp
// @router /subscribe [post]
func (this *WechatController) Subscribe() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.Ret != 200 {
			b, _ := json.Marshal(br)
			alarm_msg.SendAlarmMsg(string(b), 1)
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()

	var req request.WeChatLoginReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析失败"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}
	if req.Code == "" {
		br.Msg = "授权码不存在"
		return
	}
	info, err := wechat.GetWxUserInfo(req.Code)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取失败,Err:" + err.Error()
		return
	}
	if info.ErrCode != 0 {
		br.Msg = "获取失败"
		br.ErrMsg = "获取失败,Err:" + info.ErrMsg
		return
	}
	userRecord, err := models.GetUserRecordByOpenId(info.OpenId)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = "获取用户关注记录失败"
		br.ErrMsg = "获取用户关注记录失败,Err:" + err.Error()
		return
	}
	// 如果不存在就新增一条记录
	if userRecord == nil {
		userRecord := &models.UserRecord{
			OpenId: info.OpenId,
		}
		insertId, err := userRecord.Insert()
		if err != nil {
			br.Msg = "新增失败"
			br.ErrMsg = "新增失败,Err:" + err.Error()
			return
		}
		userRecord.UserRecordId = int(insertId)
	}
	if userRecord.UnionId == "" {
		wxInfo, er := wechat.GetUserInfo(userRecord.OpenId)
		if er != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取失败,Err:" + er.Error()
			return
		}
		userRecord.UnionId = wxInfo.UnionID
		er = userRecord.Update([]string{"union_id"})
		if er != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取失败,Err:" + er.Error()
			return
		}

	}
	user, err := models.GetUserByUnionId(userRecord.UnionId)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = "获取用户信息失败"
		br.ErrMsg = "获取用户信息失败,Err:" + err.Error()
		return
	}
	if user != nil {
		user.IsSubscribed = true
		err := user.Update([]string{"is_subscribed"})
		if err != nil {
			br.Msg = "更新用户信息失败"
			br.ErrMsg = "更新用户信息失败,Err:" + err.Error()
			return
		}
		userRecord.UserId = user.UserId
		userRecord.Update([]string{"user_id"})
	}

	br.Msg = "获取成功"
	br.Success = true
	br.Ret = 200
}