package utils

import (
	"context"
	"log/slog"
	"net/http"
	"os"
	"strings"
)

type traceIDContextKey string

const traceIDKey traceIDContextKey = "trace_id"

func InitSlog() {
	level := new(slog.LevelVar)
	switch strings.ToLower(strings.TrimSpace(os.Getenv("SLOG_LEVEL"))) {
	case "debug":
		level.Set(slog.LevelDebug)
	case "warn":
		level.Set(slog.LevelWarn)
	case "error":
		level.Set(slog.LevelError)
	default:
		level.Set(slog.LevelInfo)
	}

	handler := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
		Level:     level,
		AddSource: false,
	})

	slog.SetDefault(slog.New(handler).With("app", "bssapp-backend"))
}

func TraceIDFromRequest(r *http.Request) string {
	if r == nil {
		return ""
	}

	candidates := []string{
		strings.TrimSpace(r.Header.Get("X-Trace-ID")),
		strings.TrimSpace(r.URL.Query().Get("trace_id")),
		strings.TrimSpace(r.Header.Get("X-Request-ID")),
	}

	for _, candidate := range candidates {
		if candidate != "" {
			return candidate
		}
	}

	return ""
}

func ContextWithTraceID(ctx context.Context, traceID string) context.Context {
	traceID = strings.TrimSpace(traceID)
	if ctx == nil || traceID == "" {
		return ctx
	}
	return context.WithValue(ctx, traceIDKey, traceID)
}

func TraceIDFromContext(ctx context.Context) string {
	if ctx == nil {
		return ""
	}
	value, _ := ctx.Value(traceIDKey).(string)
	return strings.TrimSpace(value)
}

func SlogFromContext(ctx context.Context) *slog.Logger {
	traceID := TraceIDFromContext(ctx)
	if traceID == "" {
		return slog.Default()
	}
	return slog.Default().With("trace_id", traceID)
}
