package alerter

import (
	"sync"

	"gitea.computernetthings.ru/yash/crypto_alert_bot/internal/entities"
)

type alertsCache struct {
	mu           sync.RWMutex
	byID         map[entities.AlertID]*entities.Alert
	byInstrument map[entities.InstrumentID]map[entities.AlertID]*entities.Alert
}

func newCache() *alertsCache {
	return &alertsCache{
		byID:         make(map[entities.AlertID]*entities.Alert),
		byInstrument: make(map[entities.InstrumentID]map[entities.AlertID]*entities.Alert),
	}
}

func (c *alertsCache) Add(a *entities.Alert) {
	c.mu.Lock()
	defer c.mu.Unlock()

	c.byID[a.ID] = a

	if _, ok := c.byInstrument[a.Instrument.ID]; !ok {
		c.byInstrument[a.Instrument.ID] = make(map[entities.AlertID]*entities.Alert)
	}
	c.byInstrument[a.Instrument.ID][a.ID] = a
}

func (c *alertsCache) Remove(id entities.AlertID) {
	c.mu.Lock()
	defer c.mu.Unlock()

	a, ok := c.byID[id]
	if !ok {
		return
	}

	delete(c.byID, id)
	delete(c.byInstrument[a.Instrument.ID], id)
}

func (c *alertsCache) AlertsByInstrument(id entities.InstrumentID) []*entities.Alert {
	c.mu.RLock()
	defer c.mu.RUnlock()

	alerts := c.byInstrument[id]
	result := make([]*entities.Alert, 0, len(alerts))
	for _, a := range alerts {
		result = append(result, a)
	}
	return result
}

func (c *alertsCache) Instruments() []entities.Instrument {
	c.mu.RLock()
	defer c.mu.RUnlock()

	instruments := make([]entities.Instrument, 0, len(c.byInstrument))
	for _, alerts := range c.byInstrument {
		for _, a := range alerts {
			instruments = append(instruments, a.Instrument)
			break
		}
	}
	return instruments
}
