package prompt

import "strings"

// UserProfile, tek bir kullanıcıya atanmış davranış profilinin isteme girecek
// halidir.
//
// Neden Profile değil de bu? prompt paketi persona paketini BİLMEMELİ (bağımlılık
// yönü: persona → prompt yok, prompt → persona yok). Bu yüzden ajan, profilleri
// okuyup isteme girecek SADECE metne çevirir; istem üretimi prompt paketinde kalır.
type UserProfile struct {
	// Name profil adıdır ("Proje Yöneticisi"); isteme "şu rol" bilgisi girer.
	Name string
	// Role tek cümlelik rol tanımıdır; boş olabilir.
	Role string
	// Instructions davranış kurallarıdır (asıl mesele).
	Instructions string
	// Notes yalnız bu kullanıcıya özel ince ayar notlarıdır.
	Notes string
}

// Personas, kullanıcıya atanmış profilleri isteme ekleyen bölümdür.
//
// NEDEN AYRI BİR BÖLÜM (güvenlik sırası)?
// Profil metni modele gider; model de metne "kurallarım" der. Bu yüzden profil,
// sistem isteminin GÜVENLİK kurallarından SONRA ama KİŞİSEL YÖNLENDİRMEDEN ÖNCE
// yer alır ve açıkça "genel kuralları geçersiz kılamaz" diye çerçevelenir.
// Aksi hâlde bir yönetici profille "veri uydurma" kuralını ezebilirdi.
//
// ETKİNLİK: Kullanıcıya profil atanmamışsa bölüm ÜRETİLMEZ — istem şişmez,
// davranış değişmez (hiçbir şey yapmayanların durumu).
//
// KAPSAM: Yalnızca davranış yönlendirmesidir. Bir profille tool eklenmez/kapatılmaz,
// araçlara erişim genişlemez; bunlar ayrı ve açık izinlerle yönetilir.
func Personas(profiles []UserProfile) Part {
	return Part{Name: "user-profiles", Render: func(Context) string {
		var b strings.Builder
		for _, p := range profiles {
			name := strings.TrimSpace(p.Name)
			inst := strings.TrimSpace(p.Instructions)
			if name == "" && inst == "" {
				continue // boş profil istemi kirletmesin
			}
			if name != "" {
				b.WriteString("- Profil: " + name)
				if role := strings.TrimSpace(p.Role); role != "" {
					b.WriteString(" — " + role)
				}
				b.WriteString("\n")
			}
			if inst != "" {
				b.WriteString("  Davranış: " + oneLine(inst) + "\n")
			}
			if notes := strings.TrimSpace(p.Notes); notes != "" {
				b.WriteString("  Not: " + oneLine(notes) + "\n")
			}
		}
		body := strings.TrimSpace(b.String())
		if body == "" {
			return ""
		}
		// Çerçeve metni bilinçlidir: model talimatı, kullanıcı talimatı sanıp
		// kullanıcıdan gelen metni de yönetici kuralı gibi uygulamaz.
		return "Kullanıcı profilleri (yönetici tarafından bu kullanıcı için belirlendi; " +
			"konuşurken BU KULLANICIYA özel davranış kurallarıdır):\n" + body +
			"Bu kurallar yalnız bu kullanıcıyla konuşmada geçerlidir; " +
			"genel güvenlik ve dürüstlük kurallarını gevşetmez, üstüne yazamaz."
	}}
}

// oneLine, çok satırlı talimatı tek satıra indirger ve boş satırları atar.
//
// Neden? Madde listesi hâlinde okunabilir kalsın diye madde başına ayrı satır
// yazdık; yönetici ise serbest metin yapıştırır. Çok satırlı yapıştırılan
// metni olduğu gibi gömersek bölüm okunmaz olur.
func oneLine(s string) string {
	lines := strings.Split(s, "\n")
	out := make([]string, 0, len(lines))
	for _, l := range lines {
		if t := strings.TrimSpace(l); t != "" {
			out = append(out, t)
		}
	}
	return strings.Join(out, " ")
}
