package logger

import (
	"context"
	"fmt"
	"log/slog"
	"slices"

	"quantex.com/qfixdpl/src/domain"
)

//nolint:gochecknoglobals // need to be global
var notify domain.Notifier

type QuantexHandler struct {
	slog.Handler
	levels []slog.Level
}

func SetNotifier(n domain.Notifier) {
	notify = n
}

// NewQuantexHandler creates a log handler that send logs using a notifier.
func NewQuantexHandler(handler slog.Handler, levels []slog.Level) *QuantexHandler {
	return &QuantexHandler{
		Handler: handler,
		levels:  levels,
	}
}

// Enabled reports whether the handler handles records at the given level.
func (s *QuantexHandler) Enabled(ctx context.Context, level slog.Level) bool {
	return s.Handler.Enabled(ctx, level)
}

// Handle intercepts and processes logger messages.
// In our case, send a message to the notifier.
//
//revive:disable:cognitive-complexity  we need this level of complexity
func (s *QuantexHandler) Handle(ctx context.Context, record slog.Record) error {
	const (
		shortErrKey = "err"
		longErrKey  = "error"
	)

	if notify != nil && slices.Contains(s.levels, record.Level) {
		switch record.Level {
		case slog.LevelError:
			msg := record.Message
			record.Attrs(func(attr slog.Attr) bool {
				if attr.Key == shortErrKey || attr.Key == longErrKey {
					if err, ok := attr.Value.Any().(error); ok {
						msg += err.Error()
					}
				}

				return true
			})

			notify.SendMsg(domain.MessageChannelError, msg, domain.MessageStatusStopper, nil)
		case slog.LevelWarn:
			notify.SendMsg(domain.MessageChannelError, record.Message, domain.MessageStatusWarning, nil)
		}
	}

	err := s.Handler.Handle(ctx, record)
	if err != nil {
		return fmt.Errorf("error from QuantexHandler: %w", err)
	}

	return nil
}

//revive:enable

// WithAttrs returns a new QuantexHandler whose attributes consists.
func (s *QuantexHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
	return NewQuantexHandler(s.Handler.WithAttrs(attrs), s.levels)
}

// WithGroup returns a new QuantexHandler whose group consists.
func (s *QuantexHandler) WithGroup(name string) slog.Handler {
	return NewQuantexHandler(s.Handler.WithGroup(name), s.levels)
}
