package menu

import (
	"bytes"
	"os"
	"strings"
	"testing"
)

func TestNewMenuUtils(t *testing.T) {
	utils := NewMenuUtils()
	if utils == nil {
		t.Fatal("NewMenuUtils() returned nil")
	}
}

func TestMenuUtils_PrintSeparator(t *testing.T) {
	utils := NewMenuUtils()

	// 重定向stdout
	oldStdout := os.Stdout
	r, w, _ := os.Pipe()
	os.Stdout = w

	utils.PrintSeparator()

	w.Close()
	os.Stdout = oldStdout

	var output bytes.Buffer
	output.ReadFrom(r)

	expected := "============================================================"
	if !strings.Contains(output.String(), expected) {
		t.Errorf("Expected separator %q, got %q", expected, output.String())
	}
}

func TestMenuUtils_PrintSection(t *testing.T) {
	utils := NewMenuUtils()
	title := "Test Section"

	oldStdout := os.Stdout
	r, w, _ := os.Pipe()
	os.Stdout = w

	utils.PrintSection(title)

	w.Close()
	os.Stdout = oldStdout

	var output bytes.Buffer
	output.ReadFrom(r)

	outputStr := output.String()
	if !strings.Contains(outputStr, title) {
		t.Errorf("Expected title %q in output, got %q", title, outputStr)
	}

	if !strings.Contains(outputStr, "============================================================") {
		t.Error("Expected separator in output")
	}
}

func TestMenuUtils_ValidateChoice(t *testing.T) {
	utils := NewMenuUtils()

	tests := []struct {
		name   string
		choice int
		min    int
		max    int
		expect bool
	}{
		{
			name:   "Valid choice in range",
			choice: 3,
			min:    1,
			max:    5,
			expect: true,
		},
		{
			name:   "Choice below minimum",
			choice: 0,
			min:    1,
			max:    5,
			expect: false,
		},
		{
			name:   "Choice above maximum",
			choice: 6,
			min:    1,
			max:    5,
			expect: false,
		},
		{
			name:   "Choice at minimum",
			choice: 1,
			min:    1,
			max:    5,
			expect: true,
		},
		{
			name:   "Choice at maximum",
			choice: 5,
			min:    1,
			max:    5,
			expect: true,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result := utils.ValidateChoice(tt.choice, tt.min, tt.max)
			if result != tt.expect {
				t.Errorf("ValidateChoice(%d, %d, %d) = %v; want %v",
					tt.choice, tt.min, tt.max, result, tt.expect)
			}
		})
	}
}

func TestMenuUtils_ReadString(t *testing.T) {
	utils := NewMenuUtils()

	// 这个测试比较复杂，因为需要模拟用户输入
	// 在实际项目中，你可能需要使用接口来使这个函数可测试
	// 这里我们只测试基本结构
	if utils == nil {
		t.Error("MenuUtils should not be nil")
	}
}

func TestMenuUtils_ReadStringWithDefault(t *testing.T) {
	utils := NewMenuUtils()

	// 同样，这个测试需要模拟用户输入
	if utils == nil {
		t.Error("MenuUtils should not be nil")
	}
}

// 基准测试
func BenchmarkMenuUtils_PrintSeparator(b *testing.B) {
	utils := NewMenuUtils()

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		oldStdout := os.Stdout
		r, w, _ := os.Pipe()
		os.Stdout = w

		utils.PrintSeparator()

		w.Close()
		os.Stdout = oldStdout
		_ = r
	}
}

func BenchmarkMenuUtils_ValidateChoice(b *testing.B) {
	utils := NewMenuUtils()

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		utils.ValidateChoice(3, 1, 5)
	}
}
