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 BackupType = string

const (
	AutoBackup   BackupType = "auto-backup"
	FinalBackup  BackupType = "final-backup"
	LogBackup    BackupType = "log-backup"
	ManualBackup BackupType = "manual-backup"
)

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

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

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

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

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

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

func (event *backupUBEvent) 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 backup. Cluster: ** %s **(%d)\nDetail: %s",
		*event.bizRegion,
		tenantName,
		event.tenantID,
		tenantAlias,
		*event.backupBehaviorPredicate,
		*event.clusterName,
		event.clusterID,
		event.extraInfo,
	)
}

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

func (event *backupUBEvent) GetUBEventType() ubent.UBEventTp {
	return ubent.UBEventBackup
}

func (event *backupUBEvent) 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 newBackupUBEvent(ev *evbus.DisplayEvent) UBEvent {
	ubEvent := backupUBEvent{
		originEv:                ev,
		tenantName:              nil,
		tenantAlias:             nil,
		bizRegion:               nil,
		tenantID:                ev.TenantID,
		clusterID:               ev.ClusterID,
		backupBehaviorPredicate: (*string)(&ev.DisplayStatus),
		extraInfo:               ev.Summary,
	}

	return &ubEvent
}

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