package dingtalk

import (
	errorcode "ai_scheduler/internal/data/error"
	"ai_scheduler/utils"
	"context"
	"fmt"
	"time"

	openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
	oauth2 "github.com/alibabacloud-go/dingtalk/oauth2_1_0"
	"github.com/alibabacloud-go/tea/tea"
	"github.com/redis/go-redis/v9"
)

type Oauth2Client struct {
	cli      *oauth2.Client
	redisCli *redis.Client
}

func NewOauth2Client(rds *utils.Rdb) (*Oauth2Client, error) {
	cfg := &openapi.Config{
		Protocol: tea.String("https"),
		RegionId: tea.String("central"),
	}
	c, err := oauth2.NewClient(cfg)
	if err != nil {
		return nil, err
	}
	return &Oauth2Client{cli: c, redisCli: rds.Rdb}, nil
}

type AppKey struct {
	AppKey      string `json:"appKey"`
	AppSecret   string `json:"appSecret"`
	AccessToken string `json:"accessToken"`
}

// GetAccessToken 获取access token
func (c *Oauth2Client) GetAccessToken(req AppKey) (string, error) {
	// 兼容直接传入 access token 场景
	if req.AccessToken != "" {
		return req.AccessToken, nil
	}

	// 取cache
	ctx := context.Background()
	accessToken, err := c.redisCli.Get(ctx, fmt.Sprintf("dingtalk:oauth2:%s:access_token", req.AppKey)).Result()
	if err == nil {
		fmt.Println("get access token from cache:", accessToken)
		return accessToken, nil
	}
	if err != redis.Nil {
		return "", err
	}

	// 调用API
	resp, err := c.cli.GetAccessToken(&oauth2.GetAccessTokenRequest{
		AppKey:    tea.String(req.AppKey),
		AppSecret: tea.String(req.AppSecret),
	})
	if err != nil {
		return "", err
	}

	if resp.Body == nil {
		return "", errorcode.ParamErrf("empty response body")
	}

	// 缓存token
	c.redisCli.Set(ctx, fmt.Sprintf("dingtalk:oauth2:%s:access_token", req.AppKey), *resp.Body.AccessToken, time.Duration(*resp.Body.ExpireIn)*time.Second)

	return *resp.Body.AccessToken, nil
}
