package br

import (
	"context"
	"strconv"

	eventdata "github.com/tidbcloud/eventbus-datastruct/event"

	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/entity"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/service/displayevent"
	"github.com/tidbcloud/tidb-management-service/utilities/clusterevent"
)

func newBackupDisplayEvent(
	ctx context.Context,
	backup *entity.Backup,
	eventType string,
	status eventdata.EventStatus,
	summary string,
) *clusterevent.DisplayEvent {
	return displayevent.New(
		ctx,
		eventType,
		status,
		backup.TenantId,
		backup.ClusterId,
		strconv.FormatUint(backup.ID, 10),
		summary,
		displayevent.BackupDetail{
			BackupID:    strconv.FormatUint(backup.ID, 10),
			DisplayName: backup.DisplayName,
			BackupType:  string(backup.Type),
			TriggerType: string(backup.TriggerType),
			State:       string(backup.State),
		},
	)
}

func newBackupSettingDisplayEvent(
	ctx context.Context,
	clusterID uint64,
	tenantID uint64,
	previous *backupSettingEventState,
	current *backupSettingEventState,
) *clusterevent.DisplayEvent {
	return displayevent.New(
		ctx,
		displayevent.UpdateBackupSetting,
		eventdata.EventStatusSucceeded,
		tenantID,
		clusterID,
		strconv.FormatUint(clusterID, 10),
		"Backup settings updated successfully.",
		displayevent.BackupSettingDetail{
			ClusterID:                  strconv.FormatUint(clusterID, 10),
			PreviousMode:               previous.Mode,
			NewMode:                    current.Mode,
			PreviousRetentionDays:      previous.RetentionDays,
			NewRetentionDays:           current.RetentionDays,
			PreviousDailyBackupTimeUTC: previous.DailyBackupTimeUTC,
			NewDailyBackupTimeUTC:      current.DailyBackupTimeUTC,
			PreviousSchedule:           previous.Schedule,
			NewSchedule:                current.Schedule,
		},
	)
}

type backupSettingEventState struct {
	Mode               string
	RetentionDays      int
	DailyBackupTimeUTC string
	Schedule           displayevent.BackupScheduleDetail
}

func backupSettingEventStateFromEntity(setting *entity.BackupSetting) backupSettingEventState {
	return backupSettingEventState{
		Mode:               string(setting.Mode),
		RetentionDays:      setting.RetentionDays,
		DailyBackupTimeUTC: setting.DailyBackupTimeUTC,
		Schedule: displayevent.BackupScheduleDetail{
			Type:                      setting.Schedule.Type,
			At:                        setting.Schedule.At,
			RetentionDays:             setting.Schedule.RetentionDays,
			NonZeroClockRetentionDays: setting.Schedule.NonZeroClockRetentionDays,
			ZeroClockRetentionDays:    setting.Schedule.ZeroClockRetentionDays,
			DailyBackupMinuteOfDay:    setting.Schedule.DailyBackupMinuteOfDay,
		},
	}
}

func newRestoreDisplayEvent(
	ctx context.Context,
	restore *entity.Restore,
	status eventdata.EventStatus,
	summary string,
) *clusterevent.DisplayEvent {
	return displayevent.New(
		ctx,
		displayevent.RestoreFromBackup,
		status,
		restore.TenantId,
		restore.TargetClusterId,
		strconv.FormatUint(restore.ID, 10),
		summary,
		displayevent.RestoreDetail{
			RestoreID:       strconv.FormatUint(restore.ID, 10),
			RestoreMode:     string(restore.RestoreMode),
			BackupID:        strconv.FormatUint(restore.BackupId, 10),
			SourceClusterID: strconv.FormatUint(restore.SourceClusterId, 10),
			TargetClusterID: strconv.FormatUint(restore.TargetClusterId, 10),
			State:           restore.State,
		},
	)
}
