package qywx

import (
	"ai_scheduler/internal/config"
	"ai_scheduler/internal/data/constants"
	"ai_scheduler/internal/pkg/l_request"
	"ai_scheduler/utils"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"time"

	"github.com/redis/go-redis/v9"
)

type Auth struct {
	redis *redis.Client
	cfg   *config.Config
}

func NewAuth(cfg *config.Config, redis *utils.Rdb) *Auth {
	return &Auth{
		redis: redis.Rdb,
		cfg:   cfg,
	}
}

func (a *Auth) GetAccessToken(ctx context.Context, corpid string, corpsecret string) (authInfo *AuthInfo, err error) {
	if corpid == "" {
		return nil, errors.New("corpid  is empty")
	}
	accessToken := a.redis.Get(ctx, a.getKey(corpsecret)).Val()
	var expire time.Duration
	if accessToken == "" {
		authRes, _err := a.getNewAccessToken(ctx, corpid, corpsecret)
		if _err != nil {
			return nil, _err
		}
		expire = time.Duration(authRes.ExpiresIn-60) * time.Second
		err = a.redis.SetEx(ctx, a.getKey(corpsecret), authRes.AccessToken, expire).Err()
		if err != nil {
			return
		}
		accessToken = authRes.AccessToken
	} else {
		expire, _ = a.redis.TTL(ctx, a.getKey(corpsecret)).Result()
	}
	return &AuthInfo{
		Corpid:      corpid,
		Corpsecret:  corpsecret,
		AccessToken: accessToken,
		Expire:      expire,
	}, nil
}

func (a *Auth) getKey(corpsecret string) string {
	return a.cfg.Redis.Key + ":" + constants.QywxAuthBaseKeyPrefix + ":" + corpsecret
}

func (a *Auth) getNewAccessToken(ctx context.Context, corpid string, corpsecret string) (auth AuthRes, err error) {
	if corpid == "" || corpsecret == "" {
		err = errors.New("corpid or corpsecret  is empty")
		return
	}

	req := l_request.Request{
		Method: http.MethodGet,
		Url:    "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + corpid + "&corpsecret=" + corpsecret,
	}
	res, err := req.Send()
	if err != nil {
		return
	}
	err = json.Unmarshal(res.Content, &auth)
	if auth.Errcode != 0 {
		err = fmt.Errorf("请求失败：%s", auth.Errmsg)
		return
	}
	return
}

type UploadMediaRes struct {
	Errcode   int    `json:"errcode"`
	Errmsg    string `json:"errmsg"`
	Type      string `json:"type"`
	MediaId   string `json:"media_id"`
	CreatedAt string `json:"created_at"`
}
