package storage

import "testing"

// insertClassified is a tiny helper to seed a visible story and return its id.
func insertClassified(t *testing.T, guid, headline, content string) int64 {
	t.Helper()
	s := &Story{
		GUID:       guid,
		Headline:   headline,
		Content:    content,
		ArticleURL: "https://example.com/" + guid,
		Source:     "Example Wire",
		Channel:    "tech",
		Classified: true,
		SeenAt:     nowUnix(),
	}
	if err := InsertStory(s); err != nil {
		t.Fatalf("insert %s: %v", guid, err)
	}
	var id int64
	if err := Get().QueryRow(`SELECT id FROM stories WHERE guid = ?`, guid).Scan(&id); err != nil {
		t.Fatalf("lookup %s: %v", guid, err)
	}
	return id
}

func TestStoryViews_TotalsAndTrending(t *testing.T) {
	setupTestDB(t)

	a := insertClassified(t, "s-a", "Story A", "some body text here")
	b := insertClassified(t, "s-b", "Story B", "")
	c := insertClassified(t, "s-c", "Story C", "another body")

	// A read three times, C twice, B never.
	RecordStoryView(a)
	RecordStoryView(a)
	RecordStoryView(a)
	RecordStoryView(c)
	RecordStoryView(c)

	totals := StoryViewTotals([]int64{a, b, c})
	if totals[a] != 3 {
		t.Errorf("totals[a] = %d, want 3", totals[a])
	}
	if _, ok := totals[b]; ok {
		t.Errorf("totals[b] present = %v, want absent (zero views)", totals[b])
	}
	if totals[c] != 2 {
		t.Errorf("totals[c] = %d, want 2", totals[c])
	}

	// Trending over the last week: A (3) before C (2); B is absent (no views).
	trend, err := TrendingStories(10, unixDay()-6)
	if err != nil {
		t.Fatalf("trending: %v", err)
	}
	if len(trend) != 2 {
		t.Fatalf("trending len = %d, want 2 (B has no views)", len(trend))
	}
	if trend[0].ID != a || trend[1].ID != c {
		t.Errorf("trending order = [%d, %d], want [%d, %d]", trend[0].ID, trend[1].ID, a, c)
	}

	// A window that starts after today excludes everything.
	future, err := TrendingStories(10, unixDay()+1)
	if err != nil {
		t.Fatalf("trending future: %v", err)
	}
	if len(future) != 0 {
		t.Errorf("trending (future window) len = %d, want 0", len(future))
	}
}

func TestStoryContentLengths(t *testing.T) {
	setupTestDB(t)

	a := insertClassified(t, "c-a", "Has body", "hello world body")
	b := insertClassified(t, "c-b", "No body", "")

	lengths := StoryContentLengths([]int64{a, b})
	if lengths[a] != len("hello world body") {
		t.Errorf("lengths[a] = %d, want %d", lengths[a], len("hello world body"))
	}
	if _, ok := lengths[b]; ok {
		t.Errorf("lengths[b] present, want absent (empty content)")
	}
	if got := StoryContentLengths(nil); len(got) != 0 {
		t.Errorf("StoryContentLengths(nil) = %v, want empty", got)
	}
}
