package service

import (
	"context"
	"encoding/base64"
	"errors"
	"gadmin/config"
	"gadmin/internal/admin/forms"
	"gadmin/internal/admin/library/feishu"
	"gadmin/internal/gorm/model"
	"gadmin/internal/gorm/query"
	"gadmin/utility/serializer"
	"gadmin/utility/token"
	"github.com/gin-gonic/gin"
	jsoniter "github.com/json-iterator/go"
	"github.com/larksuite/oapi-sdk-go/v3/core"
	"github.com/larksuite/oapi-sdk-go/v3/service/authen/v1"
	"github.com/sirupsen/logrus"
	"gorm.io/gorm"
	"strings"
	"time"
)

var FeiShu = new(feishuService)

type feishuService struct{}

func (s *feishuService) FeiShuUserLogin(c *gin.Context) serializer.Response {

	q := query.Use(config.AdminDB).AdminUser

	//encodeToken := token.GetAuthorization(c)
	//if encodeToken != "" {
	//	bytesT, err := base64.URLEncoding.DecodeString(encodeToken)
	//	if err != nil {
	//		logrus.Warningf("middleware base64.URLEncoding.DecodeString:%+v", err.Error())
	//		return serializer.CheckLogin()
	//	}
	//	t := string(bytesT)
	//	tokenKey := config.GetTokenKey(t)
	//	if config.TokenRedis.Exists(tokenKey).Val() == 0 {
	//		return serializer.CheckLogin()
	//	}
	//	userStr := config.TokenRedis.Get(tokenKey).Val()
	//
	//	claims := new(token.UserClaims)
	//	if err := jsoniter.UnmarshalFromString(userStr, claims); err != nil {
	//		return serializer.CheckLogin()
	//	}
	//
	//	// 查询登录token是否有效
	//	key := config.GetUserTokenKey(claims.ID)
	//	tokenCTStr := config.TokenRedis.HGet(key, t).Val()
	//	tokenCreateTime, err := strconv.Atoi(tokenCTStr)
	//	if err != nil {
	//		logrus.Warningf("middleware config.LogRedis.HGet:%+v", err.Error())
	//		return serializer.CheckLogin()
	//	}
	//	tokenCT := time.Unix(int64(tokenCreateTime), 0)
	//
	//	if tokenCT.Before(time.Now().Add(-config.TokenExpireTime)) {
	//		return serializer.CheckLogin()
	//	}
	//
	//	u, err := q.Where(q.ID.Eq(claims.ID)).First()
	//	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
	//		return serializer.Err(2, "", err)
	//	}
	//	if u.Status != 1 {
	//		return serializer.ParamErr("账号已被禁用", nil)
	//	}
	//	user := &token.UserClaims{
	//		ID:          u.ID,
	//		UserName:    u.UserName,
	//		RoleId:      int64(u.RoleID),
	//		Avatar:      u.Avatar,
	//		Nickname:    u.Nickname,
	//		AccessToken: t,
	//	}
	//	userStr, _ = jsoniter.MarshalToString(user)
	//
	//	config.TokenRedis.HSet(key, t, time.Now().Unix())
	//	config.TokenRedis.Expire(key, time.Hour*12)
	//
	//	config.TokenRedis.Set(tokenKey, userStr, time.Hour*12)
	//
	//	return serializer.Suc(forms.UserLoginRes{
	//		ID:       u.ID,
	//		UserName: u.UserName,
	//		Nickname: u.Nickname,
	//		Status:   u.Status,
	//		Avatar:   u.Avatar,
	//		Token:    encodeToken,
	//	})
	//}

	code := c.Query("code")
	if code == "" {
		return serializer.ParamErr("code is empty", nil)
	}

	feishuUserInfo, err := s.GetFeiShuUserByCode(code)
	if err != nil {
		return serializer.Err(1, "", err)
	}
	if feishuUserInfo == nil {
		return serializer.Err(1, "获取用户信息失败", nil)
	}

	u, err := q.Where(q.FeishuUnionID.Eq(*feishuUserInfo.UnionId)).First()
	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
		return serializer.Err(2, "", err)
	}
	if u == nil {
		// 不存在，创建
		u = &model.AdminUser{
			UserName: *feishuUserInfo.Name,
			Nickname: *feishuUserInfo.Name,
			Avatar:   *feishuUserInfo.AvatarUrl,
			//Mobile:        *feishuUserInfo.Mobile,
			FeishuUnionID: *feishuUserInfo.UnionId,
			CreatedAt:     time.Now(),
		}
		if err = q.WithContext(context.Background()).Create(u); err != nil {
			return serializer.DBErr(err.Error(), err)
		}

		return serializer.Err(9999, "注册成功，请联系管理员分配权限!", nil)
	}
	if u.Status != 1 {
		return serializer.ParamErr("账号已被禁用", nil)
	}
	if u.RoleID == 0 {
		return serializer.Err(9999, "请联系管理员分配权限!", nil)
	}

	t := token.GenerateTokenUsingUUID()

	// 记录登录token
	key := config.GetUserTokenKey(u.ID)
	config.TokenRedis.HSet(key, t, time.Now().Unix())
	config.TokenRedis.Expire(key, time.Hour*12)

	tokenKey := config.GetTokenKey(t)
	user := &token.UserClaims{
		ID:          u.ID,
		UserName:    u.UserName,
		RoleId:      int64(u.RoleID),
		Avatar:      u.Avatar,
		Nickname:    u.Nickname,
		AccessToken: t,
	}
	userStr, err := jsoniter.MarshalToString(user)
	if err != nil {
		return serializer.Err(1, "", err)
	}
	config.TokenRedis.Set(tokenKey, userStr, time.Hour*12)

	return serializer.Suc(forms.UserLoginRes{
		ID:       u.ID,
		UserName: u.UserName,
		Nickname: u.Nickname,
		Status:   u.Status,
		Avatar:   u.Avatar,
		Token:    base64.URLEncoding.EncodeToString([]byte(t)),
	})

}

func (s *feishuService) GetFeiShuUserByCode(code string) (*larkauthen.GetUserInfoRespData, error) {
	// 使用获取到的 code 获取 token
	req := larkauthen.NewCreateAccessTokenReqBuilder().Body(
		larkauthen.NewCreateAccessTokenReqBodyBuilder().
			GrantType("authorization_code").
			Code(code).
			Build(),
	).Build()
	resp, err := feishu.LarkClient.Authen.V1.AccessToken.Create(context.Background(), req)
	if err != nil {
		logrus.Warnf("GetAccessToken() failed with '%s'\n", err)
		return nil, err
	}
	if !resp.Success() {
		logrus.Warnf("logId: %s, error response: \n%s", resp.RequestId(), larkcore.Prettify(resp.CodeError))
		return nil, err
	}

	userInfoResp, err := feishu.LarkClient.Authen.V1.UserInfo.Get(context.Background(), larkcore.WithUserAccessToken(*resp.Data.AccessToken))
	// 处理错误
	if err != nil {
		logrus.Warnf("GetUserInfo() failed with '%s'\n", err)
		return nil, err
	}

	// 服务端错误处理
	if !userInfoResp.Success() {
		logrus.Warnf("logId: %s, error response: \n%s", userInfoResp.RequestId(), larkcore.Prettify(userInfoResp.CodeError))
		return nil, errors.New(larkcore.Prettify(userInfoResp.CodeError))
	}

	return userInfoResp.Data, nil
}

// 取出手机号码
func extractPhoneNumber(phone string) string {
	// 定义可能的国际前缀列表
	prefixes := []string{"+86", "86"}

	for _, prefix := range prefixes {
		if strings.HasPrefix(phone, prefix) {
			// 如果手机号以该前缀开头，则返回去掉前缀后的部分
			return strings.TrimPrefix(phone, prefix)
		}
	}

	// 如果没有匹配的前缀，直接返回原号码
	return phone
}
