package telemetry

import (
	"context"
	"fmt"
	"testing"
	"time"

	"github.com/alicebob/miniredis/v2"
	"github.com/glebarez/sqlite"
	"github.com/redis/go-redis/v9"
	"gorm.io/datatypes"
	"gorm.io/gorm"

	"dudu/server/internal/store"
)

func TestAggregateDay(t *testing.T) {
	mr := miniredis.RunT(t)
	rdb := redis.NewClient(&redis.Options{Addr: mr.Addr()})
	db, _ := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
	_ = db.AutoMigrate(store.AllModels()...)
	h := New(db, rdb)

	cst := time.FixedZone("CST", 8*3600)
	day := time.Now().In(cst).Format("2006-01-02")
	noon, _ := time.ParseInLocation("2006-01-02 15", day+" 12", cst)
	// 100 条延迟事件：ms = 1..100 → P50≈50, P95≈95
	for i := 1; i <= 100; i++ {
		db.Create(&store.MetricEvent{
			DeviceID: "d1", Platform: "mac", Event: "asr.first_partial_ms",
			Props: datatypes.JSON(fmt.Sprintf(`{"ms":%d}`, i)), ReceivedAt: noon,
		})
	}
	// 计数型事件不参与分位
	db.Create(&store.MetricEvent{
		DeviceID: "d1", Platform: "mac", Event: "login.success",
		Props: datatypes.JSON(`{}`), ReceivedAt: noon,
	})

	if err := h.AggregateDay(context.Background(), day); err != nil {
		t.Fatal(err)
	}
	var md store.MetricDaily
	if err := db.First(&md, "date = ? AND event = ? AND platform = ?", day, "asr.first_partial_ms", "mac").Error; err != nil {
		t.Fatal(err)
	}
	if md.Count != 100 || md.P50Ms < 45 || md.P50Ms > 55 || md.P95Ms < 90 || md.P95Ms > 100 {
		t.Fatalf("bad aggregate: %+v", md)
	}
	var login store.MetricDaily
	if err := db.First(&login, "date = ? AND event = ?", day, "login.success").Error; err != nil || login.Count != 1 {
		t.Fatalf("login aggregate missing: %+v err=%v", login, err)
	}
}
