package services_miniprogram

import (
	"fmt"
	"time"

	"mini-chat/internal/pkg/core"
	"mini-chat/internal/pkg/miniprogram"
	"mini-chat/internal/repository/mysql/model"

	"go.uber.org/zap"
	"gorm.io/gorm"
)

func (s *service) GetAccessToken(appID, appSecret string, ctx core.Context) (string, error) {
	info, err := s.readDB.MiniProgramAccessToken.WithContext(ctx.RequestContext()).
		Where(s.readDB.MiniProgramAccessToken.AppID.Eq(appID)).
		Where(s.readDB.MiniProgramAccessToken.ExpiredAt.Gte(time.Now())).First()
	if err != nil && err != gorm.ErrRecordNotFound {
		return "", err
	}

	accessToken := ""

	if err == gorm.ErrRecordNotFound {
		// 生成 access_token
		accessTokenResponse := new(miniprogram.AccessTokenResponse)
		if err := miniprogram.GetAccessToken(appID, appSecret, accessTokenResponse); err != nil {
			s.logger.Error("GetAccessToken failed", zap.Error(err))
			return "", err
		}

		if accessTokenResponse.AccessToken == "" {
			return "", fmt.Errorf("access_token is empty")
		}

		// 保存 access_token
		accessTokenData := new(model.MiniProgramAccessToken)
		accessTokenData.AppID = appID
		accessTokenData.AccessToken = accessTokenResponse.AccessToken
		accessTokenData.CreatedAt = time.Now()
		accessTokenData.ExpiredAt = time.Now().Add(time.Duration(accessTokenResponse.ExpiresIn) * time.Second)
		if err := s.writeDB.MiniProgramAccessToken.WithContext(ctx.RequestContext()).Create(accessTokenData); err != nil {
			return "", err
		}

		accessToken = accessTokenResponse.AccessToken
	} else {
		accessToken = info.AccessToken
	}

	return accessToken, nil
}
