package logger

import (
	"fmt"
	"log"
	"os"
	"sync"
	"time"
)

// Logger struct holds the logger instance
type Logger struct {
	logger *log.Logger
	level  LogLevel
}

var (
	defaultLogger *Logger
	once          sync.Once
)

// NewLogger creates a new logger instance
func NewLogger() *Logger {
	return &Logger{
		logger: log.New(os.Stdout, "", 0),
		level:  DEBUG,
	}
}

// Init initializes the default logger
func Init() *Logger {
	once.Do(func() {
		defaultLogger = NewLogger()
	})
	return defaultLogger
}

// GetLogger returns the default logger instance
func GetLogger() *Logger {
	if defaultLogger == nil {
		Init()
	}
	return defaultLogger
}

// SetLevel sets the minimum logging level
func (l *Logger) SetLevel(level LogLevel) {
	l.level = level
}

// log handles the actual logging
func (l *Logger) log(level LogLevel, format string, args ...interface{}) {
	if level < l.level {
		return
	}

	// Get timezone from environment variable or use local timezone
	timezone := os.Getenv("LOGGER_TIMEZONE")
	var location *time.Location
	var err error

	if timezone != "" {
		location, err = time.LoadLocation(timezone)
		if err != nil {
			// If invalid timezone, fall back to local
			location = time.Local
		}
	} else {
		location = time.Local
	}

	timestamp := time.Now().In(location).Format("2006/01/02 15:04:05")
	message := fmt.Sprintf(format, args...)
	l.logger.Printf("%s: %s %s", level.String(), timestamp, message)
}

// Debug logs debug level messages
func (l *Logger) Debug(format string, args ...interface{}) {
	l.log(DEBUG, format, args...)
}

// Info logs info level messages
func (l *Logger) Info(format string, args ...interface{}) {
	l.log(INFO, format, args...)
}

// Warn logs warning level messages
func (l *Logger) Warn(format string, args ...interface{}) {
	l.log(WARN, format, args...)
}

// Error logs error level messages
func (l *Logger) Error(format string, args ...interface{}) {
	l.log(ERROR, format, args...)
}

// Fatal logs fatal level messages and exits
func (l *Logger) Fatal(format string, args ...interface{}) {
	l.log(FATAL, format, args...)
	os.Exit(1)
}

// Global helper functions
func Debug(format string, args ...interface{}) {
	GetLogger().Debug(format, args...)
}

func Info(format string, args ...interface{}) {
	GetLogger().Info(format, args...)
}

func Warn(format string, args ...interface{}) {
	GetLogger().Warn(format, args...)
}

func Error(format string, args ...interface{}) {
	GetLogger().Error(format, args...)
}

func Fatal(format string, args ...interface{}) {
	GetLogger().Fatal(format, args...)
}
