package cachesvc

import (
	"context"
	"encoding/json"
	"fmt"
	"time"

	"github.com/redis/go-redis/v9"
	"github.com/tidbcloud/tiinf/errs"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"

	"github.com/tidbcloud/aipower/commons/config"
	"github.com/tidbcloud/aipower/idl/pbgen/proto/api"
)

var (
	redisClient *redis.Client
)

func InitRedisClient() error {
	conf := config.Global().ServerConf

	options, err := redis.ParseURL(conf.RedisURI)
	if err != nil {
		return err
	}

	redisClient = redis.NewClient(options)
	return nil
}

func genAIPowerCacheKey(jobID string) string {
	return fmt.Sprintf("aipower:%s", jobID)
}

func ReadCompletionResultByJobID(ctx context.Context, jobID string) (string, error) {
	key := genAIPowerCacheKey(jobID)
	fullCompletion, err := redisClient.Get(ctx, key).Result()
	tilog.Info(ctx, "query completion from redis", zap.String("jobID", jobID), zap.String("completion", fullCompletion), zap.Error(err))
	if err != nil {
		if errs.IsError(err, redis.Nil) {
			return "", errs.NewNotFound("completion not found", err)
		}

		return "", errs.NewInternalDB("failed to query completion", err)
	}

	return fullCompletion, nil
}

func SaveCompletionResult(ctx context.Context, jobID string, completionResp *api.QueryCompletionResp) {
	tilog.Info(ctx, "start to save completion result", zap.Any("completionResp", completionResp), zap.String("jobID", jobID))

	completionRespBytes, err := json.Marshal(&completionResp)
	if err != nil {
		tilog.Error(ctx, "failed to marshal completion resp", zap.Error(err))
		return
	}

	// save in redis...
	key := genAIPowerCacheKey(jobID)
	// use a new context here to avoid timeout caused "context deadline exceeded"
	err = redisClient.SetEx(context.TODO(), key, string(completionRespBytes), time.Hour*time.Duration(7*24)).Err()
	tilog.Info(ctx, "save completion result complete", zap.Any("completionResp", completionResp), zap.String("jobID", jobID), zap.Error(err))
}
