package logger

import (
	"fmt"
	"os"
	"strings"
)

// Log levels
const (
	LevelDebug = "DEBUG"
	LevelInfo  = "INFO"
	LevelWarn  = "WARN"
	LevelError = "ERROR"
)

// Logger is the interface for logging
var (
	// DefaultLogger is the default logger instance
	DefaultLogger = NewLogger(LevelInfo)
)

// Logger represents a simple logger
type Logger struct {
	level string
}

// NewLogger creates a new logger instance with the specified log level
func NewLogger(level string) *Logger {
	return &Logger{level: level}
}

// SetLevel changes the logger level at runtime
func (l *Logger) SetLevel(level string) {
	switch strings.ToUpper(strings.TrimSpace(level)) {
	case LevelDebug, LevelInfo, LevelWarn, LevelError:
		l.level = strings.ToUpper(strings.TrimSpace(level))
	default:
		// keep previous
	}
}

// SetLevel changes the default logger level at runtime
func SetLevel(level string) {
	if DefaultLogger != nil {
		DefaultLogger.SetLevel(level)
	}
}

// Debug logs a debug message
func (l *Logger) Debug(message string, args ...interface{}) {
	if l.shouldLog(LevelDebug) {
		l.log(LevelDebug, message, args...)
	}
}

// Info logs an info message
func (l *Logger) Info(message string, args ...interface{}) {
	if l.shouldLog(LevelInfo) {
		l.log(LevelInfo, message, args...)
	}
}

// Warn logs a warning message
func (l *Logger) Warn(message string, args ...interface{}) {
	if l.shouldLog(LevelWarn) {
		l.log(LevelWarn, message, args...)
	}
}

// Error logs an error message
func (l *Logger) Error(message string, args ...interface{}) {
	if l.shouldLog(LevelError) {
		l.log(LevelError, message, args...)
	}
}

// shouldLog checks if the log level is enabled
func (l *Logger) shouldLog(level string) bool {
	levels := map[string]int{
		LevelDebug: 0,
		LevelInfo:  1,
		LevelWarn:  2,
		LevelError: 3,
	}

	return levels[level] >= levels[l.level]
}

// log writes the log message to stderr
func (l *Logger) log(level, message string, args ...interface{}) {
	msg := message
	if len(args) > 0 {
		msg = fmt.Sprintf(message, args...)
	}
	fmt.Fprintf(os.Stderr, "[%s] %s\n", level, msg)
}

// Package level functions

// Debug logs a debug message using the default logger
func Debug(message string, args ...interface{}) {
	DefaultLogger.Debug(message, args...)
}

// Info logs an info message using the default logger
func Info(message string, args ...interface{}) {
	DefaultLogger.Info(message, args...)
}

// Warn logs a warning message using the default logger
func Warn(message string, args ...interface{}) {
	DefaultLogger.Warn(message, args...)
}

// Error logs an error message using the default logger
func Error(message string, args ...interface{}) {
	DefaultLogger.Error(message, args...)
}
