package traceql

import (
	"strings"
	"time"

	"github.com/grafana/grafana-plugin-sdk-go/data"
	"github.com/grafana/tempo/pkg/tempopb"
)

func transformExemplarToFrame(name string, series *tempopb.TimeSeries) *data.Frame {
	exemplars := series.Exemplars

	// Setup fields for basic data
	fields := []*data.Field{
		data.NewField("Time", nil, []time.Time{}),
		data.NewField("Value", nil, []float64{}),
		data.NewField("traceId", nil, []string{}),
	}

	fields[2].Config = &data.FieldConfig{
		DisplayName: "Trace ID",
	}

	// Add fields for each label to be able to link exemplars to the series
	for _, label := range series.Labels {
		fields = append(fields, data.NewField(label.GetKey(), nil, []string{}))
	}

	frame := &data.Frame{
		RefID:  name,
		Name:   "exemplar",
		Fields: fields,
		Meta: &data.FrameMeta{
			DataTopic: data.DataTopicAnnotations,
		},
	}

	for _, exemplar := range exemplars {
		_, labels := transformLabelsAndGetName(exemplar.GetLabels())
		traceId := labels["trace:id"]
		if traceId != "" {
			traceId = strings.ReplaceAll(traceId, "\"", "")
		}

		// Skip exemplars with invalid data
		if exemplar.GetValue() == 0 || exemplar.GetTimestampMs() <= 0 {
			continue
		}

		// Add basic data
		frame.AppendRow(time.UnixMilli(exemplar.GetTimestampMs()), exemplar.GetValue(), traceId)

		// Add labels
		for _, label := range series.Labels {
			field, _ := frame.FieldByName(label.GetKey())
			if field != nil {
				val, _ := metricsValueToString(label.GetValue())
				field.Append(val)
			}
		}
	}
	return frame
}
