package crrf

import (
	"fmt"
	"time"

	"github.com/tidbcloud/dataflow-service-e2e/cases/utils"
	"github.com/tidbcloud/dataflow-service-e2e/internal/tidbcloud/dedicated/consoleapi"
	br_model "github.com/tidbcloud/dataflow-service-e2e/internal/tidbcloud/dedicated/consoleapi/br/model"
	"github.com/tidbcloud/dataflow-service-e2e/internal/tidbcloud/dedicated/consoleapi/cluster_non_gen"
)

// Common CRRF test constants.
const (
	DefaultClusterPassword = "TestPassword123!"
	DefaultClusterPort     = int32(4000)
)

// BuildMinimalClusterComponents returns a minimal component configuration suitable for CRRF restore tests.
func BuildMinimalClusterComponents() []*consoleapi.SimpleClusterComponentRequest {
	return []*consoleapi.SimpleClusterComponentRequest{
		{
			ComponentType:   "COMPONENT_TYPE_TIDB",
			NodeProfileName: "2C8G",
			Replicas:        1,
			StorageSizeGi:   0,
		},
		{
			ComponentType:   "COMPONENT_TYPE_TIKV",
			NodeProfileName: "2C8G",
			Replicas:        3,
			StorageSizeGi:   200,
		},
	}
}

// GenerateClusterName creates a unique cluster name for test purposes.
func GenerateClusterName(prefix string) string {
	return fmt.Sprintf("%s-%d-%s", prefix, time.Now().Unix(), utils.GenerateRandomString(6))
}

func GetSecondaryRegionFromBackupSetting(primary string, regions []*consoleapi.RegionInfoResp) (string, error) {
	for _, region := range regions {
		if region != nil && region.Name != "" && region.Name != primary {
			return region.Name, nil
		}
	}
	return "", fmt.Errorf("secondary region not found (primary=%s)", primary)
}

func BuildCRRFRestoreRequest(clusterName, secondaryRegion string, restoreTs int64) *consoleapi.RestoreBackupRequest {
	return &consoleapi.RestoreBackupRequest{
		ClusterName: clusterName,
		Description: "E2E test CRRF failover restore",
		Password:    DefaultClusterPassword,
		RestoreMode: string(br_model.DataflowRestoreModeRESTOREMODEPITR),
		RestoredTs:  restoreTs,
		Components:  BuildMinimalClusterComponents(),
		Port:        DefaultClusterPort,
		Region:      secondaryRegion,
	}
}

// BuildCRRFRestoreRequestForRegion is a region-aware variant of BuildCRRFRestoreRequest. It
// resolves the smallest available node spec for the target (secondary) region and builds the
// restore components from it, mirroring the cluster-creation fallback in
// internal/case_driver/dependency_tidb_dedicated.go (doCreateCluster). Falls back to the
// default "2C8G" components if the node-spec query fails.
func BuildCRRFRestoreRequestForRegion(
	cli *cluster_non_gen.ClusterClient,
	orgID, projectID, cloudProvider, clusterName, secondaryRegion string,
	restoreTs int64,
) *consoleapi.RestoreBackupRequest {
	components := BuildMinimalClusterComponents()
	regionId := fmt.Sprintf("%s-%s", cloudProvider, secondaryRegion)
	if tidbSpec, err := cli.GetSmallestNodeSpec(orgID, projectID, regionId, "TIDB"); err == nil {
		components[0].NodeProfileName = tidbSpec.NodeSpecKey
	}
	if tikvSpec, err := cli.GetSmallestNodeSpec(orgID, projectID, regionId, "TIKV"); err == nil {
		components[1].NodeProfileName = tikvSpec.NodeSpecKey
		if tikvSpec.MinStorageSizeGi > 0 {
			components[1].StorageSizeGi = int(tikvSpec.MinStorageSizeGi)
		}
	}

	return &consoleapi.RestoreBackupRequest{
		ClusterName: clusterName,
		Description: "E2E test CRRF failover restore",
		Password:    DefaultClusterPassword,
		RestoreMode: string(br_model.DataflowRestoreModeRESTOREMODEPITR),
		RestoredTs:  restoreTs,
		Components:  components,
		Port:        DefaultClusterPort,
		Region:      secondaryRegion,
	}
}
