package utils

import (
	"io"
	"log/slog"
	"os"
	"time"
)

// Logger provides structured logging capabilities
type Logger struct {
	*slog.Logger
}

// NewLogger creates a new structured logger
func NewLogger() *Logger {
	return NewLoggerWithOutput(os.Stdout)
}

// NewDebugLogger creates a new logger with debug level enabled
func NewDebugLogger() *Logger {
	opts := &slog.HandlerOptions{
		Level: slog.LevelDebug,
		ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr {
			// Customize timestamp format
			if a.Key == slog.TimeKey {
				return slog.Attr{
					Key:   a.Key,
					Value: slog.StringValue(time.Now().Format("2006-01-02 15:04:05")),
				}
			}
			return a
		},
	}

	handler := slog.NewTextHandler(os.Stdout, opts)
	logger := slog.New(handler)

	return &Logger{Logger: logger}
}

// NewLoggerWithOutput creates a new logger with custom output
func NewLoggerWithOutput(w io.Writer) *Logger {
	opts := &slog.HandlerOptions{
		Level: slog.LevelInfo,
		ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr {
			// Customize timestamp format
			if a.Key == slog.TimeKey {
				return slog.Attr{
					Key:   a.Key,
					Value: slog.StringValue(time.Now().Format("2006-01-02 15:04:05")),
				}
			}
			return a
		},
	}

	handler := slog.NewTextHandler(w, opts)
	logger := slog.New(handler)

	return &Logger{Logger: logger}
}

// NewSilentLogger creates a logger that discards all output
func NewSilentLogger() *Logger {
	return NewLoggerWithOutput(io.Discard)
}

// WithComponent adds a component context to the logger
func (l *Logger) WithComponent(component string) *Logger {
	return &Logger{Logger: l.Logger.With("component", component)}
}

// WithRequestID adds a request ID context to the logger
func (l *Logger) WithRequestID(requestID string) *Logger {
	return &Logger{Logger: l.Logger.With("request_id", requestID)}
}

// Fatal logs a fatal error and exits the program
func (l *Logger) Fatal(msg string, args ...interface{}) {
	l.Error(msg, args...)
	os.Exit(1)
}
