package logging

import (
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"go.uber.org/zap"
)

func TestNewLogger_Development(t *testing.T) {
	logger, err := NewLogger("development", "INFO")
	require.NoError(t, err)
	require.NotNil(t, logger)

	// Vérifier que le logger ne panique pas
	logger.Info("test message", zap.String("key", "value"))
	logger.Debug("debug message", zap.Int("count", 42))
	logger.Warn("warn message", zap.Bool("flag", true))
	logger.Error("error message", zap.Error(nil))

	// Sync peut échouer sur certains systèmes (stderr), c'est OK
	_ = logger.Sync()
}

func TestNewLogger_Production(t *testing.T) {
	logger, err := NewLogger("production", "INFO")
	require.NoError(t, err)
	require.NotNil(t, logger)

	// Vérifier que le logger ne panique pas
	logger.Info("test message", zap.String("key", "value"))
	logger.Error("error message", zap.String("error", "test error"))

	// Sync peut échouer sur certains systèmes (stderr), c'est OK
	_ = logger.Sync()
}

func TestLogger_Info(t *testing.T) {
	logger, err := NewLogger("test", "INFO")
	require.NoError(t, err)

	// Ne devrait pas paniquer
	logger.Info("test message", zap.String("key", "value"))
	logger.Info("another message", zap.Int("number", 123), zap.Bool("flag", true))
}

func TestLogger_Error(t *testing.T) {
	logger, err := NewLogger("test", "ERROR")
	require.NoError(t, err)

	// Ne devrait pas paniquer
	logger.Error("error message", zap.String("error", "test error"))
	logger.Error("another error", zap.Error(nil), zap.String("context", "test"))
}

func TestLogger_Debug(t *testing.T) {
	logger, err := NewLogger("test", "DEBUG")
	require.NoError(t, err)

	logger.Debug("debug message", zap.String("debug_key", "debug_value"))
}

func TestLogger_Warn(t *testing.T) {
	logger, err := NewLogger("test", "WARN")
	require.NoError(t, err)

	logger.Warn("warn message", zap.String("warn_key", "warn_value"))
}

func TestLogger_With(t *testing.T) {
	logger, err := NewLogger("test", "INFO")
	require.NoError(t, err)

	// Créer un logger avec des champs contextuels
	contextLogger := logger.With(
		zap.String("request_id", "req-123"),
		zap.String("user_id", "user-456"),
	)

	// Les logs avec ce logger incluront automatiquement les champs contextuels
	contextLogger.Info("request processed", zap.String("action", "login"))
	contextLogger.Error("request failed", zap.String("action", "login"), zap.Error(nil))
}

func TestLogger_With_Chaining(t *testing.T) {
	logger, err := NewLogger("test", "INFO")
	require.NoError(t, err)

	// Chaîner plusieurs With
	logger1 := logger.With(zap.String("service", "api"))
	logger2 := logger1.With(zap.String("handler", "auth"))
	logger3 := logger2.With(zap.String("method", "POST"))

	// Tous les champs devraient être inclus
	logger3.Info("chained logger test")
}

func TestLogger_Sync(t *testing.T) {
	logger, err := NewLogger("test", "INFO")
	require.NoError(t, err)

	// Sync peut échouer sur certains systèmes (stderr), c'est OK
	// On vérifie juste qu'il ne panique pas
	_ = logger.Sync()
}

func TestLogger_GetZapLogger(t *testing.T) {
	logger, err := NewLogger("test", "INFO")
	require.NoError(t, err)

	zapLogger := logger.GetZapLogger()
	assert.NotNil(t, zapLogger)
	// Vérifier que c'est bien le même logger
	assert.Equal(t, logger.GetZapLogger(), zapLogger)
}
