package infra

import "sort"

// LoggerWith retorna una copia del Logger con campos adicionales.
// No muta el logger original — los campos se apilan sobre los ya existentes.
// Funcion pura: misma entrada produce siempre la misma salida sin I/O.
func LoggerWith(logger *Logger, fields map[string]any) *Logger {
	if logger == nil {
		return nil
	}

	// Combinar fields existentes + nuevos (los nuevos tienen precedencia)
	combined := make(map[string]any, len(logger.Fields)+len(fields))
	for k, v := range logger.Fields {
		combined[k] = v
	}
	for k, v := range fields {
		combined[k] = v
	}

	// Convertir a args key-value ordenados para slog.With (orden determinista)
	keys := make([]string, 0, len(fields))
	for k := range fields {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	args := make([]any, 0, len(keys)*2)
	for _, k := range keys {
		args = append(args, k, fields[k])
	}

	var inner = logger.inner
	if inner != nil && len(args) > 0 {
		inner = inner.With(args...)
	}

	return &Logger{
		Level:  logger.Level,
		Output: logger.Output,
		Format: logger.Format,
		Fields: combined,
		inner:  inner,
	}
}
