package dispatcher

import (
	"testing"

	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/AgentTeam/desktop/internal/agent/drivercontract"
	"github.com/tidbcloud/AgentTeam/desktop/internal/agent/runtimeevents"
	"github.com/tidbcloud/AgentTeam/desktop/internal/consts"
	"github.com/tidbcloud/AgentTeam/desktop/internal/types"
	"github.com/tidbcloud/AgentTeam/desktop/internal/wire/manager"
)

func TestBuildEventCallbackPublishesNormalizedEventToBus(t *testing.T) {
	d := mustNewDispatcher("")
	t.Cleanup(d.Close)
	mgr := manager.New(d, nil)
	ch := &reportingStubChannel{id: "agentteam"}
	mgr.Register(ch)
	d.serverConnections = mgr

	callback := d.buildEventCallback("agentteam", "agent-a", "agent-a", "")
	callback(drivercontract.ParsedEvent{
		Kind:      consts.ParsedEventKindThinking,
		SessionID: "sess-1",
		Text:      "hello",
	})

	recent := d.runtimeEventBus.Recent(runtimeevents.FilterKind(runtimeevents.KindTurnThinking), 10)
	require.Len(t, recent, 1)
	require.Equal(t, "agentteam", recent[0].Context.ServerID)
	require.Equal(t, "agent-a", recent[0].Context.ServerAgentID)
	require.Equal(t, "sess-1", recent[0].Context.SessionID)
	require.Equal(t, "hello", payloadString(recent[0], "text"))
}

func TestEmitRuntimeEventMainPathPreservesLegacyEventClass(t *testing.T) {
	d := mustNewDispatcher("")
	t.Cleanup(d.Close)
	mgr := manager.New(d, nil)
	ch := &reportingStubChannel{id: "agentteam"}
	mgr.Register(ch)
	d.serverConnections = mgr

	d.emitRuntimeEvent("agentteam", "server-agent", types.RuntimeEvent{
		MessageID:  "msg-1",
		EventClass: consts.RuntimeEventClassWakeFailed,
		Target:     "#agentteam",
		Detail:     "delivery failed",
	})

	require.Len(t, ch.events, 1)
	runtimeEvent, ok := ch.events[0].(types.RuntimeEvent)
	require.True(t, ok)
	require.Equal(t, "server-agent", runtimeEvent.AgentID)
	require.Equal(t, consts.RuntimeEventClassWakeFailed, runtimeEvent.EventClass)
	require.Equal(t, "delivery failed", runtimeEvent.Detail)

	recent := d.runtimeEventBus.Recent(runtimeevents.FilterKind(runtimeevents.KindWakeFailed), 10)
	require.Len(t, recent, 1)
	require.Equal(t, consts.RuntimeEventClassWakeFailed, payloadString(recent[0], "event_class"))
}
