package handlers

import (
	"encoding/json"
	"strings"
	"testing"

	"github.com/gin-gonic/gin"
	"wa-assistant/backend/models"
)

func TestAIFormSummarySeparatesQuestionFromFieldName(t *testing.T) {
	form := models.AIForm{Name: "Pembelian", StepsJSON: `[{"key":"field_123","label":"Boleh dibantu nama lengkapnya?","type":"text","required":true}]`}
	steps := parseAIFormSteps(form)
	if steps[0].Label != "Boleh dibantu nama lengkapnya?" {
		t.Fatal("pertanyaan asli berubah")
	}
	if got := aiFormSummary(form, steps, `{"field_123":"edi"}`); got != "*Ringkasan Pembelian*\nNama lengkap: edi" {
		t.Fatalf("ringkasan keliru: %q", got)
	}
	steps[0].SummaryLabel = "Nama penerima"
	if got := aiFormSummary(form, steps, `{"field_123":"edi","_media_field_123":"photo"}`); !strings.Contains(got, "Nama penerima: edi (foto terlampir)") {
		t.Fatalf("nama khusus atau media hilang: %q", got)
	}
}

func TestAIFormLegacyFieldLabels(t *testing.T) {
	tests := []struct{ key, question, want string }{
		{"x", "Boleh dibantu nama lengkapnya?", "Nama lengkap"},
		{"x", "Untuk berapa orang?", "Jumlah peserta"},
		{"x", "Kapan waktu yang diinginkan?", "Jadwal"},
		{"x", "Nomor WhatsApp penerima", "Nomor WhatsApp penerima"},
		{"x", "Apa nama produk yang mau dibeli?", "Produk"},
		{"x", "Ada catatan tambahan? Ketik lewati jika tidak ada.", "Catatan"},
		{"field_1212", "Boleh pilih yang paling cocok?", "Data 1"},
	}
	for _, tt := range tests {
		t.Run(tt.question, func(t *testing.T) {
			if got := aiFormFieldLabel(aiFormStepConfig{Key: tt.key, Label: tt.question}, 0); got != tt.want {
				t.Fatalf("got %q want %q", got, tt.want)
			}
		})
	}
}

func TestAIFormLabelEditorUsesSameLegacySummaryWithoutChangingStoredForm(t *testing.T) {
	db, form, _ := serviceTestDB(t)
	w := workflowRequest(t, ListAIForms, nil, gin.Params{{Key: "id", Value: "1"}})
	if w.Code != 200 {
		t.Fatalf("list: %s", w.Body.String())
	}
	var payload struct {
		Data []models.AIForm `json:"data"`
	}
	if err := json.Unmarshal(w.Body.Bytes(), &payload); err != nil {
		t.Fatal(err)
	}
	var steps []aiFormStepConfig
	if err := json.Unmarshal([]byte(payload.Data[0].StepsJSON), &steps); err != nil {
		t.Fatal(err)
	}
	if steps[0].SummaryLabel != "Nama" {
		t.Fatalf("editor tidak menampilkan nama data: %+v", steps[0])
	}
	var stored models.AIForm
	db.First(&stored, form.ID)
	if stored.StepsJSON != form.StepsJSON {
		t.Fatal("pembacaan editor mengubah data tersimpan")
	}
	steps[0].SummaryLabel = "Nama pemesan"
	raw, _ := json.Marshal(steps)
	if err := validateAIFormConfig(string(raw), "[]"); err != nil {
		t.Fatal(err)
	}
	steps[0].SummaryLabel = "Nama\nbaru"
	raw, _ = json.Marshal(steps)
	if validateAIFormConfig(string(raw), "[]") == nil {
		t.Fatal("nama data multibaris diterima")
	}
}

func TestAIFormConfirmationRemainsExplicitAndConversational(t *testing.T) {
	db, form, session := serviceTestDB(t)
	session.DataJSON = `{"name":"edi","quantity":"2","schedule":"besok"}`
	result := aiFormConfirmation(session, form, parseAIFormSteps(form))
	for _, required := range []string{"Nama: edi", "Sudah benar, kak?", "*konfirmasi*", "*ubah data*", "*batal*", "permintaannya saya catat"} {
		if !strings.Contains(result.reply, required) {
			t.Fatalf("konfirmasi kurang %q: %s", required, result.reply)
		}
	}
	if strings.Contains(result.reply, "berhasil") || strings.Contains(result.reply, "pembayaran selesai") {
		t.Fatal("mengklaim transaksi sebelum konfirmasi")
	}
	var count int64
	db.Model(&models.AIFormSubmission{}).Count(&count)
	if count != 0 {
		t.Fatal("ringkasan mencatat permintaan sebelum konfirmasi")
	}
	if len(result.buttons) != 3 || result.buttons[0].Text != "Data sudah benar" {
		t.Fatal("aksi konfirmasi hilang")
	}
}

func TestAIFormNaturalConfirmationDoesNotAcceptQuestionsOrCorrections(t *testing.T) {
	for _, message := range []string{"konfirmasi", "Data sudah benar", "Iya, sudah benar kak", "sudah sesuai, kak.", "betul", "datanya sudah benar"} {
		if !isAIFormConfirmationMessage(message) {
			t.Fatalf("explicit confirmation rejected: %q", message)
		}
	}
	for _, message := range []string{"oke", "edi", "belum benar", "tidak sesuai", "sudah benar?", "apa maksud konfirmasi", "sudah benar tapi namanya Edi", "konfirmasi nanti", "benar\nubah data"} {
		if isAIFormConfirmationMessage(message) {
			t.Fatalf("ambiguous/correcting message submitted: %q", message)
		}
	}
	db, form, session := serviceTestDB(t)
	session.DataJSON = `{"name":"edi","quantity":"2","schedule":"besok"}`
	session.Status = "confirming"
	db.Model(&session).Updates(map[string]any{"data_json": session.DataJSON, "status": session.Status})
	result := handleAIFormAnswer(session, "iya, sudah benar kak", "")
	if !result.handoff || !strings.Contains(result.reply, "Permintaannya sudah saya catat") {
		t.Fatalf("natural confirmation did not complete: %+v", result)
	}
	var submissions []models.AIFormSubmission
	db.Find(&submissions)
	if len(submissions) != 1 || submissions[0].FormID != form.ID {
		t.Fatal("natural confirmation created incorrect request")
	}
}
