//go:build integration

package inttest

import (
	"context"
	"testing"

	"github.com/google/uuid"

	"scrabble/backend/internal/account"
)

// TestUserListFilter checks the admin user-list filter: the people/robots split (by a
// robot identity) and the case-insensitive glob masks on display name and external id.
func TestUserListFilter(t *testing.T) {
	ctx := context.Background()
	st := account.NewStore(testDB)
	uniq := uuid.NewString()

	human, _, err := st.ProvisionTelegram(ctx, "tg-"+uniq, "en", "", "Zzqxhuman", "")
	if err != nil {
		t.Fatalf("provision human: %v", err)
	}
	robot, err := st.ProvisionRobot(ctx, "robot-uxz-"+uniq, "Zzqxbot")
	if err != nil {
		t.Fatalf("provision robot: %v", err)
	}
	guest, err := st.ProvisionGuest(ctx, "", "")
	if err != nil {
		t.Fatalf("provision guest: %v", err)
	}

	collect := func(f account.UserFilter) map[uuid.UUID]account.UserListItem {
		items, err := st.ListUsers(ctx, f, 5000, 0)
		if err != nil {
			t.Fatalf("list users %+v: %v", f, err)
		}
		m := make(map[uuid.UUID]account.UserListItem, len(items))
		for _, it := range items {
			m[it.ID] = it
		}
		return m
	}

	people := collect(account.UserFilter{})
	if _, ok := people[human.ID]; !ok {
		t.Error("human missing from people")
	}
	if _, ok := people[guest.ID]; !ok {
		t.Error("guest missing from people")
	}
	if _, ok := people[robot.ID]; ok {
		t.Error("robot must not appear in people")
	}
	if it := people[human.ID]; it.IsRobot || it.IsGuest {
		t.Errorf("human flags wrong: robot=%v guest=%v (want both false)", it.IsRobot, it.IsGuest)
	}

	robots := collect(account.UserFilter{Robots: true})
	if it, ok := robots[robot.ID]; !ok || !it.IsRobot {
		t.Errorf("robot missing from robots or IsRobot=false (ok=%v)", ok)
	}
	if _, ok := robots[human.ID]; ok {
		t.Error("human must not appear in robots")
	}

	// Name mask (people).
	if _, ok := collect(account.UserFilter{NameMask: "Zzqx*"})[human.ID]; !ok {
		t.Error("name mask Zzqx* should match the human")
	}
	if _, ok := collect(account.UserFilter{NameMask: "nomatch*"})[human.ID]; ok {
		t.Error("name mask nomatch* should not match the human")
	}
	// External-id mask (robots).
	if _, ok := collect(account.UserFilter{Robots: true, ExternalIDMask: "robot-uxz-*"})[robot.ID]; !ok {
		t.Error("external-id mask robot-uxz-* should match the robot")
	}
	if _, ok := collect(account.UserFilter{Robots: true, ExternalIDMask: "robot-zzz-*"})[robot.ID]; ok {
		t.Error("external-id mask robot-zzz-* should not match the robot")
	}
	// CountUsers agrees that robots exist.
	if n, err := st.CountUsers(ctx, account.UserFilter{Robots: true, ExternalIDMask: "robot-uxz-*"}); err != nil || n != 1 {
		t.Errorf("count robots robot-uxz-* = (%d, %v), want 1", n, err)
	}
}
