package adminalert

import (
	"context"
	"strings"
	"testing"
	"time"

	"scrabble/backend/internal/account"
)

// The fakes ignore the watermark and return a fixed count, which is all the digest logic
// needs.
type fbCounter struct{ n int }

func (f fbCounter) CountSince(context.Context, time.Time) (int, error) { return f.n, nil }

type cpCounter struct{ n int }

func (c cpCounter) CountComplaintsSince(context.Context, time.Time) (int, error) { return c.n, nil }

type recordingMailer struct{ sent []account.Message }

func (m *recordingMailer) Send(_ context.Context, msg account.Message) error {
	m.sent = append(m.sent, msg)
	return nil
}

func TestNotifierSkipsWhenNothingNew(t *testing.T) {
	mailer := &recordingMailer{}
	n := New(mailer, fbCounter{0}, cpCounter{0}, "alerts@erudit-game.ru", "op@x.ru", nil)
	n.tick(context.Background())
	if len(mailer.sent) != 0 {
		t.Fatalf("sent %d emails, want 0 when nothing is new", len(mailer.sent))
	}
}

func TestNotifierDigestsNewItems(t *testing.T) {
	mailer := &recordingMailer{}
	n := New(mailer, fbCounter{2}, cpCounter{1}, "alerts@erudit-game.ru", "op@x.ru, two@x.ru", nil)
	n.tick(context.Background())
	if len(mailer.sent) != 1 {
		t.Fatalf("sent %d emails, want 1 digest", len(mailer.sent))
	}
	msg := mailer.sent[0]
	if msg.From != "alerts@erudit-game.ru" || msg.To != "op@x.ru, two@x.ru" {
		t.Errorf("digest addressing = From %q To %q", msg.From, msg.To)
	}
	if !strings.Contains(msg.Subject, "2 new feedback") || !strings.Contains(msg.Subject, "1 new word complaint") {
		t.Errorf("digest subject = %q, want the feedback + complaint counts", msg.Subject)
	}
	// The digest must never carry an admin-console link — an admin URL in an email is a leak
	// (mail providers cache/index it).
	if strings.Contains(msg.Text, "/_gm") || strings.Contains(strings.ToLower(msg.Text), "admin console") {
		t.Errorf("digest body = %q, must not carry an admin-console link", msg.Text)
	}
}
