package notification

import (
	// External
	werr "git.gibonuddevalla.se/go/wrappederror"

	// Standard
	"log/slog"
	"slices"
)

type Service interface {
	SetLogger(*slog.Logger)
	GetPrio() int
	GetType() string
	Send(int, []byte) error
}

type Manager struct {
	services []Service
	logger   *slog.Logger
}

func NewManager(logger *slog.Logger) (nm Manager) {
	nm.services = []Service{}
	nm.logger = logger
	return
}

func (nm *Manager) AddService(service Service) {
	nm.services = append(nm.services, service)
	slices.SortFunc(nm.services, func(a, b Service) int {
		if a.GetPrio() < b.GetPrio() {
			return -1
		}
		if a.GetPrio() > b.GetPrio() {
			return 1
		}
		return 0
	})
}

func (nm *Manager) Send(problemID int, msg []byte, fn func(*Service, error)) (err error) {
	for i, service := range nm.services {
		nm.logger.Info("notification", "service", service.GetType(), "prio", service.GetPrio())
		if err = service.Send(problemID, msg); err == nil {
			fn(&nm.services[i], nil)
			break
		} else {
			data := struct {
				ProblemID int
				Msg  []byte
			}{
				problemID,
				msg,
			}
			werr.Wrap(err).WithData(data).Log()
			fn(&nm.services[i], err)
		}
	}

	return
}
