package logs

import (
	"fmt"

	"go.uber.org/zap/zapcore"
)

// logWithTrace 是一个私有的辅助函数，用于统一处理日志记录。
// 它会检查 logger 实例中是否包含 traceValue，如果存在，则将其作为最后一个结构化字段追加。
// 然后，它根据传入的日志级别，调用底层 SugaredLogger 对应级别的 '...w' 方法。
func (l *Logger) logWithTrace(level zapcore.Level, msg string, keysAndValues ...interface{}) {
	// 如果存在调用链信息，则将其追加到键值对列表的末尾
	if l.traceValue != "" {
		keysAndValues = append(keysAndValues, traceKey, l.traceValue)
	}

	// 根据级别调用相应的 '...w' 方法
	switch level {
	case zapcore.DebugLevel:
		l.sl.Debugw(msg, keysAndValues...)
	case zapcore.InfoLevel:
		l.sl.Infow(msg, keysAndValues...)
	case zapcore.WarnLevel:
		l.sl.Warnw(msg, keysAndValues...)
	case zapcore.ErrorLevel:
		l.sl.Errorw(msg, keysAndValues...)
	case zapcore.DPanicLevel:
		l.sl.DPanicw(msg, keysAndValues...)
	case zapcore.PanicLevel:
		l.sl.Panicw(msg, keysAndValues...)
	case zapcore.FatalLevel:
		l.sl.Fatalw(msg, keysAndValues...)
	}
}

// --- 重写所有日志记录方法 ---

// Debug 使用 fmt.Sprint 格式化参数并记录 Debug 级别的日志。
func (l *Logger) Debug(args ...interface{}) {
	l.logWithTrace(zapcore.DebugLevel, fmt.Sprint(args...))
}

// Info 使用 fmt.Sprint 格式化参数并记录 Info 级别的日志。
func (l *Logger) Info(args ...interface{}) {
	l.logWithTrace(zapcore.InfoLevel, fmt.Sprint(args...))
}

// Warn 使用 fmt.Sprint 格式化参数并记录 Warn 级别的日志。
func (l *Logger) Warn(args ...interface{}) {
	l.logWithTrace(zapcore.WarnLevel, fmt.Sprint(args...))
}

// Error 使用 fmt.Sprint 格式化参数并记录 Error 级别的日志。
func (l *Logger) Error(args ...interface{}) {
	l.logWithTrace(zapcore.ErrorLevel, fmt.Sprint(args...))
}

// DPanic 使用 fmt.Sprint 格式化参数并记录 DPanic 级别的日志。
func (l *Logger) DPanic(args ...interface{}) {
	l.logWithTrace(zapcore.DPanicLevel, fmt.Sprint(args...))
}

// Panic 使用 fmt.Sprint 格式化参数并记录 Panic 级别的日志。
func (l *Logger) Panic(args ...interface{}) {
	l.logWithTrace(zapcore.PanicLevel, fmt.Sprint(args...))
}

// Fatal 使用 fmt.Sprint 格式化参数并记录 Fatal 级别的日志。
func (l *Logger) Fatal(args ...interface{}) {
	l.logWithTrace(zapcore.FatalLevel, fmt.Sprint(args...))
}

// Debugf 使用 fmt.Sprintf 格式化模板和参数，并记录 Debug 级别的日志。
func (l *Logger) Debugf(template string, args ...interface{}) {
	l.logWithTrace(zapcore.DebugLevel, fmt.Sprintf(template, args...))
}

// Infof 使用 fmt.Sprintf 格式化模板和参数，并记录 Info 级别的日志。
func (l *Logger) Infof(template string, args ...interface{}) {
	l.logWithTrace(zapcore.InfoLevel, fmt.Sprintf(template, args...))
}

// Warnf 使用 fmt.Sprintf 格式化模板和参数，并记录 Warn 级别的日志。
func (l *Logger) Warnf(template string, args ...interface{}) {
	l.logWithTrace(zapcore.WarnLevel, fmt.Sprintf(template, args...))
}

// Errorf 使用 fmt.Sprintf 格式化模板和参数，并记录 Error 级别的日志。
func (l *Logger) Errorf(template string, args ...interface{}) {
	l.logWithTrace(zapcore.ErrorLevel, fmt.Sprintf(template, args...))
}

// DPanicf 使用 fmt.Sprintf 格式化模板和参数，并记录 DPanic 级别的日志。
func (l *Logger) DPanicf(template string, args ...interface{}) {
	l.logWithTrace(zapcore.DPanicLevel, fmt.Sprintf(template, args...))
}

// Panicf 使用 fmt.Sprintf 格式化模板和参数，并记录 Panic 级别的日志。
func (l *Logger) Panicf(template string, args ...interface{}) {
	l.logWithTrace(zapcore.PanicLevel, fmt.Sprintf(template, args...))
}

// Fatalf 使用 fmt.Sprintf 格式化模板和参数，并记录 Fatal 级别的日志。
func (l *Logger) Fatalf(template string, args ...interface{}) {
	l.logWithTrace(zapcore.FatalLevel, fmt.Sprintf(template, args...))
}

// Debugw 记录 Debug 级别的结构化日志。
func (l *Logger) Debugw(msg string, keysAndValues ...interface{}) {
	l.logWithTrace(zapcore.DebugLevel, msg, keysAndValues...)
}

// Infow 记录 Info 级别的结构化日志。
func (l *Logger) Infow(msg string, keysAndValues ...interface{}) {
	l.logWithTrace(zapcore.InfoLevel, msg, keysAndValues...)
}

// Warnw 记录 Warn 级别的结构化日志。
func (l *Logger) Warnw(msg string, keysAndValues ...interface{}) {
	l.logWithTrace(zapcore.WarnLevel, msg, keysAndValues...)
}

// Errorw 记录 Error 级别的结构化日志。
func (l *Logger) Errorw(msg string, keysAndValues ...interface{}) {
	l.logWithTrace(zapcore.ErrorLevel, msg, keysAndValues...)
}

// DPanicw 记录 DPanic 级别的结构化日志。
func (l *Logger) DPanicw(msg string, keysAndValues ...interface{}) {
	l.logWithTrace(zapcore.DPanicLevel, msg, keysAndValues...)
}

// Panicw 记录 Panic 级别的结构化日志。
func (l *Logger) Panicw(msg string, keysAndValues ...interface{}) {
	l.logWithTrace(zapcore.PanicLevel, msg, keysAndValues...)
}

// Fatalw 记录 Fatal 级别的结构化日志。
func (l *Logger) Fatalw(msg string, keysAndValues ...interface{}) {
	l.logWithTrace(zapcore.FatalLevel, msg, keysAndValues...)
}

// With 在 zap 中，With 方法返回的是一个新的 SugaredLogger。
// 为了保持兼容性并继续传递 traceValue，我们需要在这里也返回一个新的 Logger 实例。
func (l *Logger) With(args ...interface{}) *Logger {
	newSl := l.sl.With(args...)
	return &Logger{sl: newSl, traceValue: l.traceValue}
}

func (l *Logger) Sync() error {
	return l.sl.Sync()
}
