package utils

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

func TestLogLevel_String(t *testing.T) {
	tests := []struct {
		level    LogLevel
		expected string
	}{
		{DEBUG, "DEBUG"},
		{INFO, "INFO"},
		{WARN, "WARN"},
		{ERROR, "ERROR"},
		{FATAL, "FATAL"},
		{LogLevel(999), "UNKNOWN"},
	}

	for _, tt := range tests {
		t.Run(tt.level.String(), func(t *testing.T) {
			if result := tt.level.String(); result != tt.expected {
				t.Errorf("LogLevel.String() = %v, want %v", result, tt.expected)
			}
		})
	}
}

func TestLogLevel_Color(t *testing.T) {
	tests := []struct {
		level    LogLevel
		expected string
	}{
		{DEBUG, "\033[36m"},
		{INFO, "\033[32m"},
		{WARN, "\033[33m"},
		{ERROR, "\033[31m"},
		{FATAL, "\033[35m"},
		{LogLevel(999), "\033[0m"},
	}

	for _, tt := range tests {
		t.Run(tt.level.String(), func(t *testing.T) {
			if result := tt.level.Color(); result != tt.expected {
				t.Errorf("LogLevel.Color() = %v, want %v", result, tt.expected)
			}
		})
	}
}

func TestNewLogger(t *testing.T) {
	config := &LoggerConfig{
		Level:       INFO,
		LogToFile:   false,
		ServiceName: "test-service",
		ColorOutput: false,
	}

	logger, err := NewLogger(config)
	if err != nil {
		t.Fatalf("NewLogger() error = %v", err)
	}

	if logger == nil {
		t.Fatal("NewLogger() returned nil")
	}

	if logger.level != INFO {
		t.Errorf("logger.level = %v, want %v", logger.level, INFO)
	}

	if logger.service != "test-service" {
		t.Errorf("logger.service = %v, want %v", logger.service, "test-service")
	}

	// 清理
	logger.Close()
}

func TestLogger_SetLevel(t *testing.T) {
	logger, _ := NewLogger(&LoggerConfig{
		Level:       INFO,
		ServiceName: "test",
		ColorOutput: false,
	})

	logger.SetLevel(ERROR)
	if logger.level != ERROR {
		t.Errorf("SetLevel() = %v, want %v", logger.level, ERROR)
	}

	logger.Close()
}

func TestLogger_SetService(t *testing.T) {
	logger, _ := NewLogger(&LoggerConfig{
		Level:       INFO,
		ServiceName: "test",
		ColorOutput: false,
	})

	logger.SetService("new-service")
	if logger.service != "new-service" {
		t.Errorf("SetService() = %v, want %v", logger.service, "new-service")
	}

	logger.Close()
}

func TestNewDefaultLogger(t *testing.T) {
	logger, err := NewDefaultLogger()
	if err != nil {
		t.Fatalf("NewDefaultLogger() error = %v", err)
	}

	if logger == nil {
		t.Fatal("NewDefaultLogger() returned nil")
	}

	if logger.service == "" {
		t.Error("service name should not be empty")
	}

	if !logger.logToFile {
		t.Error("LogToFile should be true by default")
	}

	logger.Close()

	// 清理日志文件
	if logger.logPath != "" {
		os.Remove(logger.logPath)
	}
}

func TestLogger_WithField(t *testing.T) {
	logger, _ := NewLogger(&LoggerConfig{
		Level:       INFO,
		ServiceName: "test",
		ColorOutput: false,
	})

	fieldLogger := logger.WithField("key", "value")
	if fieldLogger == nil {
		t.Fatal("WithField() returned nil")
	}

	if fieldLogger.logger != logger {
		t.Error("fieldLogger.logger should be the same as original logger")
	}

	if fieldLogger.fields["key"] != "value" {
		t.Errorf("fieldLogger.fields[\"key\"] = %v, want %v", fieldLogger.fields["key"], "value")
	}

	logger.Close()
}

func TestLogger_WithFields(t *testing.T) {
	logger, _ := NewLogger(&LoggerConfig{
		Level:       INFO,
		ServiceName: "test",
		ColorOutput: false,
	})

	fields := map[string]string{
		"key1": "value1",
		"key2": "value2",
	}

	fieldLogger := logger.WithFields(fields)
	if fieldLogger == nil {
		t.Fatal("WithFields() returned nil")
	}

	if len(fieldLogger.fields) != 2 {
		t.Errorf("len(fieldLogger.fields) = %v, want %v", len(fieldLogger.fields), 2)
	}

	if fieldLogger.fields["key1"] != "value1" {
		t.Errorf("fieldLogger.fields[\"key1\"] = %v, want %v", fieldLogger.fields["key1"], "value1")
	}

	logger.Close()
}

func TestFieldLogger_formatFields(t *testing.T) {
	logger, _ := NewLogger(&LoggerConfig{
		Level:       INFO,
		ServiceName: "test",
		ColorOutput: false,
	})

	// 测试空字段（不使用空键值对，而是使用nil字段）
	var emptyFields map[string]string
	emptyLogger := &FieldLogger{
		logger: logger,
		fields: emptyFields,
	}
	result := emptyLogger.formatFields()
	if result != "" {
		t.Errorf("formatFields() with nil fields = %v, want %v", result, "")
	}

	// 测试单个字段
	singleLogger := logger.WithField("key", "value")
	result = singleLogger.formatFields()
	expected := " {key=value}"
	if result != expected {
		t.Errorf("formatFields() with single field = %v, want %v", result, expected)
	}

	// 测试多个字段
	multiLogger := logger.WithFields(map[string]string{
		"key1": "value1",
		"key2": "value2",
	})
	result = multiLogger.formatFields()
	// 结果应该是以下两种之一，取决于map迭代顺序
	if result != " {key1=value1, key2=value2}" && result != " {key2=value2, key1=value1}" {
		t.Errorf("formatFields() with multiple fields = %v, want one of the expected formats", result)
	}

	logger.Close()
}

func TestInitDefaultLogger(t *testing.T) {
	err := InitDefaultLogger()
	if err != nil {
		t.Fatalf("InitDefaultLogger() error = %v", err)
	}

	logger := GetDefaultLogger()
	if logger == nil {
		t.Fatal("GetDefaultLogger() returned nil after InitDefaultLogger()")
	}

	if logger.service == "" {
		t.Error("service name should not be empty after initialization")
	}

	// 清理
	if logger.logPath != "" {
		os.Remove(logger.logPath)
	}
}

func TestGlobalLoggerFunctions(t *testing.T) {
	// 初始化默认日志记录器
	InitDefaultLogger()
	defer func() {
		logger := GetDefaultLogger()
		if logger.logPath != "" {
			os.Remove(logger.logPath)
		}
	}()

	// 这些函数主要是测试它们不会panic
	// 实际的输出验证比较困难，因为它们输出到stdout
	Info("Test info message: %s", "test")
	Debug("Test debug message: %s", "test")
	Warn("Test warn message: %s", "test")
	Error("Test error message: %s", "test")

	// 注意：不能测试Fatal，因为它会调用os.Exit(1)
}

func TestGlobalFieldLoggerFunctions(t *testing.T) {
	// 初始化默认日志记录器
	InitDefaultLogger()
	defer func() {
		logger := GetDefaultLogger()
		if logger.logPath != "" {
			os.Remove(logger.logPath)
		}
	}()

	// 测试全局字段日志记录器
	fieldLogger := WithField("test", "value")
	if fieldLogger == nil {
		t.Fatal("WithField() returned nil")
	}

	fieldLogger.Info("Test message with field")

	// 测试多字段全局日志记录器
	fieldsLogger := WithFields(map[string]string{
		"key1": "value1",
		"key2": "value2",
	})
	if fieldsLogger == nil {
		t.Fatal("WithFields() returned nil")
	}

	fieldsLogger.Info("Test message with fields")
}

func TestLogger_FileLogging(t *testing.T) {
	// 创建临时日志文件
	tempFile := "test.log"
	defer os.Remove(tempFile)

	config := &LoggerConfig{
		Level:       DEBUG,
		LogToFile:   true,
		LogPath:     tempFile,
		ServiceName: "test-service",
		ColorOutput: false,
	}

	logger, err := NewLogger(config)
	if err != nil {
		t.Fatalf("NewLogger() error = %v", err)
	}
	defer logger.Close()

	// 写入一些日志
	logger.Info("Test log message")
	logger.Error("Test error message")

	// 关闭日志记录器以确保内容写入文件
	logger.Close()

	// 读取日志文件
	content, err := os.ReadFile(tempFile)
	if err != nil {
		t.Fatalf("ReadFile() error = %v", err)
	}

	contentStr := string(content)
	if !strings.Contains(contentStr, "Test log message") {
		t.Error("Log file should contain test message")
	}

	if !strings.Contains(contentStr, "Test error message") {
		t.Error("Log file should contain error message")
	}

	if !strings.Contains(contentStr, "test-service") {
		t.Error("Log file should contain service name")
	}
}
