package core

import (
	"strings"
	"testing"
)

func TestTopologicalSort(t *testing.T) {
	issues := []Issue{
		{Number: 1, Title: "base", Deps: nil},
		{Number: 2, Title: "depends on 1", Deps: []int{1}},
		{Number: 3, Title: "independent", Deps: nil},
		{Number: 4, Title: "depends on 1 and 3", Deps: []int{1, 3}},
	}

	result := TopologicalSort(issues)
	if result.IsErr() {
		t.Fatalf("TopologicalSort failed: %v", result.Error())
	}

	groups := result.Unwrap()
	if len(groups) < 2 {
		t.Fatalf("expected at least 2 groups, got %d", len(groups))
	}

	// Group 1 should have issues 1 and 3 (no deps)
	g1Nums := make(map[int]bool)
	for _, issue := range groups[0].Issues {
		g1Nums[issue.Number] = true
	}
	if !g1Nums[1] || !g1Nums[3] {
		t.Errorf("group 1 should contain issues 1 and 3, got %v", groups[0].Issues)
	}
}

func TestTopologicalSortCycle(t *testing.T) {
	issues := []Issue{
		{Number: 1, Title: "a", Deps: []int{2}},
		{Number: 2, Title: "b", Deps: []int{1}},
	}

	result := TopologicalSort(issues)
	if !result.IsErr() {
		t.Error("expected cycle detection error")
	}
	if !strings.Contains(result.Error().Error(), "circular") {
		t.Errorf("expected circular dependency error, got: %v", result.Error())
	}
}

func TestTopologicalSortEmpty(t *testing.T) {
	result := TopologicalSort(nil)
	if !result.IsErr() {
		t.Error("expected error for empty issues")
	}
}

func TestAnalyzeFileConflicts(t *testing.T) {
	files := map[int][]string{
		1: {"core/types.go", "shell/http.go"},
		2: {"core/types.go", "app/main.go"},
		3: {"app/other.go"},
	}

	conflicts := AnalyzeFileConflicts(files)
	if len(conflicts) != 1 {
		t.Fatalf("expected 1 conflict, got %d", len(conflicts))
	}
	if conflicts[0].IssueA != 1 || conflicts[0].IssueB != 2 {
		t.Errorf("expected conflict between 1 and 2, got %d and %d",
			conflicts[0].IssueA, conflicts[0].IssueB)
	}
	if conflicts[0].SharedFiles[0] != "core/types.go" {
		t.Errorf("expected shared file core/types.go, got %s", conflicts[0].SharedFiles[0])
	}
}

func TestGeneratePlanMarkdown(t *testing.T) {
	groups := []IssueGroup{
		{Number: 1, Issues: []Issue{
			{Number: 1, Title: "base"},
			{Number: 3, Title: "other"},
		}},
		{Number: 2, Issues: []Issue{
			{Number: 2, Title: "depends", Deps: []int{1}},
		}},
	}

	md := GeneratePlanMarkdown(groups, nil)
	if !strings.Contains(md, "## Grupo 1") {
		t.Error("markdown should contain group headers")
	}
	if !strings.Contains(md, "Issue #0001") {
		t.Error("markdown should contain issue references")
	}
	if !strings.Contains(md, "3 issues") || !strings.Contains(md, "2 grupos") {
		// Check summary table
		if !strings.Contains(md, "| 3 |") {
			t.Error("markdown should contain correct totals")
		}
	}
}
