package store

import (
	"context"
	"encoding/json"
	"path/filepath"
	"testing"
	"time"
)

// Внутренний тест, потому что проверяемое наружу не отдаётся: `updated_at` —
// колонка, а не поле модели. Обещание «метка означает изменение содержимого, а
// не касание строки» держится только этой проверкой, и внешний тест для неё
// потребовал бы публичного метода ради теста.
func TestMergeПовторНеДвигаетМеткуИзменения(t *testing.T) {
	t.Parallel()

	ctx := context.Background()
	st, err := Open(filepath.Join(t.TempDir(), "healthlog.db"))
	if err != nil {
		t.Fatalf("открытие базы: %v", err)
	}
	t.Cleanup(func() { _ = st.Close() })

	raw := json.RawMessage(`{"id":"w1","route":[{"lat":1},{"lat":2}],"totalEnergy":{"qty":20}}`)
	wo := IncomingEntity{
		ID:    "w1",
		Kind:  "workouts",
		Start: time.Date(2025, 6, 5, 7, 0, 0, 0, time.UTC),
		End:   time.Date(2025, 6, 5, 7, 10, 0, 0, time.UTC),
		Raw:   raw,
	}
	merge := func(id string, at time.Time) MergeStats {
		t.Helper()
		s, err := st.Merge(ctx, Incoming{Workouts: []IncomingEntity{wo}},
			DeliveryRef{ID: id, ReceivedAt: at})
		if err != nil {
			t.Fatalf("слияние: %v", err)
		}
		return s
	}
	updatedAt := func() string {
		t.Helper()
		var v string
		if err := st.db.QueryRowContext(ctx,
			`SELECT updated_at FROM workout WHERE id = 'w1'`).Scan(&v); err != nil {
			t.Fatalf("чтение updated_at: %v", err)
		}
		return v
	}

	base := time.Date(2025, 6, 5, 8, 0, 0, 0, time.UTC)
	merge("d1", base)
	before := updatedAt()

	// Тренировка приезжает до 26 раз, пока источник её досчитывает. Провенанс
	// при этом обязан подняться, а метка изменения — нет: иначе она становится
	// меткой касания строки, и запрос «что изменилось с момента X» получает 26
	// ложных изменений, неотличимых от настоящего досчёта.
	merge("d2", base.Add(5*time.Minute))
	if after := updatedAt(); after != before {
		t.Errorf("метка изменения двинулась без изменения содержимого: %s → %s", before, after)
	}

	w, err := st.Workout(ctx, "w1")
	if err != nil {
		t.Fatalf("чтение тренировки: %v", err)
	}
	if w.Delivery != "d2" {
		t.Fatal("провенанс не обновился — тест проверяет не то")
	}
}
