package configchange

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"time"

	"github.com/tidbcloud/tiinf/transport/crossregion"
	"sigs.k8s.io/controller-runtime/pkg/log"

	"github.com/tidbcloud/infra-provider/pkg/config"
)

const (
	DBUserCloudAdmin = "cloud_admin"
)

func newCloudAdminPasswdGetter(conf *config.ConfigChangeConfig) CloudAdminPasswdGetter {
	return &getCloudAdminPasswdFromAccountSvc{
		conf: conf,
	}
}

type getCloudAdminPasswdFromAccountSvc struct {
	conf *config.ConfigChangeConfig
}

func (g *getCloudAdminPasswdFromAccountSvc) GetCloudAdminPasswd(ctx context.Context, clusterID string) (string, error) {
	const (
		getCloudAdminPasswdPath = "/inner/account-central/api/v1/cloudadmin-passwd"
		timeoutSec              = 10 * time.Second
	)
	logger := log.FromContext(ctx)
	envType := crossregion.EnvType(g.conf.AccountEnv)
	authKey := os.Getenv(config.EnvKeyAccountXRegionAuthKey)
	if authKey == "" {
		return "", fmt.Errorf("account cross region auth key is not provided")
	}

	logger.Info("get cloud admin passwd from account")
	client := crossregion.NewBasicAuthClient(envType, authKey, timeoutSec)
	params := map[string]string{
		"cluster_id": clusterID,
	}
	respStr, httpCode, err := client.GetGlobal(ctx, getCloudAdminPasswdPath, &params)
	if err != nil {
		logger.Error(err, "call global account")
		return "", err
	}
	if httpCode != http.StatusOK {
		return "", fmt.Errorf("call global account failed, code=%d", httpCode)
	}

	logger.Info("call global account", "code", httpCode)
	type response struct {
		Passwd string `json:"passwd"`
	}
	resp := &response{}
	if err := json.Unmarshal([]byte(respStr), resp); err != nil {
		logger.Error(err, "unmarshal account response")
		return "", err
	}
	return resp.Passwd, nil
}
