package logger

import (
    "fmt"
    "io"
    "os"
    "path/filepath"
    "time"

	"github.com/sirupsen/logrus"
	"gopkg.in/natefinch/lumberjack.v2"
)

var Logger *logrus.Logger

// LogConfig 日志配置
type LogConfig struct {
	Level      string `json:"level"`      // 日志级别
	Format     string `json:"format"`     // 日志格式 json/text
	Output     string `json:"output"`     // 输出方式 console/file/both
	FilePath   string `json:"file_path"`  // 日志文件路径
	MaxSize    int    `json:"max_size"`   // 单个日志文件最大大小(MB)
	MaxBackups int    `json:"max_backups"` // 保留的旧日志文件数量
	MaxAge     int    `json:"max_age"`    // 日志文件保留天数
	Compress   bool   `json:"compress"`   // 是否压缩旧日志文件
}

// InitLogger 初始化日志系统
func InitLogger(config LogConfig) {
	Logger = logrus.New()

	// 设置日志级别
	setLogLevel(config.Level)

	// 设置日志格式
	setLogFormat(config.Format)

	// 设置日志输出
	setLogOutput(config)

	// 添加钩子
	addHooks()

	Logger.Info("Logger initialized successfully")
}

// setLogLevel 设置日志级别
func setLogLevel(level string) {
	switch level {
	case "debug":
		Logger.SetLevel(logrus.DebugLevel)
	case "info":
		Logger.SetLevel(logrus.InfoLevel)
	case "warn":
		Logger.SetLevel(logrus.WarnLevel)
	case "error":
		Logger.SetLevel(logrus.ErrorLevel)
	case "fatal":
		Logger.SetLevel(logrus.FatalLevel)
	case "panic":
		Logger.SetLevel(logrus.PanicLevel)
	default:
		Logger.SetLevel(logrus.InfoLevel)
	}
}

// setLogFormat 设置日志格式
func setLogFormat(format string) {
	switch format {
	case "json":
		Logger.SetFormatter(&logrus.JSONFormatter{
			TimestampFormat: time.RFC3339,
		})
	case "text":
		Logger.SetFormatter(&logrus.TextFormatter{
			FullTimestamp:   true,
			TimestampFormat: "2006-01-02 15:04:05",
		})
	default:
		Logger.SetFormatter(&logrus.JSONFormatter{
			TimestampFormat: time.RFC3339,
		})
	}
}

// setLogOutput 设置日志输出
func setLogOutput(config LogConfig) {
	switch config.Output {
	case "console":
		Logger.SetOutput(os.Stdout)
	case "file":
		setFileOutput(config)
	case "both":
		setBothOutput(config)
	default:
		Logger.SetOutput(os.Stdout)
	}
}

// setFileOutput 设置文件输出
func setFileOutput(config LogConfig) {
	// 确保日志目录存在
	logDir := filepath.Dir(config.FilePath)
	if err := os.MkdirAll(logDir, 0755); err != nil {
		fmt.Printf("Failed to create log directory: %v\n", err)
		return
	}

	// 配置日志轮转
	lumberjackLogger := &lumberjack.Logger{
		Filename:   config.FilePath,
		MaxSize:    config.MaxSize,
		MaxBackups: config.MaxBackups,
		MaxAge:     config.MaxAge,
		Compress:   config.Compress,
	}

	Logger.SetOutput(lumberjackLogger)
}

// setBothOutput 设置同时输出到控制台和文件
func setBothOutput(config LogConfig) {
    // 确保日志目录存在
    logDir := filepath.Dir(config.FilePath)
    if err := os.MkdirAll(logDir, 0755); err != nil {
        fmt.Printf("Failed to create log directory: %v\n", err)
        Logger.SetOutput(os.Stdout)
        return
    }

    // 配置日志轮转
    lumberjackLogger := &lumberjack.Logger{
        Filename:   config.FilePath,
        MaxSize:    config.MaxSize,
        MaxBackups: config.MaxBackups,
        MaxAge:     config.MaxAge,
        Compress:   config.Compress,
    }

    // 同时输出到控制台和文件，避免嵌套/转义问题
    Logger.SetOutput(io.MultiWriter(os.Stdout, lumberjackLogger))
}

// addHooks 添加日志钩子
func addHooks() {
	// 添加调用者信息钩子
	Logger.AddHook(&CallerHook{})
}

// FileHook 文件输出钩子
type FileHook struct {
	Writer *lumberjack.Logger
}

func (hook *FileHook) Fire(entry *logrus.Entry) error {
	line, err := entry.String()
	if err != nil {
		return err
	}
	_, err = hook.Writer.Write([]byte(line))
	return err
}

func (hook *FileHook) Levels() []logrus.Level {
	return logrus.AllLevels
}

// CallerHook 调用者信息钩子
type CallerHook struct{}

func (hook *CallerHook) Fire(entry *logrus.Entry) error {
	if entry.HasCaller() {
		entry.Data["file"] = fmt.Sprintf("%s:%d", filepath.Base(entry.Caller.File), entry.Caller.Line)
		entry.Data["function"] = entry.Caller.Function
	}
	return nil
}

func (hook *CallerHook) Levels() []logrus.Level {
	return logrus.AllLevels
}

// 便捷方法
func Debug(args ...interface{}) {
	Logger.Debug(args...)
}

func Debugf(format string, args ...interface{}) {
	Logger.Debugf(format, args...)
}

func Info(args ...interface{}) {
	Logger.Info(args...)
}

func Infof(format string, args ...interface{}) {
	Logger.Infof(format, args...)
}

func Warn(args ...interface{}) {
	Logger.Warn(args...)
}

func Warnf(format string, args ...interface{}) {
	Logger.Warnf(format, args...)
}

func Error(args ...interface{}) {
	Logger.Error(args...)
}

func Errorf(format string, args ...interface{}) {
	Logger.Errorf(format, args...)
}

func Fatal(args ...interface{}) {
	Logger.Fatal(args...)
}

func Fatalf(format string, args ...interface{}) {
	Logger.Fatalf(format, args...)
}

func Panic(args ...interface{}) {
	Logger.Panic(args...)
}

func Panicf(format string, args ...interface{}) {
	Logger.Panicf(format, args...)
}

// WithFields 创建带字段的日志条目
func WithFields(fields logrus.Fields) *logrus.Entry {
	return Logger.WithFields(fields)
}

// WithField 创建带单个字段的日志条目
func WithField(key string, value interface{}) *logrus.Entry {
	return Logger.WithField(key, value)
}

// WithError 创建带错误信息的日志条目
func WithError(err error) *logrus.Entry {
	return Logger.WithError(err)
}