package services

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

// TestAgentMessageRawRoundTrip confirma que un campo que el proveedor manda
// y que nuestra struct no conoce (ej. thought_signature de Gemini) sobrevive
// a un ciclo unmarshal->marshal en vez de perderse — es justo lo que hacía
// que Gemini rechazara la segunda ronda de una tool call.
func TestAgentMessageRawRoundTrip(t *testing.T) {
	original := `{"role":"assistant","content":null,"tool_calls":[{"id":"call_1","type":"function","function":{"name":"buscar_conocimiento","arguments":"{}"},"thought_signature":"opaco-123"}]}`

	var msg agentMessage
	if err := json.Unmarshal([]byte(original), &msg); err != nil {
		t.Fatalf("unmarshal: %v", err)
	}
	if len(msg.ToolCalls) != 1 || msg.ToolCalls[0].Function.Name != "buscar_conocimiento" {
		t.Fatalf("no se poblaron los campos tipados normalmente: %+v", msg)
	}

	out, err := json.Marshal(msg)
	if err != nil {
		t.Fatalf("marshal: %v", err)
	}
	if !strings.Contains(string(out), `"thought_signature":"opaco-123"`) {
		t.Errorf("se perdió el campo desconocido al reserializar: %s", out)
	}

	// Un mensaje armado por nosotros (no parseado) no debe llevar Raw ni
	// romperse por eso — tiene que serializar normal.
	propio := agentMessage{Role: "user", Content: "hola"}
	outPropio, err := json.Marshal(propio)
	if err != nil {
		t.Fatalf("marshal de mensaje propio: %v", err)
	}
	if !strings.Contains(string(outPropio), `"role":"user"`) || !strings.Contains(string(outPropio), `"content":"hola"`) {
		t.Errorf("mensaje propio no serializó bien: %s", outPropio)
	}
}
