package utils

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

	"github.com/tidbcloud/tiinf/errs"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"
)

var (
	urlFormat = "http://devops-server.devops:8088/api/v1/devops-internal/tenants/%d"

	client = &http.Client{
		Timeout: time.Second * 2,
	}
)

func GetOrgAccountManager(ctx context.Context, orgID uint64) string {
	manager, err := GetOrgAccountManagerFromOps(ctx, orgID)
	if err != nil {
		tilog.Warn(ctx, "GetOrgAccountManagerFromOps error", zap.Any("orgID", orgID), zap.Any("err", err))
		return ""
	}
	tilog.Info(ctx, "GetOrgAccountManager get account manager", zap.Any("orgID", orgID), zap.Any("manager", manager))
	return manager
}

func GetOrgAccountManagerFromOps(ctx context.Context, orgID uint64) (string, error) {
	url := fmt.Sprintf(urlFormat, orgID)
	req, _ := http.NewRequest("GET", url, nil)
	rsp, err := client.Do(req)
	if err != nil {
		tilog.Warn(ctx, "GetOrgAccountManager request error", zap.Any("orgID", orgID), zap.Any("err", err))
		return "", err
	}
	defer func() {
		err := rsp.Body.Close()
		if err != nil {
			tilog.Warn(ctx, "GetOrgAccountManager close body error", zap.Any("err", err))
		}
	}()

	httpCode := rsp.StatusCode
	bodyB, err := io.ReadAll(rsp.Body)
	if err != nil {
		tilog.Warn(ctx, "GetOrgAccountManager read body error", zap.Any("err", err))
		return "", err
	}
	body := string(bodyB)
	tilog.Info(ctx, "GetOrgAccountManager response", zap.Any("httpCode", httpCode), zap.Any("rspBody", body), zap.Any("url", url))

	if rsp.StatusCode != 200 {
		return "", errs.NewInternalUnknown(fmt.Sprintf("ops return http code not 200: %s", body), nil)
	}

	var data map[string]interface{}
	err = json.Unmarshal(bodyB, &data)
	if err != nil {
		tilog.Warn(ctx, "GetOrgAccountManager unmarshal body error", zap.Any("rspBody", body), zap.Any("err", err))
		return "", err
	}
	mangerI, ok := data["sales_owner_email"]
	if !ok {
		return "", errs.NewInternalUnknown("ops not return sales_owner_email", nil)
	}
	manager, ok := mangerI.(string)
	if !ok {
		return "", errs.NewInternalUnknown("ops return sales_owner_email not string", nil)
	}

	return manager, nil
}
