package playevents

import (
	"context"
	"encoding/json"
	"io"
	"log/slog"
	"testing"
	"time"

	"github.com/jackc/pgx/v5/pgtype"

	"git.fabledsword.com/bvandeusen/minstrel/internal/db/dbq"
)

func TestCaptureContextualLikeIfPlaying_NoOpenEvent_NoOp(t *testing.T) {
	f := newFixture(t, 200_000)
	logger := slog.New(slog.NewTextHandler(io.Discard, nil))
	q := dbq.New(f.pool)
	if err := CaptureContextualLikeIfPlaying(context.Background(), q, f.user, f.track, logger); err != nil {
		t.Fatalf("err: %v", err)
	}
	var count int
	_ = f.pool.QueryRow(context.Background(), "SELECT count(*) FROM contextual_likes WHERE user_id=$1", f.user).Scan(&count)
	if count != 0 {
		t.Errorf("count = %d, want 0 (no open play_event)", count)
	}
}

func TestCaptureContextualLikeIfPlaying_OpenEventWithVector_Inserts(t *testing.T) {
	f := newFixture(t, 200_000)
	logger := slog.New(slog.NewTextHandler(io.Discard, nil))
	// Start a play (creates an open play_event with a populated vector).
	at := time.Now().UTC()
	_, err := f.w.RecordPlayStarted(context.Background(), f.user, f.track, "c", at)
	if err != nil {
		t.Fatalf("RecordPlayStarted: %v", err)
	}
	// Like the same track — captures contextual signal.
	q := dbq.New(f.pool)
	if err := CaptureContextualLikeIfPlaying(context.Background(), q, f.user, f.track, logger); err != nil {
		t.Fatalf("Capture: %v", err)
	}
	var rawVec []byte
	if err := f.pool.QueryRow(context.Background(),
		"SELECT session_vector FROM contextual_likes WHERE user_id=$1 AND track_id=$2",
		f.user, f.track).Scan(&rawVec); err != nil {
		t.Fatalf("query: %v", err)
	}
	var vec map[string]any
	_ = json.Unmarshal(rawVec, &vec)
	if vec == nil {
		t.Errorf("vector empty: %s", rawVec)
	}
}

func TestSoftDeleteContextualLikes_MarksActiveRowsDeleted(t *testing.T) {
	f := newFixture(t, 200_000)
	logger := slog.New(slog.NewTextHandler(io.Discard, nil))
	at := time.Now().UTC()
	_, _ = f.w.RecordPlayStarted(context.Background(), f.user, f.track, "c", at)
	q := dbq.New(f.pool)
	_ = CaptureContextualLikeIfPlaying(context.Background(), q, f.user, f.track, logger)
	// Now soft-delete.
	if err := SoftDeleteContextualLikes(context.Background(), q, f.user, f.track); err != nil {
		t.Fatalf("SoftDelete: %v", err)
	}
	var deletedAt pgtype.Timestamptz
	if err := f.pool.QueryRow(context.Background(),
		"SELECT deleted_at FROM contextual_likes WHERE user_id=$1 AND track_id=$2",
		f.user, f.track).Scan(&deletedAt); err != nil {
		t.Fatalf("query: %v", err)
	}
	if !deletedAt.Valid {
		t.Errorf("deleted_at not set after SoftDelete")
	}
}
