package claim

// Tür bazlı görünürlük (Faz 8). Kural şemada (internal/claim/kinds) tanımlıdır: Team türleri ekipteki
// herkes görür; Private türleri (personel, pdks) yalnızca PATRON ve kaydın İLGİLİ KİŞİSİ (subjectId) görür.
//
// YETKİ FİLTRESİ ARAMADAN ÖNCE UYGULANIR: cevap yalnızca prompt'taki bilgiye göre üretildiği için
// görme yetkisi olmayan kayıt prompt'a hiç girmemelidir. Bu yüzden süzgeç depoya iletilir (Filter.OwnOnly
// / ViewerID); sonuçlar sonradan ayıklanmaz. Hem bellek içi hem Mongo deposu aynı kuralı uygular
// (sözleşme testi denetler).
//
// FAIL-CLOSED: Actor'ın sıfır değeri (ID boş, rol boş) hiçbir özel kaydı göremez. Kimliği doğrulanmamış
// bir çağrı, unutulmuş bir alan yüzünden "hepsini göster"e dönüşmez.

import (
	"context"
	"strings"
	"time"

	"fiko-ai/internal/claim/kinds"
)

// isPatron aktör gerçek bir patron mu? (Kimliksiz "patron" rolü geçersizdir.)
func (a Actor) isPatron() bool {
	return a.Role == RolePatron && strings.TrimSpace(a.ID) != ""
}

// Scope süzgece aktörün görme sınırını ekler. Patron için süzgeç değişmez; diğerleri için özel türler
// yalnızca kendi kayıtlarıyla (SubjectID == aktör) sınırlanır.
func (a Actor) Scope(f Filter) Filter {
	if a.isPatron() {
		return f
	}
	f.OwnOnly = kinds.Default().PrivateKinds()
	f.ViewerID = strings.TrimSpace(a.ID)
	return f
}

// CanSee aktör bu kaydı görebilir mi? Depo süzgeciyle AYNI kural.
func (a Actor) CanSee(c *Claim) bool {
	if c == nil {
		return false
	}
	if a.isPatron() || !kinds.Default().IsPrivate(c.Kind) {
		return true
	}
	id := strings.TrimSpace(a.ID)
	return id != "" && c.SubjectID == id
}

// IsPrivateKind tür kişisel veri görünürlüğünde mi?
func IsPrivateKind(kind string) bool { return kinds.Default().IsPrivate(kind) }

// logViews özel türlerdeki kayıtlara ERİŞİMİ denetime yazar (KVKK: kim, ne zaman, hangi kayda baktı).
// Yalnızca özel tür kayıtları yazılır; ekip verisi okumaları denetlenmez. Denetim yazılamazsa hata
// DÖNER: erişim kaydı bırakılamıyorsa kişisel veri verilmez (çağıran sonucu iletmemelidir).
func logViews(ctx context.Context, audit AuditRepository, newID func(string) string, at time.Time,
	actor Actor, claims []Claim) error {
	if audit == nil {
		return nil
	}
	for _, c := range claims {
		if !kinds.Default().IsPrivate(c.Kind) {
			continue
		}
		e := AuditEntry{ID: newID("aud"), ClaimID: c.ID, Action: ActionView, By: actor.ID, ByName: actor.Name, At: at}
		if err := audit.Append(ctx, &e); err != nil {
			return err
		}
	}
	return nil
}
