package store_test

import (
	"context"
	"testing"
	"time"

	"github.com/stretchr/testify/require"

	"gitea.d-ma.be/mathias/tapir/internal/domain"
)

func ytVideo(userID, provVideoID, title string) domain.Video {
	return domain.Video{
		UserID:          userID,
		Provider:        domain.ProviderYouTube,
		ProviderVideoID: provVideoID,
		Title:           title,
		URL:             "https://www.youtube.com/watch?v=" + provVideoID,
		PublishedAt:     time.Date(2026, 6, 1, 12, 0, 0, 0, time.UTC),
		// SubscriptionID is a provider resource id, not a UUID — must not be
		// written to the UUID column. Set it to prove UpsertVideo ignores it.
		SubscriptionID: "yt-subscription-resource-id",
	}
}

func TestUpsertVideo_ReturnsStableID(t *testing.T) {
	ctx := context.Background()
	s := newStore(t)
	resetDB(t, rawPool(t))

	id1, err := s.UpsertVideo(ctx, ytVideo(userA, "dQw4w9WgXcQ", "first title"))
	require.NoError(t, err)
	require.NotEmpty(t, id1)

	// Same (user, provider, provider_video_id) -> same row, same id, updated meta.
	id2, err := s.UpsertVideo(ctx, ytVideo(userA, "dQw4w9WgXcQ", "updated title"))
	require.NoError(t, err)
	require.Equal(t, id1, id2, "idempotent upsert must return the same durable id")

	p := rawPool(t)
	var (
		title string
		count int
	)
	require.NoError(t, p.QueryRow(ctx,
		`SELECT title FROM videos WHERE id = $1`, id1).Scan(&title))
	require.Equal(t, "updated title", title, "second upsert must update metadata in place")

	require.NoError(t, p.QueryRow(ctx,
		`SELECT count(*) FROM videos WHERE user_id = $1`, userA).Scan(&count))
	require.Equal(t, 1, count, "must not duplicate the row")
}

func TestUpsertVideo_IDMatchesSummaryDedup(t *testing.T) {
	ctx := context.Background()
	s := newStore(t)
	resetDB(t, rawPool(t))

	// Upsert assigns the durable video id; a summary delivered under that id
	// must then show up in SeenVideoIDs — this is the cross-restart dedup chain.
	id, err := s.UpsertVideo(ctx, ytVideo(userA, "abc123", "t"))
	require.NoError(t, err)

	require.NoError(t, s.Deliver(ctx, summary(userA, id, "the summary")))

	seen, err := s.SeenVideoIDs(ctx, userA)
	require.NoError(t, err)
	require.True(t, seen[id], "the upserted video id must match the summary dedup key")
}

func TestUpsertVideo_PerUserIsolation(t *testing.T) {
	ctx := context.Background()
	s := newStore(t)
	resetDB(t, rawPool(t))

	idA, err := s.UpsertVideo(ctx, ytVideo(userA, "same-provider-id", "a"))
	require.NoError(t, err)
	idB, err := s.UpsertVideo(ctx, ytVideo(userB, "same-provider-id", "b"))
	require.NoError(t, err)

	require.NotEqual(t, idA, idB, "same provider video for two users must be two distinct rows")
}
