package logging

import (
	"os"

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

var logger *zap.Logger

// InitLogger initializes the global logger
func InitLogger() error {
	var config zap.Config

	// Use pretty config in development, JSON in production
	if os.Getenv("ENVIRONMENT") == "production" {
		config = zap.NewProductionConfig()
	} else {
		config = zap.NewDevelopmentConfig()
		config.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
	}

	var err error
	logger, err = config.Build()
	if err != nil {
		return err
	}

	return nil
}

// GetLogger returns the global logger
func GetLogger() *zap.Logger {
	if logger == nil {
		logger, _ = zap.NewProduction()
	}
	return logger
}

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

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

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

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

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

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

// With returns a child logger with additional fields
func With(fields ...zap.Field) *zap.Logger {
	return GetLogger().With(fields...)
}

// String is a helper for creating a string field
func String(key, value string) zap.Field {
	return zap.String(key, value)
}

// Int is a helper for creating an int field
func Int(key string, value int) zap.Field {
	return zap.Int(key, value)
}

// Int64 is a helper for creating an int64 field
func Int64(key string, value int64) zap.Field {
	return zap.Int64(key, value)
}

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