package dashboard

import (
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"testing"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/AgentTeam/desktop/internal/agent"
	"github.com/tidbcloud/AgentTeam/desktop/internal/agentview"
	"github.com/tidbcloud/AgentTeam/desktop/internal/profile"
	"github.com/tidbcloud/AgentTeam/desktop/internal/types"
)

func TestBuildAgentResponsePreservesAgentTeamSourceContract(t *testing.T) {
	setupDashboardTestProfile(t)
	mgr := profile.Default()

	require.NoError(t, mgr.Servers().Add(&profile.AgentTeamServer{
		ID:   "agentteam-channel-1",
		Name: "Primary AgentTeam Server",
	}))

	resp := BuildAgentResponse(agent.Config{
		ID:      "synced-agent",
		Name:    "Synced Agent",
		Runtime: "codex",
		Source:  agent.NewAgentTeamSource("agentteam-channel-1"),
	})

	require.Equal(t, "agentteam:agentteam-channel-1", resp.Source)
	require.Equal(t, "agentteam", resp.SourceType)
	require.Equal(t, "Primary AgentTeam Server", resp.SourceName)

	missingChannelResp := BuildAgentResponse(agent.Config{
		ID:      "orphaned-agent",
		Runtime: "codex",
		Source:  agent.NewAgentTeamSource("agentteam-channel-missing"),
	})

	require.Equal(t, "agentteam:agentteam-channel-missing", missingChannelResp.Source)
	require.Equal(t, "agentteam", missingChannelResp.SourceType)
	require.Empty(t, missingChannelResp.SourceName)
}

func TestBuildAgentResponseMarksAgentTeamSyncedAgentsRegistered(t *testing.T) {
	setupDashboardTestProfile(t)

	resp := BuildAgentResponse(agent.Config{ID: "server-agent", Runtime: "codex", Source: agent.NewAgentTeamSource("agentteam-channel")})

	if !resp.BackendRegistered {
		t.Fatal("BackendRegistered = false, want true for agentteam-synced agent")
	}
	if resp.Status != "registered" {
		t.Fatalf("Status = %q, want registered", resp.Status)
	}
}

func TestListAgentsHandlerOverlaysActiveSessionStatus(t *testing.T) {
	setupDashboardTestProfile(t)
	mgr := profile.Default()
	if err := mgr.Servers().Add(&profile.AgentTeamServer{ID: "agentteam-channel", Name: "AgentTeam"}); err != nil {
		t.Fatalf("Add channel: %v", err)
	}
	if err := mgr.Agents().Add(agent.Config{ID: "server-agent", Runtime: "codex", Source: agent.NewAgentTeamSource("agentteam-channel")}); err != nil {
		t.Fatalf("Add agent: %v", err)
	}

	gin.SetMode(gin.TestMode)
	router := gin.New()
	router.GET("/agents", NewListAgentsHandler(dashboardTestSessionStore{sessions: []types.SessionSnapshot{
		{
			AgentConfigID:    "server-agent",
			ServerAgentID:    "agt_server",
			Status:           "running",
			Activity:         "thinking",
			ActivityDetail:   "Investigating",
			StartedAt:        time.Now(),
			RuntimeSessionID: "sess-live",
		},
	}}))

	req := httptest.NewRequest(http.MethodGet, "/agents", nil)
	rec := httptest.NewRecorder()
	router.ServeHTTP(rec, req)
	if rec.Code != http.StatusOK {
		t.Fatalf("status = %d, want 200: %s", rec.Code, rec.Body.String())
	}

	var resp []agentview.Snapshot
	if err := json.Unmarshal(rec.Body.Bytes(), &resp); err != nil {
		t.Fatalf("decode response: %v", err)
	}
	if len(resp) != 1 {
		t.Fatalf("len(response) = %d, want 1", len(resp))
	}
	if !resp[0].BackendRegistered {
		t.Fatal("BackendRegistered = false, want true")
	}
	if resp[0].Status != "running" {
		t.Fatalf("Status = %q, want running", resp[0].Status)
	}
}
