package common

import (
	"errors"
	"strings"

	globaldedicatedv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/dedicated/v1"
)

type ClusterIdParameter struct {
	ClusterId uint64 `json:"cluster_id"`
}

func GetClusterId(params any) (uint64, error) {
	clusterParam, ok := params.(*ClusterIdParameter)
	if !ok {
		return 0, errors.New("invalid cluster id parameter type")
	}
	clusterId := clusterParam.ClusterId
	if clusterId == 0 {
		return 0, errors.New("cluster id is empty")
	}
	return clusterId, nil
}

type TidbGroupParameter struct {
	ClusterId   uint64 `json:"cluster_id"`
	TidbGroupId uint64 `json:"tidb_group_id"`
}

func GetTidbGroupIdFromTidbGroupParams(params any) (uint64, error) {
	tidbGroupParam, ok := params.(*TidbGroupParameter)
	if !ok {
		return 0, errors.New("invalid tidb group parameter type")
	}
	tidbGroupId := tidbGroupParam.TidbGroupId
	if tidbGroupId == 0 {
		return 0, errors.New("tidb group id is empty")
	}
	return tidbGroupId, nil
}

func GetClusterIdFromTidbGroupParams(params any) (uint64, error) {
	tidbGroupParam, ok := params.(*TidbGroupParameter)
	if !ok {
		return 0, errors.New("invalid tidb group parameter type")
	}
	clusterId := tidbGroupParam.ClusterId
	if clusterId == 0 {
		return 0, errors.New("cluster id is empty")
	}
	return clusterId, nil
}

type PrivateLinkServiceMigrationParameter struct {
	SourceClusterId               uint64 `json:"source_cluster_id"`
	SourceTidbGroupId             uint64 `json:"source_tidb_group_id"`
	TargetClusterId               uint64 `json:"target_cluster_id"`
	TargetTidbGroupId             uint64 `json:"target_tidb_group_id"`
	PrivateLinkServiceMigrationId uint64 `json:"private_link_service_migration_id"`
}

func GetSourceClusterIdFromPrivateLinkServiceMigrationParams(params any) (uint64, error) {
	cutoverPrivateLinkServiceParam, ok := params.(*PrivateLinkServiceMigrationParameter)
	if !ok {
		return 0, errors.New("invalid cutover private link service parameter type")
	}
	return cutoverPrivateLinkServiceParam.SourceClusterId, nil
}

func GetSourceTidbGroupIdFromPrivateLinkServiceMigrationParams(params any) (uint64, error) {
	cutoverPrivateLinkServiceParam, ok := params.(*PrivateLinkServiceMigrationParameter)
	if !ok {
		return 0, errors.New("invalid cutover private link service parameter type")
	}
	return cutoverPrivateLinkServiceParam.SourceTidbGroupId, nil
}

func GetTargetClusterIdFromPrivateLinkServiceMigrationParams(params any) (uint64, error) {
	cutoverPrivateLinkServiceParam, ok := params.(*PrivateLinkServiceMigrationParameter)
	if !ok {
		return 0, errors.New("invalid cutover private link service parameter type")
	}
	return cutoverPrivateLinkServiceParam.TargetClusterId, nil
}

func GetTargetTidbGroupIdFromPrivateLinkServiceMigrationParams(params any) (uint64, error) {
	cutoverPrivateLinkServiceParam, ok := params.(*PrivateLinkServiceMigrationParameter)
	if !ok {
		return 0, errors.New("invalid cutover private link service parameter type")
	}
	return cutoverPrivateLinkServiceParam.TargetTidbGroupId, nil
}

func GetMigrationIdFromPrivateLinkServiceMigrationParams(params any) (uint64, error) {
	cutoverPrivateLinkServiceParam, ok := params.(*PrivateLinkServiceMigrationParameter)
	if !ok {
		return 0, errors.New("invalid cutover private link service parameter type")
	}
	return cutoverPrivateLinkServiceParam.PrivateLinkServiceMigrationId, nil
}

func ScaleComponentTypeFromString(componentType string) globaldedicatedv1.ComponentType {
	return globaldedicatedv1.ComponentType(globaldedicatedv1.ComponentType_value[strings.ToUpper(componentType)])
}

type TidbGroupDNSParameter struct {
	ClusterId   uint64 `json:"cluster_id"`
	TidbGroupId uint64 `json:"tidb_group_id"`
	DNSIdentity string `json:"dns_identity"`
}

func GetClusterIdFromTidbGroupDNSParams(params any) (uint64, error) {
	tidbGroupDNSParam, ok := params.(*TidbGroupDNSParameter)
	if !ok {
		return 0, errors.New("invalid tidb group dns parameter type")
	}
	return tidbGroupDNSParam.ClusterId, nil
}

func GetTidbGroupIdFromTidbGroupDNSParams(params any) (uint64, error) {
	tidbGroupDNSParam, ok := params.(*TidbGroupDNSParameter)
	if !ok {
		return 0, errors.New("invalid tidb group dns parameter type")
	}
	return tidbGroupDNSParam.TidbGroupId, nil
}

func GetDNSIdentityFromTidbGroupDNSParams(params any) (string, error) {
	tidbGroupDNSParam, ok := params.(*TidbGroupDNSParameter)
	if !ok {
		return "", errors.New("invalid tidb group dns parameter type")
	}
	return tidbGroupDNSParam.DNSIdentity, nil
}

type PrivateLinkServiceMigrationStatusParameter struct {
	PrivateLinkServiceMigrationId string `json:"private_link_service_migration_id"`
}

func GetMigrationIdFromPrivateLinkServiceMigrationStatusParams(params any) (string, error) {
	cutoverPrivateLinkServiceParam, ok := params.(*PrivateLinkServiceMigrationStatusParameter)
	if !ok {
		return "", errors.New("invalid private link service migration status parameter type")
	}
	return cutoverPrivateLinkServiceParam.PrivateLinkServiceMigrationId, nil
}
