package jobqueue

import (
	"sync"
)

type EventName string

const (
	JobAdded    EventName = "JobAdded"
	JobRemoved  EventName = "JobRemoved"
	ExecuteJob  EventName = "ExecuteJob"
	JobReady    EventName = "JobReady"
	QueueJob    EventName = "QueueJob"
	JobFinished EventName = "JobFinished"
	// add more events as needed
)

type Event struct {
	Name EventName
	Data any
}

// EventBus is a simple event bus
type EventBus struct {
	subscribers map[EventName][]chan interface{}
	mu          sync.RWMutex
}

// NewEventBus creates a new event bus
func NewEventBus() *EventBus {
	return &EventBus{
		subscribers: make(map[EventName][]chan interface{}),
	}
}

// Subscribe adds a channel to the subscribers list
func (eb *EventBus) Subscribe(name EventName, ch chan interface{}) {
	eb.mu.Lock()
	defer eb.mu.Unlock()
	if _, found := eb.subscribers[name]; !found {
		eb.subscribers[name] = []chan interface{}{}
	}
	eb.subscribers[name] = append(eb.subscribers[name], ch)
}

// Unsubscribe removes a channel from the subscribers list
func (eb *EventBus) Unsubscribe(name EventName, ch chan interface{}) {
	eb.mu.Lock()
	defer eb.mu.Unlock()
	if channels, found := eb.subscribers[name]; found {
		for i := range channels {
			if channels[i] == ch {
				eb.subscribers[name] = append(channels[:i], channels[i+1:]...)
				break
			}
		}
	}
}

// Publish publishes an event to all subscribers
func (eb *EventBus) Publish(name EventName, data interface{}) {
	eb.mu.RLock()
	defer eb.mu.RUnlock()
	if channels, found := eb.subscribers[name]; found {
		for _, ch := range channels {
			ch <- Event{Name: name, Data: data}
		}
	}
}