package main

import (
	"context"
	"testing"

	"golang.org/x/crypto/bcrypt"

	"fiko-ai/internal/user"
)

// newNotifyRecipients, arama zincirini gerçek kodla kurar (user.Service → notifyRecipients).
func newNotifyRecipients(t *testing.T, users ...user.User) notifyRecipients {
	t.Helper()
	store := user.NewMemoryStore()
	ctx := context.Background()
	for i := range users {
		u := users[i]
		if err := store.Create(ctx, &u); err != nil {
			t.Fatalf("kullanıcı eklenemedi %q: %v", u.Username, err)
		}
	}
	svc, err := user.NewService(store, user.ServiceOptions{BcryptCost: bcrypt.MinCost})
	if err != nil {
		t.Fatalf("NewService: %v", err)
	}
	return notifyRecipients{svc: svc}
}

// CANLI HATA (05.10.2026): notify.users "admin" aramasında count:0 döndü → model
// kullanıcı adını UYDURDU ("adminbinbe") ve notify.send uydurma kimlikle hata
// verdi. Sebep: Search yalnız DisplayName ve ID alanlarında arıyordu; görünen adı
// boş olan kullanıcıda Username eşleşmesi hiç denenmiyordu.
//
// Kullanıcının bildiği metin kullanıcı adıdır (giriş onunla yapılır), görünen ad
// ise opsiyoneldir. Üçü de aranmalıdır.
func TestNotifyRecipients_SearchFindsByUsername(t *testing.T) {
	ctx := context.Background()
	r := newNotifyRecipients(t,
		// Görünen adı YOK — canlıdaki durum buydu.
		user.User{ID: "usr_1", Username: "admin", Role: user.RoleAdmin},
		user.User{ID: "usr_2", Username: "ahmet", DisplayName: "Ahmet Yılmaz"},
	)

	cases := []struct {
		query string
		want  []string
	}{
		{"admin", []string{"usr_1"}},   // kullanıcı adıyla
		{"ahmet", []string{"usr_2"}},   // kullanıcı adıyla
		{"yilmaz", []string{"usr_2"}},  // görünen adla (Türkçe normalize: "yılmaz")
		{"Ahmet Y", []string{"usr_2"}}, // büyük/küçük harf duyarsız
		{"usr_1", []string{"usr_1"}},   // kimlikle
	}
	for _, tc := range cases {
		got, err := r.Search(ctx, tc.query, 5)
		if err != nil {
			t.Fatalf("%q: Search: %v", tc.query, err)
		}
		if len(got) != len(tc.want) {
			t.Errorf("%q: %d sonuç, beklenen %d (%v)", tc.query, len(got), len(tc.want), tc.want)
			continue
		}
		for i, id := range tc.want {
			if got[i].ID != id {
				t.Errorf("%q: sonuç[%d] = %q, beklenen %q", tc.query, i, got[i].ID, id)
			}
		}
	}
}

// Devre dışı kullanıcı bildirim ALAMAZ: aramada görünmemeli.
func TestNotifyRecipients_SearchSkipsDisabled(t *testing.T) {
	ctx := context.Background()
	r := newNotifyRecipients(t,
		user.User{ID: "usr_1", Username: "admin", DisplayName: "Yönetici"},
		user.User{ID: "usr_2", Username: "mehmet", DisplayName: "Mehmet", Disabled: true},
	)
	got, err := r.Search(ctx, "mehmet", 5)
	if err != nil {
		t.Fatalf("Search: %v", err)
	}
	if len(got) != 0 {
		t.Errorf("devre dışı kullanıcı aramada çıkmamalı: %v", got)
	}
}

// Tek harf araması modele kullanılamaz listeyi döndürür; boş kalmalı.
func TestNotifyRecipients_SearchRejectsSingleChar(t *testing.T) {
	ctx := context.Background()
	r := newNotifyRecipients(t, user.User{ID: "usr_1", Username: "admin"})
	got, err := r.Search(ctx, "a", 5)
	if err != nil {
		t.Fatalf("Search: %v", err)
	}
	if len(got) != 0 {
		t.Errorf("tek harf araması boş dönmeli: %v", got)
	}
}
