package logging

import (
	"context"
	"os"
	"time"

	"github.com/rs/zerolog"
	"github.com/rs/zerolog/log"
)

// InitLogger initializes the global logger
func InitLogger() {
	zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
	// Default to console writer for dev, strict JSON for prod if needed
	log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339})
}

// Logger wraps zerolog context
type Logger struct {
	logger zerolog.Logger
}

// New creates a new logger with context.
// Falls back to the global logger when the context has no logger set,
// avoiding a disabled (nop) zerolog.Logger from log.Ctx.
func New(ctx context.Context) *Logger {
	ctxLogger := log.Ctx(ctx)
	if ctxLogger.GetLevel() == zerolog.Disabled {
		return &Logger{logger: log.Logger}
	}
	return &Logger{
		logger: ctxLogger.With().Logger(),
	}
}

// WithField adds a field. Nil-safe: returns nil unchanged so chained
// WithField().Info() calls on a nil logger don't panic.
func (l *Logger) WithField(key string, value interface{}) *Logger {
	if l == nil {
		return nil
	}
	return &Logger{
		logger: l.logger.With().Interface(key, value).Logger(),
	}
}

// Info logs info. Nil-safe: a nil Logger silently discards the message so
// partially-constructed services (e.g. unit tests that only wire a few
// dependencies) don't panic on a logging call.
func (l *Logger) Info(msg string) {
	if l == nil {
		return
	}
	l.logger.Info().Msg(msg)
}

// Error logs error. Nil-safe — see Info.
func (l *Logger) Error(msg string, err error) {
	if l == nil {
		return
	}
	l.logger.Error().Err(err).Msg(msg)
}

// Debug logs debug. Nil-safe — see Info.
func (l *Logger) Debug(msg string) {
	if l == nil {
		return
	}
	l.logger.Debug().Msg(msg)
}

// Warn logs warning. Nil-safe — see Info.
func (l *Logger) Warn(msg string) {
	if l == nil {
		return
	}
	l.logger.Warn().Msg(msg)
}

// Get global logger instance for simple usage
var Default = &Logger{
	logger: log.Logger,
}
