package tiworkload

import (
	"encoding/json"
	"fmt"
	"strings"
)

type api string

const (
	version = "/api/v1/"

	getWorkloads api = "service/workloads/infos"
	getWorkload  api = "service/workloads/info/%s"

	// Get workload form by workload name
	getWorkloadForm api = "service/workload/%s/config/form"
	postWorkload    api = "service/workload"
	getWorkloadExec api = "service/workload/exec/%s"

	deleteWorkloadExec api = "service/workload/exec/%s"

	// A temporary api to recreate workload execution
	postWorkloadRecreate api = "service/workload/recreate"

	postSampleDBs  api = "service/clusters/sample/dbs"
	postSampleData api = "service/clusters/sample/tables"

	postCluster      api = "service/clusters"
	getCluster       api = "service/clusters"
	getClusterDetail api = "service/clusters/%s"

	postOverprovision   api = "service/clusters/%s/workers/overprovision"
	deleteOverprovision api = "service/clusters/%s/workers/overprovision/%s"

	postExecuteSql api = "service/clusters/sql/execute"
)

func getPath(api api, pathVer ...any) string {
	return fmt.Sprintf(fmt.Sprintf("%s%s", version, api), pathVer...)
}

func getUrl(path string, params any) string {
	// Convert params to map
	paramMap := make(map[string]any)

	// Handle different types of params
	switch v := params.(type) {
	case map[string]any:
		paramMap = v
	case map[string]string:
		for k, val := range v {
			paramMap[k] = val
		}
	case nil:
		// No parameters, just return the path
		return string(path)
	default:
		// For struct types, use JSON marshaling to convert to map
		if data, err := json.Marshal(params); err == nil {
			_ = json.Unmarshal(data, &paramMap)
		}
	}

	// If no parameters, return just the path
	if len(paramMap) == 0 {
		return string(path)
	}

	// Build query string
	queryParts := make([]string, 0, len(paramMap))
	for key, value := range paramMap {
		if value != nil {
			queryParts = append(queryParts, fmt.Sprintf("%s=%v", key, value))
		}
	}

	// Return complete URL with query parameters
	return fmt.Sprintf("%s?%s", string(path), strings.Join(queryParts, "&"))
}
