package central_thanos

import (
	"context"
	"strconv"
	"time"

	"github.com/juju/errors"
	"github.com/prometheus/common/model"
	"github.com/tidbcloud/metrics-integration/pipeline/central/config"
	"github.com/tidbcloud/metrics-integration/pipeline/central/metrics/prom"
	"github.com/tidbcloud/metrics-integration/pipeline/internal/datasource"
)

// clusterLabels returns the standard cluster-dimension labels for a TargetCluster.
// For Premium plans, asPremiumElement() will rename cluster_id→instance_id and cluster_name→instance_name.
// For Starter/Essential plans, asStarterEssentialElement() keeps all labels intact.
func clusterLabels(cluster *config.TargetCluster) []prom.MetricLabel {
	return []prom.MetricLabel{
		{Name: datasource.LabelClusterID, Value: strconv.FormatUint(cluster.Id, 10)},
		{Name: datasource.LabelCluster, Value: cluster.Name},
		{Name: datasource.LabelProjectID, Value: strconv.FormatUint(cluster.ProjectId, 10)},
	}
}

// BuildDBRowStorageUsedBytesQuerier builds the row-based (TiKV) storage usage metric for TiDB X clusters.
// This metric is only applicable to NextGen plans (Premium/Essential/Starter).
func BuildDBRowStorageUsedBytesQuerier(cluster *config.TargetCluster) datasource.MetricQuerierFunc {
	return func(ctx context.Context) (prom.Metric, error) {
		vec := prom.VecMetric{
			Name:        "tidbcloud_db_row_storage_used_bytes",
			Help:        "The row-based (TiKV) storage size of TiDB X cluster in bytes.",
			Type:        "gauge",
			Metrics:     []*prom.VecMetricElement{},
			ServicePlan: cluster.ServicePlan,
		}
		currTime := time.Now()
		vec.Timestamp = currTime.Unix()

		resp, err := QueryDBRowStorageUsedBytes(ctx, cluster.Id, vec.Name, currTime, currTime)
		if err != nil || resp.Status != "success" {
			return &vec, errors.Errorf("failed to query db row storage used bytes, err: %v, result: %+v", err, resp)
		}

		for _, result := range resp.Data.Result {
			value, err := datasource.GetFloatValue(result.Value)
			if err != nil {
				return &vec, err
			}

			vec.Metrics = append(vec.Metrics, &prom.VecMetricElement{
				Labels: clusterLabels(cluster),
				Value:  model.SampleValue(value),
			})
		}

		return &vec, nil
	}
}

// BuildDBColumnarStorageUsedBytesQuerier builds the columnar (TiFlash) storage usage metric for TiDB X clusters.
// Returns 0 when TiFlash is not enabled. Only applicable to NextGen plans.
func BuildDBColumnarStorageUsedBytesQuerier(cluster *config.TargetCluster) datasource.MetricQuerierFunc {
	return func(ctx context.Context) (prom.Metric, error) {
		vec := prom.VecMetric{
			Name:        "tidbcloud_db_columnar_storage_used_bytes",
			Help:        "The columnar (TiFlash) storage size of TiDB X cluster in bytes. Returns 0 when TiFlash is not enabled.",
			Type:        "gauge",
			Metrics:     []*prom.VecMetricElement{},
			ServicePlan: cluster.ServicePlan,
		}
		currTime := time.Now()
		vec.Timestamp = currTime.Unix()

		resp, err := QueryDBColumnarStorageUsedBytes(ctx, cluster.Id, vec.Name, currTime, currTime)
		if err != nil || resp.Status != "success" {
			return &vec, errors.Errorf("failed to query db columnar storage used bytes, err: %v, result: %+v", err, resp)
		}

		for _, result := range resp.Data.Result {
			value, err := datasource.GetFloatValue(result.Value)
			if err != nil {
				return &vec, err
			}

			vec.Metrics = append(vec.Metrics, &prom.VecMetricElement{
				Labels: clusterLabels(cluster),
				Value:  model.SampleValue(value),
			})
		}

		return &vec, nil
	}
}
