//go:build go1.21

package logger

import (
	
	
	
	
	

	
)

type slogLogger struct {
	Logger                    *slog.Logger
	LogLevel                  LogLevel
	SlowThreshold             time.Duration
	Parameterized             bool
	Colorful                  bool // Ignored in slog
	IgnoreRecordNotFoundError bool
}

func ( *slog.Logger,  Config) Interface {
	return &slogLogger{
		Logger:                    ,
		LogLevel:                  .LogLevel,
		SlowThreshold:             .SlowThreshold,
		Parameterized:             .ParameterizedQueries,
		IgnoreRecordNotFoundError: .IgnoreRecordNotFoundError,
	}
}

func ( *slogLogger) ( LogLevel) Interface {
	 := *
	.LogLevel = 
	return &
}

func ( *slogLogger) ( context.Context,  string,  ...interface{}) {
	if .LogLevel >= Info {
		.log(, slog.LevelInfo, , slog.Any("data", ))
	}
}

func ( *slogLogger) ( context.Context,  string,  ...interface{}) {
	if .LogLevel >= Warn {
		.log(, slog.LevelWarn, , slog.Any("data", ))
	}
}

func ( *slogLogger) ( context.Context,  string,  ...interface{}) {
	if .LogLevel >= Error {
		.log(, slog.LevelError, , slog.Any("data", ))
	}
}

func ( *slogLogger) ( context.Context,  time.Time,  func() ( string,  int64),  error) {
	if .LogLevel <= Silent {
		return
	}

	 := time.Since()
	,  := ()
	 := []slog.Attr{
		slog.String("duration", fmt.Sprintf("%.3fms", float64(.Nanoseconds())/1e6)),
		slog.String("sql", ),
	}

	if  != -1 {
		 = append(, slog.Int64("rows", ))
	}

	switch {
	case  != nil && (!.IgnoreRecordNotFoundError || !errors.Is(, ErrRecordNotFound)):
		 = append(, slog.String("error", .Error()))
		.log(, slog.LevelError, "SQL executed", slog.Attr{
			Key:   "trace",
			Value: slog.GroupValue(...),
		})

	case .SlowThreshold != 0 &&  > .SlowThreshold:
		.log(, slog.LevelWarn, "SQL executed", slog.Attr{
			Key:   "trace",
			Value: slog.GroupValue(...),
		})

	case .LogLevel >= Info:
		.log(, slog.LevelInfo, "SQL executed", slog.Attr{
			Key:   "trace",
			Value: slog.GroupValue(...),
		})
	}
}

func ( *slogLogger) ( context.Context,  slog.Level,  string,  ...any) {
	if  == nil {
		 = context.Background()
	}

	if !.Logger.Enabled(, ) {
		return
	}

	 := slog.NewRecord(time.Now(), , , utils.CallerFrame().PC)
	.Add(...)
	_ = .Logger.Handler().Handle(, )
}

// ParamsFilter filter params
func ( *slogLogger) ( context.Context,  string,  ...interface{}) (string, []interface{}) {
	if .Parameterized {
		return , nil
	}
	return , 
}