package common

import (
	"strconv"

	globalcommonv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/common/v1"
	globalngv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/nextgen/v1"
	openapicommonv1beta1 "github.com/tidbcloud/tidb-management-service/api/spec/tidb_cloud_open_api/common/v1beta1"
	openapingv1beta2 "github.com/tidbcloud/tidb-management-service/api/spec/tidb_cloud_open_api/nextgen/v1beta2"
	commonpkg "github.com/tidbcloud/tidb-management-service/tidb-mgmt-service/pkg/common"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
	"github.com/tidbcloud/tidb-management-service/utilities/region"
)

func ConvertToOpenapiBackups(backups []*globalngv1.Backup) []*openapingv1beta2.Backup {
	result := make([]*openapingv1beta2.Backup, len(backups))
	for i, backup := range backups {
		result[i] = &openapingv1beta2.Backup{
			Id:              backup.Id,
			TidbId:          backup.ClusterId,
			OrganizationId:  backup.OrganizationId,
			ServicePlan:     commonpkg.CvtOpenAPIServicePlan(backup.ServicePlan),
			DisplayName:     backup.DisplayName,
			Description:     backup.Description,
			CreateTime:      backup.CreateTime,
			SizeBytes:       backup.Size,
			State:           openapingv1beta2.Backup_State(backup.State),
			Type:            openapingv1beta2.Backup_Type(backup.Type),
			TriggerType:     openapingv1beta2.Backup_TriggerType(backup.TriggerType),
			ExpirationTime:  backup.ExpirationTime,
			BackupTs:        backup.BackupTs,
			RegionId:        region.ToUserFace(backup.RegionId),
			CustomerManaged: backup.CustomerManaged,
			EncryptionKeyId: strconv.FormatUint(backup.EncryptionKeyId, 10),
		}
	}
	return result
}

func ConvertToNextgenBackupStates(backup_State []openapingv1beta2.Backup_State) []globalngv1.Backup_State {
	if len(backup_State) == 0 {
		return nil
	}
	result := make([]globalngv1.Backup_State, len(backup_State))
	for i, state := range backup_State {
		result[i] = globalngv1.Backup_State(state)
	}
	return result
}

func ConvertToNextgenServicePlans(servicePlan []openapicommonv1beta1.ServicePlan) []globalcommonv1.ServicePlan {
	if len(servicePlan) == 0 {
		return nil
	}
	result := make([]globalcommonv1.ServicePlan, len(servicePlan))
	for i, plan := range servicePlan {
		result[i] = commonpkg.CvtGlobalServicePlan(plan)
	}
	return result
}

func ValidateRegionIds(regionIds []string) bizerr.BizError {
	for _, regionId := range regionIds {
		if err := region.Validate(regionId); err != nil {
			return bizerr.WrapErrorWithCode(err, bizerr.ErrCodeParams, "invalid region id: %s", regionId)
		}
	}
	return nil
}

func ConvertToOpenapiBackupSetting(backupSetting *globalngv1.BackupSetting) *openapingv1beta2.BackupSetting {
	result := &openapingv1beta2.BackupSetting{
		TidbId:             backupSetting.ClusterId,
		PitrStartTime:      backupSetting.PitrStartTime,
		PitrEndTime:        backupSetting.PitrEndTime,
		LastModifyTime:     backupSetting.LastModifyTime,
		BackupPolicy:       openapingv1beta2.BackupSetting_BackupPolicy_Tier(backupSetting.BackupPolicy),
		Mode:               openapingv1beta2.BackupSetting_BackupMode(backupSetting.Mode),
		RetentionDays:      backupSetting.RetentionDays,
		DailyBackupTimeUtc: backupSetting.DailyBackupTimeUtc,
	}
	return result
}

func ConvertToNextgenClusterStates(
	clusterStates []openapingv1beta2.ListBackupsRequest_TidbState,
) []globalngv1.ListBackupsRequest_ClusterState {
	if len(clusterStates) == 0 {
		return nil
	}
	result := make([]globalngv1.ListBackupsRequest_ClusterState, len(clusterStates))
	for i, state := range clusterStates {
		result[i] = globalngv1.ListBackupsRequest_ClusterState(state)
	}
	return result
}

func ConvertToNextgenBackupTriggerTypes(
	triggerTypes []openapingv1beta2.Backup_TriggerType,
) []globalngv1.Backup_TriggerType {
	if len(triggerTypes) == 0 {
		return nil
	}
	result := make([]globalngv1.Backup_TriggerType, len(triggerTypes))
	for i, triggerType := range triggerTypes {
		result[i] = globalngv1.Backup_TriggerType(triggerType)
	}
	return result
}
