package userbehavior

import (
	"context"
	"fmt"

	"github.com/expr-lang/expr"
	larkcard "github.com/larksuite/oapi-sdk-go/v3/card"
	ubent "github.com/tidbcloud/devops/entity/userbehavior"
	evbus "github.com/tidbcloud/eventbus-datastruct/event"
)

type restoreUBEvent struct {
	originEv                 *evbus.DisplayEvent
	tenantName               *string
	tenantID                 uint64
	tenantAlias              *string
	bizRegion                *string
	clusterID                uint64
	clusterName              *string
	restoreBehaviorPredicate *string
	extraInfo                string
}

var acceptedRestoreEvents = []evbus.EventStatus{
	evbus.EventStatusSucceeded,
	evbus.EventStatusFailed,
}

func (event *restoreUBEvent) HandleUBEvent(ctx context.Context) error {
	return nil
}

func (event *restoreUBEvent) PreProcess(ctx context.Context) error {
	return nil
}

func (event *restoreUBEvent) PostProcess(ctx context.Context) error {
	return nil
}

func (event *restoreUBEvent) ProcessTemplate(ctx context.Context, template string) (string, error) {
	return template, nil
}

func (event *restoreUBEvent) DefaultText(ctx context.Context) string {
	var tenantName, tenantAlias string
	if event.tenantName != nil {
		tenantName = *event.tenantName
	}
	if event.tenantAlias != nil {
		tenantAlias = *event.tenantAlias
	}

	return fmt.Sprintf("[** %s **] Tenant** %s **(%d, alias: %s) ** %s ** a restore. Cluster: ** %s **(%d)\nDetail: %s",
		*event.bizRegion,
		tenantName,
		event.tenantID,
		tenantAlias,
		*event.restoreBehaviorPredicate,
		*event.clusterName,
		event.clusterID,
		event.extraInfo,
	)
}

func (event *restoreUBEvent) GetAvailableParams(ctx context.Context) []string {
	return clusterEventParams
}

func (event *restoreUBEvent) GetUBEventType() ubent.UBEventTp {
	return ubent.UBEventRestore
}

func (event *restoreUBEvent) CustomFilter(ctx context.Context, textFilter string) (ret bool, err error) {
	program, err := expr.Compile(textFilter)
	if err != nil {
		return ret, err
	}

	output, err := expr.Run(program, event.originEv)
	if err != nil {
		return ret, err
	}
	ret, ok := output.(bool)
	if !ok {
		return ret, fmt.Errorf("not return a bool type")
	}

	return ret, nil
}

func newRestoreUBEvent(ev *evbus.DisplayEvent) UBEvent {
	ubEvent := restoreUBEvent{
		originEv:                 ev,
		tenantName:               nil,
		tenantAlias:              nil,
		bizRegion:                nil,
		tenantID:                 ev.TenantID,
		clusterID:                ev.ClusterID,
		restoreBehaviorPredicate: (*string)(&ev.DisplayStatus),
		extraInfo:                ev.Summary,
	}

	return &ubEvent
}

func (e *restoreUBEvent) BuildCustomCard(ctx context.Context) (*larkcard.MessageCard, error) {
	return nil, nil // Use standard card
}
