package utils

import (
	"net/http"
	"slices"
	"strings"
	"sync"

	"github.com/go-resty/resty/v2"
	"github.com/pingcap/log"
	"github.com/tidbcloud/serverless-service/internal/config"
	"go.uber.org/zap"
)

const (
	LarkMsgLevelInfo  = "info"
	LarkMsgLevelWarn  = "warn"
	LarkMsgLevelError = "error"
)

var (
	once            sync.Once
	LarkBotWebHooks = []string{"https://open.feishu.cn/open-apis/bot/v2/hook/4eb35fc4-9723-4fcd-a39b-97ae07db72f3"}
	LarkHeaderColor = map[string]string{
		LarkMsgLevelInfo:  "blue",
		LarkMsgLevelWarn:  "yellow",
		LarkMsgLevelError: "red",
	}
	NotifyBlockTenantIDs = map[uint64]bool{
		/* Prod */
		1372813089209260919: true, // manus
		1372813089209245725: true, // dify
		1372813089187791289: true, // dbaastest3
		1372813089209061418: true, // QA PingCAP
		1372813089208191698: true, // disksing
		1372813089208521817: true, // Autonomous Test1
		1372813089187041280: true, // pingcap-prod
		1372813089209302377: true, // TiDB Cloud Zero Prod
		1372813089209301246: true, // kimi
		1372813089209300444: true, // mulerun.ai
		/* Staging */
		1369847559691427383: true, // dbaastest2
		1369847559690857266: true, // dbaastest3
		1369847559691397265: true, // dedicated test
		/* dev */
		60205: true, // dbaastest2
		30008: true, // dbaastest3
	}
)

func IsNotifyBlockTenantsAndEnv(tenantId uint64) bool {
	if config.Global().BizConfig.BillingLargeTenants != nil &&
		slices.Contains(config.Global().BizConfig.BillingLargeTenants, tenantId) {
		return true
	}

	// ignore dev/staging stage
	if stage := config.Global().ServerConfig.Stage; stage == config.StageDev || stage == config.StageStaging {
		return true
	}

	return NotifyBlockTenantIDs[tenantId]
}

// SendLarkMessage sends a card message to lark via bot webhook.
// if you want to use this in `defer` statement, put it into goroutine.
func SendLarkMessage(title, message, level string) {
	log.Info("send lark msg start", zap.String("message", message))
	if !config.Global().ServerConfig.EnableLarkMsg {
		log.Info("EnableLarkMsg disabled")
		return
	}
	once.Do(func() {
		if strings.ToUpper(config.Global().ServerConfig.Stage) == "PROD" {
			// Serverless Service Team Group
			LarkBotWebHooks = append(
				LarkBotWebHooks,
				"https://open.feishu.cn/open-apis/bot/v2/hook/c71759d4-4c87-4327-887a-c7ed82666e63",
			)
		}
	})
	color, ok := LarkHeaderColor[level]
	if !ok {
		color = LarkHeaderColor[LarkMsgLevelInfo]
	}

	param := map[string]any{
		"msg_type": "interactive",
		"card": map[string]any{
			"header": map[string]any{
				"template": color,
				"title":    map[string]any{"content": title, "tag": "plain_text"},
			},
			"elements": []map[string]any{{
				"tag":  "div",
				"text": map[string]any{"content": message, "tag": "plain_text"},
			}},
		},
	}
	request := resty.New().R().SetBody(param)
	for _, LarkBotWebHook := range LarkBotWebHooks {
		resp, err := request.Execute(resty.MethodPost, LarkBotWebHook)
		if err != nil || resp.StatusCode() != http.StatusOK {
			log.Error("send lark msg failed", zap.Error(err), zap.String("web hook", LarkBotWebHook))
		} else {
			log.Info("send lark msg succeed", zap.String("body", resp.String()), zap.String("web hook", LarkBotWebHook))
		}
	}
}
