package subscriber

import (
	"context"
	"slices"

	eb_event "github.com/tidbcloud/eventbus-datastruct/event"
	"github.com/tidbcloud/pkgv2/log"
	"github.com/tidbcloud/serverless-service/internal/config"
	"github.com/tidbcloud/serverless-service/internal/domain/constant"
	eb "github.com/tidbcloud/serverless-service/internal/infra/eventbus"
	"github.com/tidbcloud/serverless-service/internal/service/event_svc"
	"github.com/tidbcloud/tiinf/transport/tieventbus"
	"go.uber.org/zap"
)

const (
	SpendLimitGroup     = "default-consumer"
	SpendLimitEventType = "spend-limit"
)

type ClusterSpendLimitEventSubscriber struct {
	subscriber eb.Subscriber[eb_event.SpendLimitEvent]
}

func NewClusterSpendLimitEventSubscriber(
	eventbus tieventbus.Eventbus,
) *ClusterSpendLimitEventSubscriber {
	return &ClusterSpendLimitEventSubscriber{
		subscriber: eb.Subscriber[eb_event.SpendLimitEvent]{
			Eventbus: eventbus,
		},
	}
}

func (s *ClusterSpendLimitEventSubscriber) RegisterHandlers(handlers ...eb.EventHandler[eb_event.SpendLimitEvent]) {
	s.subscriber.RegisterHandlers(SpendLimitGroup, SpendLimitEventType, handlers...)
}

type SpendLimitEventHandler struct {
	spendLimitSvc *event_svc.SpendLimitService
}

func NewSpendLimitEventHandler(spendLimitSvc *event_svc.SpendLimitService) *SpendLimitEventHandler {
	return &SpendLimitEventHandler{spendLimitSvc: spendLimitSvc}
}

func (h *SpendLimitEventHandler) Handle(ctx context.Context, e *eb_event.SpendLimitEvent) error {
	logger := log.WithContextL(ctx).With(zap.Any("SpendLimitEventHandler", e))
	logger.Info("receive new event")
	if e.RangeID == 0 ||
		e.RangeType != constant.SpendLimitRangeTypeCluster ||
		e.BizType != constant.SpendLimitBizType_ServerlessCluster ||
		!slices.Contains(constant.SpendLimitValidStatuses, e.Status) {
		logger.Info("ignore unexpected event")
		return nil
	}
	newCtx := context.WithValue(ctx, config.CtxWorkerNameKey, "spendLimitEventHandler")
	logger.Info("handle serverless cluster event")
	return h.spendLimitSvc.UpdateTidbPoolPolicy(newCtx, e)
}
