package prompt

import (
	"strings"
	"testing"
	"time"
	_ "time/tzdata" // Windows'ta IANA saat dilimi veritabanı yoktur; testler buna bağımlı olmasın.
)

// NoFabrication kuralları tool çıktısındaki SOMUT işaretlere bağlanmalı. Bağlanmazsa
// kural "dürüst ol" seviyesinde kalır ve model uydurmayı sürdürür (canlı hata).
func TestNoFabrication_AnchoredToToolSignals(t *testing.T) {
	got := NoFabrication().Render(Context{})
	for _, want := range []string{
		"Veri doğruluğu:",
		"empty: true",         // biz.find boş sonuç işareti
		"count: 0",            // kayıt sayısı
		"collectionTotal: 0",  // koleksiyonun tamamı boş
		"nonEmptyCollections", // summary'nin dolu koleksiyon listesi
		"biz.add",             // yeni bilgi önce KAYDEDİLİR
		"uydurma",             // açık yasak
	} {
		if !strings.Contains(got, want) {
			t.Errorf("NoFabrication çıktısında %q yok:\n%s", want, got)
		}
	}
}

// Araç kullanımı bölümü bozulmamalı; sadece yeni bölüm eklendi.
func TestToolUsageUnchanged(t *testing.T) {
	got := ToolUsage().Render(Context{})
	for _, want := range []string{"Yalnızca sana sunulan araçları çağır", "Aynı aracı aynı girdiyle tekrar çağırma"} {
		if !strings.Contains(got, want) {
			t.Errorf("ToolUsage içeriği bozulmuş: %q yok:\n%s", want, got)
		}
	}
}

// Varsayılan istem bu bölümü İÇERMEZ: tool'suz oturumda gereksiz şişer.
func TestDefault_DoesNotIncludeNoFabrication(t *testing.T) {
	for _, n := range Default().Names() {
		if n == "no-fabrication" {
			t.Fatal("varsayılan istemde no-fabrication olmamalı (yalnızca tool açıkken eklenir)")
		}
	}
}

func TestDefault_PartOrderAndContent(t *testing.T) {
	b := Default()
	want := []string{"identity", "personality", "rules", "datetime"}
	got := b.Names()
	if len(got) != len(want) {
		t.Fatalf("parçalar %v, beklenen %v", got, want)
	}
	for i := range want {
		if got[i] != want[i] {
			t.Fatalf("parçalar %v, beklenen %v", got, want)
		}
	}
	out := b.Build(Context{Now: time.Date(2026, 10, 2, 9, 30, 0, 0, time.UTC), Timezone: "Europe/Istanbul"})
	for _, s := range []string{"Fiko", "Kurallar:", "2 Ekim 2026 Cuma, 12:30 (Europe/Istanbul)"} {
		if !strings.Contains(out, s) {
			t.Errorf("çıktıda %q yok:\n%s", s, out)
		}
	}
	if strings.Contains(out, "\n\n\n") {
		t.Errorf("fazladan boş satır var:\n%q", out)
	}
}

func TestDateTime_SkippedWhenZeroAndFallsBackToUTC(t *testing.T) {
	if got := DateTime().Render(Context{}); got != "" {
		t.Fatalf("Now sıfırken boş bekleniyordu: %q", got)
	}
	got := DateTime().Render(Context{Now: time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC), Timezone: "Yok/Boyle"})
	if !strings.Contains(got, "(UTC)") || !strings.Contains(got, "1 Ocak 2026 Perşembe, 00:00") {
		t.Fatalf("UTC'ye düşmesi bekleniyordu: %q", got)
	}
}

func TestPersonality_UserName(t *testing.T) {
	if strings.Contains(Personality().Render(Context{}), "adı") {
		t.Error("kullanıcı adı yokken ad cümlesi olmamalı")
	}
	if !strings.Contains(Personality().Render(Context{UserName: "Ali"}), "Ali") {
		t.Error("kullanıcı adı eklenmeli")
	}
}

func TestBuilder_WithDoesNotMutateAndSkipsEmpty(t *testing.T) {
	base := New(Part{Name: "a", Render: func(Context) string { return "A" }})
	ext := base.With(Part{Name: "empty", Render: func(Context) string { return "  " }}).
		With(Part{Name: "b", Render: func(Context) string { return "B" }})
	if len(base.Names()) != 1 {
		t.Fatal("orijinal Builder değişmemeli")
	}
	if got := ext.Build(Context{}); got != "A\n\nB" {
		t.Fatalf("beklenen %q, gelen %q", "A\n\nB", got)
	}
}
