package services

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

// Pagar jalur sosial: label sosial dari model tidak boleh dipakai membawa klaim
// fakta, tautan, angka, direktif, atau teks panjang.
func TestFactFreeSocialReplyGuardrails(t *testing.T) {
	long := strings.Repeat("a", 241)
	for _, tc := range []struct {
		name, answer string
		want         bool
	}{
		{"sapaan pendek", "Halo, kak. Ada yang bisa saya bantu?", true},
		{"dua kalimat", "Halo Kak. Saya siap membantu.", true},
		{"tiga kalimat", "Halo Kak. Saya siap membantu. Terima kasih.", false},
		{"memuat angka", "Harga mulai 100 ribu ya kak.", false},
		{"angka dalam kata", "Harganya sekitar dua juta ya kak.", false},
		{"mata uang tanpa digit", "Cuma Rp ya kak.", false},
		{"persen", "Diskon 10 persen hari ini.", false},
		{"memuat tautan", "Info lengkap di https://ngertikode.id ya kak.", false},
		{"direktif transaksi", "[[START_FORM:1]]", false},
		{"terlalu panjang", long, false},
	} {
		t.Run(tc.name, func(t *testing.T) {
			if got := isFactFreeSocialReply(tc.answer); got != tc.want {
				t.Fatalf("isFactFreeSocialReply(%q)=%t, ingin %t", tc.answer, got, tc.want)
			}
		})
	}
}

// Pesan yang tidak ada di daftar kata tetap memakai kebijakan faktual. Label sosial
// dari model harus tetap diterima supaya obrolan ringan tidak dieskalasi.
func TestSocialKindAcceptedWithoutWordListPolicy(t *testing.T) {
	state := &agentTurnState{reviewAnswer: approveTestAnswer, userMessage: "lagi apa?", policy: responsePolicyForLength(selectAIResponsePolicy("lagi apa?", "", "", 1), "balanced", "lagi apa?")}
	if state.policy.Name == "social" {
		t.Fatalf("prasyarat uji tidak terpenuhi: kebijakan sudah sosial (%s)", state.policy.Name)
	}
	check := state.checkAnswer(context.Background(), 1, answerCheckInput{Answer: "Halo, saya di sini siap membantu.", Kind: "social"})
	if !check.Approved || state.socialDraft == "" || state.socialDraftKind != "social" {
		t.Fatalf("balasan sosial ditolak: %+v (draf=%q)", check, state.socialDraft)
	}
}

// Label sosial tidak boleh menjadi jalan pintas untuk klaim fakta tanpa bukti.
func TestSocialKindCannotCarryBusinessFacts(t *testing.T) {
	state := &agentTurnState{reviewAnswer: approveTestAnswer, userMessage: "harganya berapa?", policy: responsePolicyForLength(selectAIResponsePolicy("harganya berapa?", "", "", 1), "balanced", "harganya berapa?")}
	check := state.checkAnswer(context.Background(), 1, answerCheckInput{Answer: "Harga Masterclass Laravel 12 Rp179.000 ya kak.", Kind: "social"})
	if check.Approved {
		t.Fatal("label sosial dipakai untuk membawa klaim fakta tanpa bukti")
	}
	if state.socialDraft != "" {
		t.Fatalf("draf berisi fakta ikut disimpan untuk fallback: %q", state.socialDraft)
	}
}

// Draf sosial yang ditolak karena gaya tetap disimpan, supaya giliran yang gagal
// mendapat jawaban resmi tidak berakhir sebagai eskalasi ke CS.
func TestSocialDraftKeptWhenStyleRejected(t *testing.T) {
	state := &agentTurnState{reviewAnswer: approveTestAnswer, userMessage: "lagi apa?", policy: responsePolicyForLength(selectAIResponsePolicy("lagi apa?", "", "", 1), "balanced", "lagi apa?")}
	state.policy.Conversation = &conversationStyle{NoEmoji: true, NoExclamation: true}
	check := state.checkAnswer(context.Background(), 1, answerCheckInput{Answer: "Halo kak 😊", Kind: "social"})
	if check.Approved || check.Issue != "emoji_context" {
		t.Fatalf("prasyarat uji tidak terpenuhi: %+v", check)
	}
	if state.socialDraft != "Halo kak 😊" || state.socialDraftKind != "social" {
		t.Fatalf("draf sosial tidak disimpan untuk fallback: %q", state.socialDraft)
	}
}

// Kalau upaya terbaru bukan balasan sosial, draf lama dibuang supaya pertanyaan
// faktual yang gagal tetap dieskalasi dan pelanggan tidak diberi basa-basi.
func TestSocialDraftClearedAfterFactualAttempt(t *testing.T) {
	state := &agentTurnState{reviewAnswer: approveTestAnswer, userMessage: "berapa harganya?", policy: responsePolicyForLength(selectAIResponsePolicy("berapa harganya?", "", "", 1), "balanced", "berapa harganya?")}
	state.policy.Conversation = &conversationStyle{NoEmoji: true, NoExclamation: true}
	if check := state.checkAnswer(context.Background(), 1, answerCheckInput{Answer: "Halo kak 😊", Kind: "social"}); check.Issue != "emoji_context" {
		t.Fatalf("prasyarat draf sosial tidak terpenuhi: %+v", check)
	}
	if state.socialDraft == "" {
		t.Fatal("prasyarat uji tidak terpenuhi: draf sosial tidak tersimpan")
	}
	state.checkAnswer(context.Background(), 1, answerCheckInput{Answer: "Harga Masterclass Laravel 12 Rp179.000.", Kind: "answer"})
	if state.socialDraft != "" || state.socialDraftKind != "" {
		t.Fatalf("draf sosial lama masih tersimpan setelah upaya faktual: %q", state.socialDraft)
	}
}
