// Package logging собирает slog-логгер по настройкам из конфига.
package logging

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

// New возвращает slog-логгер с указанным уровнем и форматом ("json"|"text").
func New(level, format string) *slog.Logger {
	opts := &slog.HandlerOptions{Level: parseLevel(level), ReplaceAttr: utcTime}

	var handler slog.Handler
	if strings.EqualFold(format, "text") {
		handler = slog.NewTextHandler(os.Stdout, opts)
	} else {
		handler = slog.NewJSONHandler(os.Stdout, opts)
	}
	return slog.New(handler)
}

// utcTime приводит метку времени к UTC. JSONHandler сериализует time.Time в
// RFC3339 с долями секунды; в UTC суффикс — Z. Бизнес-логика остаётся в
// Europe/Moscow, UTC — только в логах (явный TZ, инвариант проекта не нарушен).
func utcTime(groups []string, a slog.Attr) slog.Attr {
	if len(groups) == 0 && a.Key == slog.TimeKey {
		if t, ok := a.Value.Any().(time.Time); ok {
			a.Value = slog.TimeValue(t.UTC())
		}
	}
	return a
}

// NewStderr — JSON-логгер в stderr (UTC) для фатальных ошибок старта сервиса,
// когда основной логгер ещё не собран (конфиг не прочитан). Уровень не
// ограничиваем — пишем сам факт фатального сбоя.
func NewStderr() *slog.Logger {
	return slog.New(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{ReplaceAttr: utcTime}))
}

func parseLevel(level string) slog.Level {
	switch strings.ToLower(level) {
	case "debug":
		return slog.LevelDebug
	case "warn", "warning":
		return slog.LevelWarn
	case "error":
		return slog.LevelError
	default:
		return slog.LevelInfo
	}
}
