package agent

import (
	"context"
	"strings"
	"time"
)

// ClaimReadTimeout bir mesaj için ekip hafızası hazırlığının (sınıflandırma + embedding + arama)
// üst sınırıdır. Aşılırsa tur hafızasız sürer: hafıza bir YAKINLIK katkısıdır, sohbeti engellemez.
const ClaimReadTimeout = 45 * time.Second

// ClaimReadRequest bir kullanıcı mesajı için ekip hafızası okuma isteğidir.
type ClaimReadRequest struct {
	// UserID ağ katmanından gelir; GÜVENİLMEZ: okuyucu bunu hesap dizininde doğrular.
	UserID         string
	ConversationID string
	Text           string
}

// ClaimContext okuma sonucudur. Sıfır değer "eklenecek bir şey yok" demektir.
type ClaimContext struct {
	// Prompt sistem istemine eklenecek ekip hafızası bloğudur (yönerge + kayıtlar).
	Prompt string
	// Append model cevabının ARDINA aynen eklenecek metindir (liste sorusunda sunucu listesi).
	Append string
	// List mesaj bir liste sorusuydu; yeni bilgi içermez, bu yüzden yazma yakalaması atlanır.
	List bool
}

// ClaimReader bir mesaj için ekip ortak hafızasını hazırlar.
//
// Sözleşme: HATA DÖNMEZ ve sohbeti BOZMAZ. Kimlik doğrulanamazsa (üyelik kapalı, hesap yok ya da
// devre dışı), sınıflandırma/embedding başarısız olursa sıfır değer döner. Ajan claim paketini
// bilmez (ClaimWriter ile aynı desen).
type ClaimReader interface {
	Read(ctx context.Context, req ClaimReadRequest) ClaimContext
}

// SetClaimReader ekip hafızası okuyucusunu bağlar; nil ise okuma kapalıdır. Sunucu istek almadan
// önce çağrılmalıdır.
func (a *Agent) SetClaimReader(r ClaimReader) { a.claimRead = r }

// readClaimsAsync ekip hafızasını bellek/bilgi tabanı getirmesiyle PARALEL hazırlar (ses gecikmesi
// toplanmasın). Kanal her koşulda tam bir değer alır.
func (a *Agent) readClaimsAsync(ctx context.Context, in Input, text string) <-chan ClaimContext {
	ch := make(chan ClaimContext, 1)
	if a.claimRead == nil || strings.TrimSpace(text) == "" {
		ch <- ClaimContext{}
		return ch
	}
	req := ClaimReadRequest{UserID: in.UserID, ConversationID: in.ConversationID, Text: text}
	go func() {
		defer func() {
			// Okuma asla turu düşürmemeli.
			if r := recover(); r != nil {
				a.log.Error("ekip hafızası okuması çöktü", "panic", r, "conversation", in.ConversationID)
				ch <- ClaimContext{}
			}
		}()
		rctx, cancel := context.WithTimeout(ctx, ClaimReadTimeout)
		defer cancel()
		ch <- a.claimRead.Read(rctx, req)
	}()
	return ch
}
