package tour

import (
	"testing"

	"github.com/stretchr/testify/require"
	"github.com/tidbcloud/AgentTeam/kits/agentteam-insight/internal/graphbuilder/schema"
)

// This fixture is a mechanical translation of Understand Anything
// packages/core/src/__tests__/tour-generator.test.ts::sampleGraph at 6ae71878.
func upstreamTourFixture() schema.KnowledgeGraph {
	return schema.KnowledgeGraph{
		Nodes: []schema.GraphNode{
			{ID: "file:src/index.ts", Type: "file", Name: "index.ts", FilePath: "src/index.ts", Summary: "Application entry point"},
			{ID: "file:src/routes.ts", Type: "file", Name: "routes.ts", FilePath: "src/routes.ts", Summary: "Route definitions"},
			{ID: "file:src/service.ts", Type: "file", Name: "service.ts", FilePath: "src/service.ts", Summary: "Business logic"},
			{ID: "file:src/db.ts", Type: "file", Name: "db.ts", FilePath: "src/db.ts", Summary: "Database connection"},
			{ID: "concept:auth-flow", Type: "concept", Name: "Auth Flow", Summary: "Authentication concept"},
		},
		Edges: []schema.GraphEdge{
			{Source: "file:src/index.ts", Target: "file:src/routes.ts", Type: "imports"},
			{Source: "file:src/routes.ts", Target: "file:src/service.ts", Type: "calls"},
			{Source: "file:src/service.ts", Target: "file:src/db.ts", Type: "reads_from"},
		},
		Layers: []schema.Layer{
			{ID: "layer:api", Name: "API Layer", Description: "HTTP routes", NodeIDs: []string{"file:src/index.ts", "file:src/routes.ts"}},
			{ID: "layer:service", Name: "Service Layer", Description: "Business logic", NodeIDs: []string{"file:src/service.ts"}},
			{ID: "layer:data", Name: "Data Layer", Description: "Database", NodeIDs: []string{"file:src/db.ts"}},
		},
	}
}

func TestGenerateMatchesUpstreamLayeredGolden(t *testing.T) {
	generated := Generate(upstreamTourFixture(), Options{ProjectName: "ignored", MaxSteps: 1, OutputLanguage: "zh"})
	require.Equal(t, []schema.TourStep{
		{Order: 1, Title: "API Layer", Description: "HTTP routes. Key files: index.ts, routes.ts.", NodeIDs: []string{"file:src/index.ts", "file:src/routes.ts"}},
		{Order: 2, Title: "Service Layer", Description: "Business logic. Key files: service.ts.", NodeIDs: []string{"file:src/service.ts"}},
		{Order: 3, Title: "Data Layer", Description: "Database. Key files: db.ts.", NodeIDs: []string{"file:src/db.ts"}},
		{Order: 4, Title: "Key Concepts", Description: "Important architectural concepts: Auth Flow (Authentication concept).", NodeIDs: []string{"concept:auth-flow"}},
	}, generated)
}

func TestGenerateMatchesUpstreamNoLayerGolden(t *testing.T) {
	graph := upstreamTourFixture()
	graph.Layers = nil
	generated := Generate(graph, Options{})
	require.Equal(t, []schema.TourStep{
		{Order: 1, Title: "Step 1: Code Walkthrough", Description: "Exploring: index.ts (Application entry point); routes.ts (Route definitions); service.ts (Business logic).", NodeIDs: []string{"file:src/index.ts", "file:src/routes.ts", "file:src/service.ts"}},
		{Order: 2, Title: "Step 2: Code Walkthrough", Description: "Exploring: db.ts (Database connection).", NodeIDs: []string{"file:src/db.ts"}},
		{Order: 3, Title: "Key Concepts", Description: "Important architectural concepts: Auth Flow (Authentication concept).", NodeIDs: []string{"concept:auth-flow"}},
	}, generated)
}

func TestGeneratePreservesUpstreamNonLexicalKahnAndLayerOrder(t *testing.T) {
	graph := schema.KnowledgeGraph{
		Nodes: []schema.GraphNode{
			{ID: "z-entry", Type: "file", Name: "z", Summary: "Z"},
			{ID: "a-entry", Type: "file", Name: "a", Summary: "A"},
			{ID: "m-tail", Type: "file", Name: "m", Summary: "M"},
		},
		Edges: []schema.GraphEdge{
			{Source: "z-entry", Target: "m-tail", Type: "imports"},
			{Source: "a-entry", Target: "m-tail", Type: "calls"},
		},
		Layers: []schema.Layer{
			{ID: "layer:tail", Name: "Tail", Description: "Tail", NodeIDs: []string{"m-tail"}},
			{ID: "layer:entries", Name: "Entries", Description: "Entries", NodeIDs: []string{"a-entry", "z-entry"}},
		},
	}
	require.Equal(t, []schema.TourStep{
		{Order: 1, Title: "Entries", Description: "Entries. Key files: z, a.", NodeIDs: []string{"z-entry", "a-entry"}},
		{Order: 2, Title: "Tail", Description: "Tail. Key files: m.", NodeIDs: []string{"m-tail"}},
	}, Generate(graph, Options{}))
}

func TestGenerateMatchesUpstreamCycleAndSupportingFallback(t *testing.T) {
	graph := schema.KnowledgeGraph{
		Nodes: []schema.GraphNode{
			{ID: "a", Type: "file", Name: "a", Summary: "A"},
			{ID: "b", Type: "file", Name: "b", Summary: "B"},
			{ID: "c", Type: "config", Name: "c", Summary: "C"},
		},
		Edges: []schema.GraphEdge{
			{Source: "a", Target: "b", Type: "imports"},
			{Source: "b", Target: "a", Type: "imports"},
		},
		Layers: []schema.Layer{{ID: "layer:code", Name: "Code", Description: "Code files", NodeIDs: []string{"a", "b"}}},
	}
	require.Equal(t, []schema.TourStep{
		{Order: 1, Title: "Code", Description: "Code files. Key files: a, b.", NodeIDs: []string{"a", "b"}},
		{Order: 2, Title: "Supporting Components", Description: "Additional supporting files: c.", NodeIDs: []string{"c"}},
	}, Generate(graph, Options{}))
}

func TestNormalizeFiltersDanglingAndRenumbers(t *testing.T) {
	steps := []schema.TourStep{
		{Order: 7, Title: "", Description: "", NodeIDs: []string{"missing"}},
		{Order: 9, Title: "Start", Description: "", NodeIDs: []string{"b", "a", "a", "missing"}},
	}
	valid := map[string]struct{}{"a": {}, "b": {}}
	normalized := Normalize(steps, valid)
	require.Equal(t, []schema.TourStep{{Order: 1, Title: "Start", Description: "Start", NodeIDs: []string{"b", "a"}}}, normalized)
}
