package services

import (
	"context"
	"os"
	"strings"
	"testing"
	"time"

	"wa-assistant/backend/models"
)

// Opt-in acceptance uses the configured provider with isolated synthetic facts.
// It does not publish knowledge, create an order or send a WhatsApp message.
func TestLiveDeepSeekPurchaseLinks(t *testing.T) {
	if os.Getenv("CHATLOOP_RUN_LIVE_DEEPSEEK") != "1" {
		t.Skip("opt-in paid DeepSeek purchase-link acceptance")
	}
	p, _, _, _ := liveDeepSeekAssistantSnapshot(t)
	db := agenticTestDB(t)
	if err := db.AutoMigrate(&models.AppSetting{}, &models.Agent{}, &models.Product{}); err != nil {
		t.Fatal(err)
	}
	agent := models.Agent{Name: "CS Toko Uji", AgenticEnabled: true, SystemPrompt: "Anda asisten virtual Toko Uji. Bantu pertanyaan pelanggan berdasarkan sumber resmi yang diterbitkan.", Tone: "friendly"}
	if err := db.Create(&agent).Error; err != nil {
		t.Fatal(err)
	}
	const productURL = "https://store.example/p/source-code-toko-uji"
	source := models.Knowledge{AgentID: agent.ID, Active: true, ReviewStatus: "published", Scope: "general", SourceURL: productURL,
		Question: "Di mana membeli dan bagaimana cara checkout Source Code Toko Uji?",
		Answer:   "Pembelian Source Code Toko Uji dilakukan melalui halaman produk di website resmi Toko Uji. Buka halaman produk, tekan tombol Beli, pilih metode pembayaran yang tersedia, lalu selesaikan pembayaran mengikuti petunjuk pada halaman checkout.",
	}
	if err := db.Create(&source).Error; err != nil {
		t.Fatal(err)
	}
	if err := db.Create(&models.AppSetting{Key: "ai_provider", Value: "deepseek"}).Error; err != nil {
		t.Fatal(err)
	}
	InvalidateKB(agent.ID)
	defer InvalidateKB(agent.ID)
	dir := os.Getenv("CHATLOOP_AI_TEST_LOG_DIR")
	if dir == "" {
		dir = t.TempDir()
	}
	store := NewSimulationLogStore(dir)
	for _, tc := range []struct{ name, mode, question string }{
		{"short", "short", "belinya dimana"},
		{"balanced", "balanced", "Gimana cara checkout Source Code Toko Uji?"},
		{"detailed", "detailed", "Bagaimana cara checkout Source Code Toko Uji?"},
		{"source_url_only", "short", "belinya dimana"},
	} {
		t.Run(tc.name, func(t *testing.T) {
			if tc.name == "source_url_only" {
				// The observed regression used a pricing FAQ: its URL was only in
				// metadata, with no checkout steps in the source answer.
				if err := db.Model(&source).Updates(map[string]any{"question": "Berapa harga Source Code Toko Uji?", "answer": "Harga Source Code Toko Uji adalah Rp190.000."}).Error; err != nil {
					t.Fatal(err)
				}
				InvalidateKB(agent.ID)
			}
			agent.ResponseLength = tc.mode
			id := NewSimulationID()
			recorder, err := store.Start(agent.ID, id, NewSimulationID(), map[string]any{"question": tc.question, "response_mode": tc.mode, "fixture": "purchase_links"})
			if err != nil {
				t.Fatal(err)
			}
			started := time.Now()
			result, callErr := chatAgentic(agent, agent.SystemPrompt, agent.Tone, tc.question, []models.ChatHistory{{Message: "Saya tertarik Source Code Toko Uji", Reply: "Silakan, ada yang ingin ditanyakan tentang Source Code Toko Uji?"}}, ChatOptions{Context: recorder.Context(context.Background()), DryRun: true})
			status := "completed"
			if result.Escalate {
				status = "handoff"
			}
			if callErr != nil {
				status = "error"
			}
			recorder.Finish(status, map[string]any{"reply": result.Reply, "provider": result.Trace.Provider, "model": result.Model, "handoff_reason": result.HandoffReason, "answer_check_issue": result.Trace.AnswerCheckIssue, "answer_sources": result.Trace.AnswerSources, "tool_names": result.Trace.ToolNames, "response_validated": result.Trace.ResponseValidated})
			t.Logf("turn=%s model=%s elapsed=%s mode=%s chars=%d/%d status=%s tools=%s reply=%s", id, p.Model, time.Since(started).Round(time.Millisecond), tc.mode, len([]rune(result.Reply)), result.Trace.ResponseMaxChars, status, result.Trace.ToolNames, result.Reply)
			if callErr != nil || result.Escalate || !result.Trace.ResponseValidated {
				t.Fatalf("purchase answer was not approved: error=%v handoff=%s issue=%s", callErr, result.HandoffReason, result.Trace.AnswerCheckIssue)
			}
			if result.Trace.ResponseMode != tc.mode || len([]rune(result.Reply)) > result.Trace.ResponseMaxChars || len(result.Trace.AnswerSources) != 1 {
				t.Fatal("saved response style or selected evidence was not respected")
			}
			links := referenceAnswerLinks(result.Reply)
			if len(links) != 1 || links[0] != productURL {
				t.Fatalf("answer omitted the direct product page or invented another destination: %v", links)
			}
			if strings.Contains(result.Reply, "/checkout") || strings.ContainsAny(result.Reply, "\u2014\u2013") {
				t.Fatal("invented checkout path or long dash in customer reply")
			}
			if tc.name == "source_url_only" && strings.Contains(strings.ToLower(result.Reply), "tombol beli") {
				t.Fatal("a source URL alone cannot prove how the checkout controls work")
			}
		})
	}
}
