package hook

import (
	"context"
	"fmt"
	"time"

	"github.com/tidbcloud/pov-service/internal/client/email"
	"github.com/tidbcloud/pov-service/internal/common/constant"
	"github.com/tidbcloud/pov-service/internal/model"
	"github.com/tidbcloud/pov-service/internal/pkg/log"
	"github.com/tidbcloud/pov-service/internal/service/workload/task"
)

type SendEmailAtComplete struct {
	emailCli   email.Client
	templateID string
	from       string
}

func NewSendEmailAtComplete(
	emailCli email.Client,
	templateID string,
	from string,
) SendEmailAtComplete {
	return SendEmailAtComplete{
		emailCli:   emailCli,
		templateID: templateID,
		from:       from,
	}
}

func (r SendEmailAtComplete) Match(
	processor task.TaskProcessor,
	test model.WorkloadTest) bool {
	if processor.GetName() != task.PhaseTransitionProcessorName {
		return false
	}
	return test.Phase == model.WorkloadTestPhaseFinished
}

func (r SendEmailAtComplete) Do(
	ctx context.Context, test model.WorkloadTest) error {
	log.Log.Infof("Sending email for test %s finishing workload.", test.ID)

	var (
		durationStr    string
		dataSizeStr    string
		maxConnections string
	)
	if dur, ok := test.GetDurationMinConf(); ok {
		durationStr = fmt.Sprintf("%d min", dur)
	}

	if dataSize, ok := test.GetParam(string(constant.DataSource)); ok {
		dataSizeStr = dataSize.(string)
	}

	if maxConn, ok := test.GetParam(string(constant.MaxConnectionNumber)); ok {
		maxConnections = maxConn.(string)
	}
	finishAt := time.Now().UTC()
	if test.FinishedAt != nil {
		finishAt = *test.FinishedAt
	}
	startedAt := test.CreatedAt.UTC()
	if test.StartedAt != nil {
		startedAt = *test.StartedAt
	}

	emailVars := r.getEmailVars(
		test.WorkloadName,
		test.StartedByPrefix(),
		test.Status,
		durationStr,
		maxConnections,
		fmt.Sprintf("%d - %d", test.Cluster.MinRU, test.Cluster.MaxRU),
		dataSizeStr,
		"AWS",
		test.StartedBy,
		startedAt,
		finishAt,
	)

	return r.emailCli.SendEmailWithTemplate(
		ctx,
		email.SendWithTemplateRequest{
			From:         r.from,
			To:           []string{test.StartedBy},
			TemplateID:   r.templateID,
			TemplateVars: emailVars,
		},
	)
}

func (r SendEmailAtComplete) GetName() string {
	return "send_email_at_complete_hook"
}

func (r SendEmailAtComplete) getEmailVars(
	wlName string,
	userName string,
	status model.ExecStatus,
	duration string,
	maxConnections string,
	ruCapacity string,
	dataSize string,
	cloudProvider string,
	userEmail string,
	startAt time.Time,
	completeAt time.Time,
) map[string]string {
	startStr := startAt.UTC().Format("2006-01-02 15:04:05 MST")
	completeStr := completeAt.UTC().Format("2006-01-02 15:04:05 MST")
	return map[string]string{
		"workload_name":   wlName,
		"user_name":       userName,
		"status":          string(status),
		"duration":        duration,
		"max_connections": maxConnections,
		"RU_capacity":     ruCapacity,
		"data_size":       dataSize,
		"cloud_provider":  cloudProvider,
		"user_email":      userEmail,
		"start_at":        startStr,
		"complete_at":     completeStr,
	}
}
