package app

import (
	"context"
	"encoding/json"
	"fmt"
	"git.echol.cn/loser/logger/log"
	"github.com/gin-gonic/gin"
	"miniapp/global"
	"miniapp/model/app/request"
	"miniapp/model/common/constant"
	r "miniapp/model/common/response"
	"miniapp/oauth2"
	"miniapp/service"
	"net/http"
	"net/url"
	"strconv"
)

type LoginApi struct{}

// Login 登录
func (l *LoginApi) Login(ctx *gin.Context) {
	var p request.Login
	if err := ctx.ShouldBind(&p); err != nil {
		r.FailWithMessage(err.Error(), ctx)
		return
	}
	// 获取用户基础账号信息

	userId, err := oauth2.OAuthServer.UserAuthorizationHandler(ctx.Writer, ctx.Request)
	if err != nil {
		log.Errorf("获取用户基础账号信息失败: %v", err)
		r.FailWithMessage(err.Error(), ctx)
		return
	}
	// 重新组装登录参数
	ctx.Request.Form = url.Values{
		"username":   {userId},
		"password":   {p.Password},
		"scope":      {"ALL"},
		"grant_type": {"password"},
		"nickName":   {p.NickName},
		"avatarUrl":  {p.AvatarUrl},
	}

	// 参数解析成功，进行登录
	if err = oauth2.OAuthServer.HandleTokenRequest(ctx.Writer, ctx.Request); err != nil {
		log.Errorf("登录失败：%s", err.Error())
		r.FailWithMessage(err.Error(), ctx)
		return
	}
	// 登录成功才更新登录时间
	if ctx.Writer.Status() == http.StatusOK {
		// 登录成功，更新登录时间和IP
		uid, _ := strconv.Atoi(userId)
		go service.ServiceGroupApp.AppServiceGroup.UserService.UpdateLastLoginInfo(uid)
	}

}

// Refresh 刷新登录Token
func (l *LoginApi) Refresh(ctx *gin.Context) {
	var p request.RefreshToken
	if err := ctx.ShouldBind(&p); err != nil {
		r.FailWithMessage("参数错误: "+err.Error(), ctx)
		return
	}

	// 刷新Token
	if err := oauth2.OAuthServer.HandleTokenRequest(ctx.Writer, ctx.Request); err != nil {
		log.Errorf("Token数据返回失败: %v", err.Error())

		r.FailWithMessage(err.Error(), ctx)
	}
}

// Logout 退出登录
func (l *LoginApi) Logout(ctx *gin.Context) {
	log.Debug("退出登录啦")
	// Token字符串前缀
	const bearerSchema string = "Bearer "
	// 取出Token
	tokenHeader := ctx.Request.Header.Get("Authorization")
	tokenStr := tokenHeader[len(bearerSchema):]
	// 取出原始RedisKey
	baseDataId, err := global.GVA_REDIS.Get(context.Background(), constant.OAuth2RedisKey+tokenStr).Result()
	if err != nil {
		r.FailWithMessage("Token信息获取失败", ctx)
		return
	}
	baseDataStr, err := global.GVA_REDIS.Get(context.Background(), constant.OAuth2RedisKey+baseDataId).Result()
	if err != nil {
		r.FailWithMessage("Token信息获取失败", ctx)
		return
	}
	// 转换数据为Map
	tokenData := make(map[string]any)
	if err = json.Unmarshal([]byte(baseDataStr), &tokenData); err != nil {
		r.FailWithMessage("系统错误: "+err.Error(), ctx)
		return
	}
	// 删除Redis缓存的数据
	global.GVA_REDIS.Del(context.Background(), constant.OAuth2RedisKey+baseDataId)
	global.GVA_REDIS.Del(context.Background(), fmt.Sprintf("%v%v", constant.OAuth2RedisKey, tokenData["Access"]))
	global.GVA_REDIS.Del(context.Background(), fmt.Sprintf("%v%v", constant.OAuth2RedisKey, tokenData["Refresh"]))

	r.Ok(ctx)
}

func (l *LoginApi) GetWeChatToken(c *gin.Context) {
	wechaetToken, err := http.Get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx3d38ce1103a82225&secret=3c41ca428b4d0f43cfaef6f567a1cc06")
	if err != nil {
		log.Errorf("获取微信Token失败: %v", err)
		r.FailWithMessage(err.Error(), c)
		return
	}

	r.OkWithData(wechaetToken, c)
}
