package logger

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

var (
	Log *zap.Logger
	Sugar *zap.SugaredLogger
)

// Config holds logger configuration
type Config struct {
	Level      string `mapstructure:"level"`
	Encoding   string `mapstructure:"encoding"`
	OutputPath string `mapstructure:"output_path"`
}

// Init initializes the global logger
func Init(cfg *Config) error {
	level := zapcore.InfoLevel
	if cfg != nil && cfg.Level != "" {
		if err := level.UnmarshalText([]byte(cfg.Level)); err != nil {
			return err
		}
		// Debug output to verify level parsing
		println("DEBUG: Parsed level:", level.String())
	}

	encoding := "json"
	if cfg != nil && cfg.Encoding != "" {
		encoding = cfg.Encoding
	}

	outputPath := "stdout"
	if cfg != nil && cfg.OutputPath != "" {
		outputPath = cfg.OutputPath
	}

	atomicLevel := zap.NewAtomicLevelAt(level)
	println("DEBUG: Created AtomicLevel:", atomicLevel.String())

	zapConfig := zap.Config{
		Level:             atomicLevel,
		Development:       true,  // Changed to true to test if this affects debug logging
		DisableCaller:     false,
		DisableStacktrace: false,
		Sampling:          nil,
		Encoding:          encoding,
		EncoderConfig: zapcore.EncoderConfig{
			MessageKey:     "message",
			LevelKey:       "level",
			TimeKey:        "time",
			NameKey:        "logger",
			CallerKey:      "caller",
			FunctionKey:    zapcore.OmitKey,
			StacktraceKey:  "stacktrace",
			LineEnding:     zapcore.DefaultLineEnding,
			EncodeLevel:    zapcore.LowercaseLevelEncoder,
			EncodeTime:     zapcore.ISO8601TimeEncoder,
			EncodeDuration: zapcore.SecondsDurationEncoder,
			EncodeCaller:   zapcore.ShortCallerEncoder,
		},
		OutputPaths:      []string{outputPath},
		ErrorOutputPaths: []string{"stderr"},
	}

	var err error
	Log, err = zapConfig.Build()
	if err != nil {
		return err
	}

	println("DEBUG: After Build, AtomicLevel:", atomicLevel.String())
	println("DEBUG: After Build, Log.Level():", Log.Level().String())

	// TEST: Try to log a debug message immediately after Build()
	Log.Debug("INTERNAL TEST: Debug log immediately after Build()")
	Log.Info("INTERNAL TEST: Info log immediately after Build()")

	Sugar = Log.Sugar()

	// Replace global zap logger to ensure our config takes effect
	zap.ReplaceGlobals(Log)

	// Debug output to verify logger initialization
	println("DEBUG: Logger initialized with level:", Log.Level().String())

	return nil
}

// InitDevelopment initializes logger for development environment
func InitDevelopment() error {
	var err error
	Log, err = zap.NewDevelopment()
	if err != nil {
		return err
	}
	Sugar = Log.Sugar()
	return nil
}

// InitProduction initializes logger for production environment
func InitProduction() error {
	var err error
	Log, err = zap.NewProduction()
	if err != nil {
		return err
	}
	Sugar = Log.Sugar()
	return nil
}

// Sync flushes any buffered log entries
func Sync() error {
	if Log != nil {
		return Log.Sync()
	}
	return nil
}

// WithFields creates a new logger with additional fields
func WithFields(fields ...zap.Field) *zap.Logger {
	return Log.With(fields...)
}

// Debug logs a debug message
func Debug(msg string, fields ...zap.Field) {
	Log.Debug(msg, fields...)
}

// Info logs an info message
func Info(msg string, fields ...zap.Field) {
	Log.Info(msg, fields...)
}

// Warn logs a warning message
func Warn(msg string, fields ...zap.Field) {
	Log.Warn(msg, fields...)
}

// Error logs an error message
func Error(msg string, fields ...zap.Field) {
	Log.Error(msg, fields...)
}

// Fatal logs a fatal message and exits
func Fatal(msg string, fields ...zap.Field) {
	Log.Fatal(msg, fields...)
}

// Panic logs a panic message and panics
func Panic(msg string, fields ...zap.Field) {
	Log.Panic(msg, fields...)
}

// Field creates a zap field
func Field(key string, value interface{}) zap.Field {
	return zap.Any(key, value)
}

// String creates a string field
func String(key, value string) zap.Field {
	return zap.String(key, value)
}

// Int creates an int field
func Int(key string, value int) zap.Field {
	return zap.Int(key, value)
}

// Err creates an error field
func Err(err error) zap.Field {
	return zap.Error(err)
}

// Removed init() function to prevent it from overriding logger config.
// The logger will be initialized when Init() is explicitly called with config.
// func init() {
// 	// Initialize with development logger by default
// 	// This will be overridden when Init() is called with proper config
// 	if os.Getenv("ENV") == "production" {
// 		_ = InitProduction()
// 	} else {
// 		_ = InitDevelopment()
// 	}
// }
