package userbehavior

import (
	"context"
	"fmt"

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

type tenantPlanUBEvent struct {
	event.TenantPlanEvent

	tenantAlias *string
	tenantName  *string
	bizRegion   *string
}

var tenantPlanEventParams = []string{
	"tenant_id",
	"old_plan",
	"new_plan",
	"tenant_alias",
}

func (planEvent *tenantPlanUBEvent) HandleUBEvent(ctx context.Context) error {
	return nil
}

func (planEvent *tenantPlanUBEvent) PreProcess(ctx context.Context) error {
	return nil
}

func (planEvent *tenantPlanUBEvent) PostProcess(ctx context.Context) error {
	return nil
}

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

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

	tenantMsg := fmt.Sprintf("[** %s **] Tenant **%s**(%d, alias: %s)",
		*planEvent.bizRegion,
		tenantName,
		planEvent.TenantID,
		tenantAlias,
	)
	switch planEvent.EffectivePlan {
	case "poc":
		tenantMsg += " starts the POC."
	case "on_demand":
		tenantMsg += " adds the credit card."
	default:
		tenantMsg += fmt.Sprintf(" changes effective plan to **%s**.",
			planEvent.EffectivePlan,
		)
	}
	return tenantMsg
}

func (planEvent *tenantPlanUBEvent) GetAvailableParams(ctx context.Context) []string {
	return tenantPlanEventParams
}

func (planEvent *tenantPlanUBEvent) GetUBEventType() ubent.UBEventTp {
	return ubent.UBEventTenant
}

func (event *tenantPlanUBEvent) 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.TenantPlanEvent)
	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 newTenantPlanUBEvent(ev *event.TenantPlanEvent) UBEvent {
	ubEvent := tenantPlanUBEvent{
		TenantPlanEvent: *ev,
		tenantAlias:     nil,
		tenantName:      nil,
		bizRegion:       nil,
	}
	return &ubEvent
}

// params

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