package cvt

import (
	"google.golang.org/protobuf/proto"
	"gorm.io/gorm"

	globalcommonv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/common/v1"
	globalserverlessv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/serverless/v1"
	"github.com/tidbcloud/tidb-management-service/serverless-global-service/domain/entity"
	"github.com/tidbcloud/tidb-management-service/serverless-global-service/infra/persistence/model"
)

const defaultEngineType = "MYSQL_COMPATIBLE"

func UserClusterStatusToModel(status globalserverlessv1.UserClusterStatus) string {
	switch status {
	case globalserverlessv1.UserClusterStatus_USER_CLUSTER_STATUS_CREATING:
		return model.ClusterStatusCreating
	case globalserverlessv1.UserClusterStatus_USER_CLUSTER_STATUS_NORMAL:
		return model.ClusterStatusNormal
	}
	return ""
}

func Model2UserStatus(status string) globalserverlessv1.UserClusterStatus {
	switch status {
	case model.ClusterStatusCreating:
		return globalserverlessv1.UserClusterStatus_USER_CLUSTER_STATUS_CREATING
	case model.ClusterStatusNormal:
		return globalserverlessv1.UserClusterStatus_USER_CLUSTER_STATUS_NORMAL
	case model.ClusterStatusDeleted:
		return globalserverlessv1.UserClusterStatus_USER_CLUSTER_STATUS_DELETED
	}
	return globalserverlessv1.UserClusterStatus_USER_CLUSTER_STATUS_UNSPECIFIED
}

func ClusterEnToModel(en *entity.Cluster) *model.Cluster {
	engineType := en.EngineType
	if engineType == "" {
		engineType = defaultEngineType
	}

	return &model.Cluster{
		Model: model.Model{
			ID: en.ClusterId,
			Model: gorm.Model{
				CreatedAt: en.CreatedAt,
				DeletedAt: gorm.DeletedAt{
					Time: en.DeletedAt,
				},
			},
		},

		Versioned: model.Versioned{
			Versioning: en.Versioning,
		},
		Version:                     en.Version,
		CreationFinishedAt:          en.CreationFinishedAt,
		TenantId:                    en.TenantId,
		ProjectID:                   en.ProjectId,
		UserStatus:                  UserClusterStatusToModel(en.UserStatus),
		EncryptedCloudAdminPassword: en.EncryptedCloudAdminPassword,
		EncryptedRootPassword:       en.EncryptedRootPassword,
		// ProviderId:                  en.CloudProvider.Id,
		// RegionId:  en.Region.Id,
		Provider:  nil,
		Region:    nil,
		HasSetPwd: en.HasSetPwd,
		Attributes: model.ClusterAttributes{
			TokenBasedAuthEnabled:   en.Attributes.TokenBasedAuthEnabled,
			WithBuiltinCDCAdminRole: en.Attributes.WithBuiltinCDCAdminRole,
		},
		RuVersion:          en.RuVersion,
		EngineType:         engineType,
		ExternalInstanceID: en.ExternalInstanceID,
	}
}

func Model2En(cm *model.Cluster) (*entity.Cluster, error) {
	attributes := entity.ClusterAttributes{
		TokenBasedAuthEnabled:   cm.Attributes.TokenBasedAuthEnabled,
		WithBuiltinCDCAdminRole: cm.Attributes.WithBuiltinCDCAdminRole,
	}

	var creationFinishedAt *int64
	if cm.CreationFinishedAt != nil {
		creationFinishedAt = proto.Int64(cm.CreationFinishedAt.Unix())
	}

	if cm.EngineType == "" {
		cm.EngineType = defaultEngineType
	}

	region, err := RegionModel2Entity(cm.Region, cm.Provider)
	if err != nil {
		return nil, err
	}
	servicePlan := globalcommonv1.ServicePlan_SERVICE_PLAN_UNSPECIFIED
	if region != nil {
		servicePlan = region.GetServicePlan()
	}

	provider, err := CloudProvider2En(cm.Provider)
	if err != nil {
		return nil, err
	}

	return &entity.Cluster{
		ServerlessServiceCluster: globalserverlessv1.ServerlessServiceCluster{
			ClusterId:          cm.GetId(),
			TenantId:           cm.TenantId,
			ProjectId:          cm.ProjectID,
			UserStatus:         Model2UserStatus(cm.UserStatus),
			HasSetPwd:          cm.HasSetPwd,
			CreationFinishedAt: creationFinishedAt,
			RuVersion:          cm.RuVersion,
			EngineType:         cm.EngineType,
		},
		CreationFinishedAt:          cm.CreationFinishedAt,
		Version:                     cm.Version,
		Region:                      region,
		CloudProvider:               provider,
		Attributes:                  attributes,
		ServicePlan:                 servicePlan,
		EncryptedCloudAdminPassword: cm.EncryptedCloudAdminPassword,
		EncryptedRootPassword:       cm.EncryptedRootPassword,
		EngineType:                  cm.EngineType,
		ExternalInstanceID:          cm.ExternalInstanceID,
		DeletedAt:                   cm.DeletedAt.Time,
		CreatedAt:                   cm.CreatedAt,
		UpdatedAt:                   cm.UpdatedAt,
		Versioning:                  cm.Versioning,
	}, nil
}
