package logger

import (
	"context"
	"sync"
)

var (
	globalLogger Logger
	globalMu     sync.RWMutex
)

// SetGlobalLogger sets the global logger instance.
func SetGlobalLogger(l Logger) {
	globalMu.Lock()
	defer globalMu.Unlock()
	globalLogger = l
}

// GetGlobalLogger returns the global logger instance.
// Returns a no-op logger if no global logger is set.
func GetGlobalLogger() Logger {
	globalMu.RLock()
	defer globalMu.RUnlock()
	if globalLogger == nil {
		return &noOpLogger{}
	}
	return globalLogger
}

// Debug logs a message at debug level using the global logger.
func Debug(msg string, fields ...Field) {
	GetGlobalLogger().Debug(msg, fields...)
}

// Info logs a message at info level using the global logger.
func Info(msg string, fields ...Field) {
	GetGlobalLogger().Info(msg, fields...)
}

// Warn logs a message at warning level using the global logger.
func Warn(msg string, fields ...Field) {
	GetGlobalLogger().Warn(msg, fields...)
}

// ErrorLog logs a message at error level using the global logger.
func ErrorLog(msg string, fields ...Field) {
	GetGlobalLogger().Error(msg, fields...)
}

// noOpLogger is a logger that does nothing.
// Used as a fallback when no global logger is set.
type noOpLogger struct{}

// Debug implements Logger.Debug as a no-op.
func (n *noOpLogger) Debug(_ string, _ ...Field) {}

// Info implements Logger.Info as a no-op.
func (n *noOpLogger) Info(_ string, _ ...Field) {}

// Warn implements Logger.Warn as a no-op.
func (n *noOpLogger) Warn(_ string, _ ...Field) {}

// Error implements Logger.Error as a no-op.
func (n *noOpLogger) Error(_ string, _ ...Field) {}

// With implements Logger.With as a no-op.
func (n *noOpLogger) With(_ ...Field) Logger { return n }

// WithContext implements Logger.WithContext as a no-op.
func (n *noOpLogger) WithContext(_ context.Context) Logger { return n }
