package services

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

	sqlmysql "github.com/go-sql-driver/mysql"
	"github.com/joho/godotenv"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"wa-assistant/backend/database"
	"wa-assistant/backend/models"
)

// Opt-in smoke test: reads only AI configuration from the existing database,
// then replaces the database with an isolated in-memory fixture. No WA session,
// customer history, migrations, or outbound messages touch the real installation.
func TestLiveAgenticSmoke(t *testing.T) {
	if os.Getenv("CHATLOOP_RUN_LIVE_AI") != "1" {
		t.Skip("opt-in OpenRouter test")
	}
	p := 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 pakaian. Layani dengan ramah dan jujur."}
	db.Create(&agent)
	kb := models.Knowledge{AgentID: 1, Question: "Berapa harga Kaos Premium?", Answer: "Harga Kaos Premium Rp75.000 per buah.", Tags: "harga,kaos,premium", Active: true, ReviewStatus: "published", Scope: "general"}
	db.Create(&kb)
	InvalidateKB(1)
	t.Logf("Uji fixture melalui model %s; maksimal 3 skenario, tanpa WhatsApp", p.Model)
	tests := []struct {
		name, prompt string
		handoff      bool
	}{
		{"approved_fact", "Berapa harga Kaos Premium? Jawab singkat.", false},
		{"missing_fact", "Apakah Kaos Premium memiliki garansi 10 tahun? Jika tidak ada kepastian kebijakannya, tolong alihkan ke CS.", true},
		{"human_request", "Saya ingin bicara langsung dengan CS manusia.", true},
	}
	for _, tc := range tests {
		result, err := chatAgentic(agent, agent.SystemPrompt, "ramah", tc.prompt, nil, ChatOptions{Context: context.Background(), DryRun: true})
		if err != nil {
			t.Fatalf("%s: %v", tc.name, err)
		}
		t.Logf("%s: tools=%d handoff=%t reason=%s chars=%d", tc.name, result.Trace.ToolCalls, result.Escalate, result.HandoffReason, len([]rune(result.Reply)))
		if result.Escalate != tc.handoff {
			t.Errorf("%s: handoff=%t, expected=%t", tc.name, result.Escalate, tc.handoff)
		}
		if !tc.handoff && !strings.Contains(strings.NewReplacer(".", "", ",", "").Replace(result.Reply), "75000") {
			t.Errorf("%s: harga tidak sesuai fixture", tc.name)
		}
	}
}

func liveAIPresetForTest(t *testing.T) aiPreset {
	t.Helper()
	_ = godotenv.Load("../../.env")
	env := func(key, fallback string) string {
		if v := os.Getenv(key); v != "" {
			return v
		}
		return fallback
	}
	cfg := sqlmysql.NewConfig()
	cfg.User = env("DB_USER", "root")
	cfg.Passwd = os.Getenv("DB_PASS")
	cfg.Net = "tcp"
	cfg.Addr = env("DB_HOST", "localhost") + ":" + env("DB_PORT", "3306")
	cfg.DBName = env("DB_NAME", "wa_assistant")
	cfg.ParseTime = true
	original := database.DB
	source, err := gorm.Open(mysql.Open(cfg.FormatDSN()), &gorm.Config{Logger: logger.Default.LogMode(logger.Silent)})
	if err != nil {
		t.Fatal("Konfigurasi AI di database lokal belum bisa dibaca")
	}
	database.DB = source
	p := openRouterPreset() // These opt-in tests explicitly exercise OpenRouter.
	database.DB = original
	sqlDB, _ := source.DB()
	sqlDB.Close()
	if p.APIKey == "" {
		t.Fatal("API key OpenRouter belum dikonfigurasi")
	}
	t.Setenv("OPENROUTER_API_KEY", p.APIKey)
	t.Setenv("OPENROUTER_MODEL", p.Model)
	return p
}
