package services

import (
	"context"
	"os"
	"strings"
	"testing"
	"time"
	"wa-assistant/backend/models"
)

// Opt-in provider acceptance test. Real installation is read only for the model
// configuration; all knowledge/publication operations use a separate fixture DB.
func TestLiveKnowledgePreparationAndAgenticRetrieval(t *testing.T) {
	if os.Getenv("CHATLOOP_RUN_LIVE_AI") != "1" {
		t.Skip("opt-in OpenRouter acceptance test")
	}
	preset := liveAIPresetForTest(t)
	db := agenticTestDB(t)
	if err := db.AutoMigrate(&models.AppSetting{}, &models.Agent{}, &models.Product{}); err != nil {
		t.Fatal(err)
	}
	agent := models.Agent{ID: 1, TenantID: 1, AgenticEnabled: true, ResponseLength: "short", SystemPrompt: "Asisten Toko Nusa. Jawab faktual dan ramah, gunakan pengetahuan resmi."}
	if err := db.Create(&agent).Error; err != nil {
		t.Fatal(err)
	}
	source := "Kebijakan retur Toko Nusa: pelanggan dapat mengajukan retur maksimal 7 hari setelah barang diterima. Barang harus belum dipakai dan bukti pembelian wajib disertakan."
	t.Logf("Persiapan sumber dan dua turn chatbot via %s; data sintetis, tanpa WhatsApp", preset.Model)
	items, err := GenerateWebFAQ("Kebijakan retur Toko Nusa", source)
	if err != nil || len(items) == 0 {
		t.Fatalf("penyusunan sumber gagal: %v", err)
	}
	for _, item := range items {
		if reason := validateKnowledgeEvidence(source, item); reason != "" {
			t.Fatalf("kutipan gagal: %s", reason)
		}
		row := models.Knowledge{AgentID: 1, Question: item.Question, Answer: item.Answer, Tags: item.Tags, Source: "web", SourceExcerpt: item.Evidence, ReviewStatus: "draft", Scope: "general"}
		if err := db.Create(&row).Error; err != nil {
			t.Fatal(err)
		}
		db.Model(&row).Update("active", false)
	}
	InvalidateKB(1)
	prompt := "Berapa batas waktu pengajuan retur di Toko Nusa? Jika kebijakannya belum tersedia, alihkan ke CS."
	before, err := chatAgentic(agent, agent.SystemPrompt, "ramah", prompt, nil, ChatOptions{Context: context.Background(), DryRun: true})
	if err != nil || !before.Escalate || before.Trace.KnowledgeUsedCount != 0 {
		t.Fatalf("draf bocor ke jawaban: handoff=%t knowledge=%d err=%v", before.Escalate, before.Trace.KnowledgeUsedCount, err)
	}
	t.Logf("Sebelum terbit: tools=%s knowledge=%d handoff=%t", before.Trace.ToolNames, before.Trace.KnowledgeUsedCount, before.Escalate)
	if err := db.Model(&models.Knowledge{}).Where("agent_id = ?", 1).Updates(map[string]any{"review_status": "published", "active": true, "verified_at": time.Now()}).Error; err != nil {
		t.Fatal(err)
	}
	InvalidateKB(1)
	after, err := chatAgentic(agent, agent.SystemPrompt, "ramah", prompt, nil, ChatOptions{Context: context.Background(), DryRun: true})
	if err != nil || after.Escalate || after.Trace.KnowledgeUsedCount == 0 || !strings.Contains(after.Trace.ToolNames, "search_knowledge") {
		t.Fatalf("retrieval terbit gagal: handoff=%t knowledge=%d tools=%s err=%v", after.Escalate, after.Trace.KnowledgeUsedCount, after.Trace.ToolNames, err)
	}
	if !strings.Contains(after.Reply, "7") && !strings.Contains(strings.ToLower(after.Reply), "tujuh") {
		t.Fatal("jawaban tidak mengikuti batas waktu retur pada sumber")
	}
	t.Logf("Sesudah terbit: tools=%s knowledge=%d handoff=%t; jawaban sesuai batas 7 hari", after.Trace.ToolNames, after.Trace.KnowledgeUsedCount, after.Escalate)
}
