package conversation

import (
	"context"
	"errors"
	"strings"
	"testing"
)

func TestMemoryRepo_Contract(t *testing.T) {
	RepositoryContract(t, func() Repository { return NewMemoryRepo() })
}

func TestService_AutoTitleOnlyOnFirstMessage(t *testing.T) {
	ctx := context.Background()
	s := NewService(NewMemoryRepo())
	c, err := s.Create(ctx, "u")
	if err != nil || c.Title != DefaultTitle {
		t.Fatalf("c=%+v err=%v", c, err)
	}
	_, title, err := s.AddUserMessage(ctx, "u", c.ID, "  Merhaba dünya\nikinci satır ")
	if err != nil || title != "Merhaba dünya" {
		t.Fatalf("başlık %q err=%v", title, err)
	}
	_, title, _ = s.AddUserMessage(ctx, "u", c.ID, "başka bir şey")
	if title != "" {
		t.Fatalf("başlık ikinci mesajda değişmemeli: %q", title)
	}
	got, _ := s.Get(ctx, "u", c.ID)
	if got.Title != "Merhaba dünya" {
		t.Fatalf("kalıcı başlık: %q", got.Title)
	}
}

func TestService_OwnershipAndValidation(t *testing.T) {
	ctx := context.Background()
	s := NewService(NewMemoryRepo())
	c, _ := s.Create(ctx, "alice")

	if _, err := s.Get(ctx, "mallory", c.ID); !errors.Is(err, ErrNotFound) {
		t.Fatalf("başkasının konuşması ErrNotFound olmalı: %v", err)
	}
	if err := s.Delete(ctx, "mallory", c.ID); !errors.Is(err, ErrNotFound) {
		t.Fatalf("başkası silememeli: %v", err)
	}
	if _, _, err := s.AddUserMessage(ctx, "alice", c.ID, " \n\t "); !errors.Is(err, ErrEmptyContent) {
		t.Fatalf("ErrEmptyContent bekleniyordu: %v", err)
	}
	if _, _, err := s.AddUserMessage(ctx, "mallory", c.ID, "selam"); !errors.Is(err, ErrNotFound) {
		t.Fatalf("başkası mesaj ekleyememeli: %v", err)
	}
}

func TestService_AssistantMessageDefaults(t *testing.T) {
	ctx := context.Background()
	s := NewService(NewMemoryRepo())
	c, _ := s.Create(ctx, "u")
	m, err := s.AddAssistantMessage(ctx, c.ID, AssistantMessage{ID: "msg_fixed", Content: "yarım", Status: StatusInterrupted})
	if err != nil || m.ID != "msg_fixed" || m.Status != StatusInterrupted || m.Role != RoleAssistant {
		t.Fatalf("m=%+v err=%v", m, err)
	}
	m2, _ := s.AddAssistantMessage(ctx, c.ID, AssistantMessage{Content: "tam"})
	if m2.ID == "" || m2.Status != StatusComplete {
		t.Fatalf("varsayılanlar: %+v", m2)
	}
	hist, _ := s.Messages(ctx, "u", c.ID, 10)
	if len(hist) != 2 {
		t.Fatalf("geçmiş: %+v", hist)
	}
}

func TestTitleFrom(t *testing.T) {
	long := strings.Repeat("ş", 60)
	got := TitleFrom(long)
	if r := []rune(got); len(r) != 49 || r[48] != '…' {
		t.Fatalf("48 karaktere + … kesilmeli, gelen %d rune: %q", len(r), got)
	}
	if TitleFrom("\n \n") != "" {
		t.Fatal("boş metin boş başlık vermeli")
	}
	if TitleFrom("a   b\tc") != "a b c" {
		t.Fatal("boşluklar sadeleşmeli")
	}
}
