package claim

import (
	"context"
	"time"
)

// Filter listeleme/sayma/arama süzgecidir. Kullanıcıya göre SÜZMEZ: claim'ler ekip ortaktır.
//
// GÜVENLİK ANLAMI (Faz 8 yetki filtresi buna dayanır): Kinds ve Statuses için
//
//	nil           → süzme yok (hepsi)
//	boş, nil değil → HİÇBİRİ izinli: sonuç her zaman boştur
//
// "Kullanıcı hiçbir türü göremiyor" durumu böylece yanlışlıkla "hepsini göster"e dönüşmez.
// Çağıranlar yetki sonucunu `[]string{}` ile (nil ile DEĞİL) iletmelidir.
type Filter struct {
	Kinds    []string
	Statuses []Status
	Key      string // NormalizeKey çıktısı, birebir eşleşme; boş = süzme yok
	AuthorID string // boş = süzme yok
	Query    string // text içinde düz metin, büyük/küçük harf duyarsız; boş = süzme yok

	// OwnOnly (Faz 8, kişisel veri): bu türlerdeki kayıtlar YALNIZCA SubjectID == ViewerID ise döner;
	// diğer türler etkilenmez. ViewerID boşsa OwnOnly türlerinden HİÇBİR kayıt dönmez (fail-closed).
	// nil/boş OwnOnly = bu kısıt yok (patron). Süzgeç Actor.Scope ile üretilir; elle kurmak yerine onu kullanın.
	OwnOnly  []string
	ViewerID string
}

// Repository claim deposudur. Hem bellek içi hem MongoDB uygular; aynı sözleşmeden geçerler
// (bkz. RepositoryContract). Depo yalnızca saklar: doğrulama (Claim.Validate), embedding,
// çakışma kararı ve yetki Service'tedir.
type Repository interface {
	// Create kaydı ekler. Aynı kimlik varsa ErrDuplicate. (Aynı Key ikinci kez eklenebilir:
	// güncellenmiş/çelişkili kayıtlar aynı anahtarı paylaşır; karar servistedir.)
	Create(ctx context.Context, c *Claim) error
	// Get yoksa ErrNotFound. Embedding DAHİL döner.
	Get(ctx context.Context, id string) (*Claim, error)
	// Update kaydı kimliğe göre TAMAMEN değiştirir (embedding dahil). List sonuçlarında vektör
	// yoktur: List'ten gelen kaydı olduğu gibi Update'e vermek vektörü SİLER; önce Get kullanın.
	// Yoksa ErrNotFound.
	Update(ctx context.Context, c *Claim) error
	// SetStatus yalnızca durumu ve UpdatedAt'i yazar (çelişki/geçersiz işaretleme; diğer alanları ezmez).
	SetStatus(ctx context.Context, id string, status Status, at time.Time) error
	// SetEmbedding yalnızca vektörü yazar (eşzamanlı düzenlemeyi ezmemek için).
	SetEmbedding(ctx context.Context, id string, vec []float32, model string) error
	// Delete yoksa ErrNotFound. Denetim kaydı yazmak Service'in işidir.
	Delete(ctx context.Context, id string) error
	// List kararlı sırayla döner: Key artan, sonra CreatedAt artan, sonra ID. Sayfalama bu sıraya
	// dayanır (liste soruları "hepsini, eksiksiz" ister). limit<=0: hepsi. Asla nil değil. Vektör yok.
	List(ctx context.Context, f Filter, limit, offset int) ([]Claim, error)
	// Count süzgece uyan kayıt sayısıdır ("140 firma").
	Count(ctx context.Context, f Filter) (int, error)
	// ByKey aynı tür ve anahtardaki TÜM durumlardaki kayıtları döner (yeni önce; eşitlikte ID).
	// Birleştirme kararı için. Vektör yok.
	ByKey(ctx context.Context, kind, key string) ([]Claim, error)
	// Searchable süzgece uyan kayıtları EMBEDDING'leriyle döndürür (Go tarafı skorlama için).
	// Yetki süzgeci (Kinds) arama ÖNCESİ burada uygulanır. Sıra List ile aynıdır.
	Searchable(ctx context.Context, f Filter) ([]Claim, error)
}
