package alerts

import (
	"context"
	"encoding/json"
	"log/slog"
	"sync"
	"text/template"

	"git.sr.ht/~ashkeel/strimertul/database"
	"git.sr.ht/~ashkeel/strimertul/log"
	"git.sr.ht/~ashkeel/strimertul/twitch/eventsub"
	templater "git.sr.ht/~ashkeel/strimertul/twitch/template"
)

type (
	templateCache    map[string]*template.Template
	templateCacheMap map[templateType]templateCache
)

type templateType string

const (
	templateTypeSubscription templateType = "subscription"
	templateTypeFollow       templateType = "follow"
	templateTypeRaid         templateType = "raid"
	templateTypeCheer        templateType = "cheer"
	templateTypeGift         templateType = "gift"
)

type Module struct {
	Config Config

	ctx       context.Context
	db        database.Database
	logger    *slog.Logger
	templater templater.Engine
	templates templateCacheMap

	pendingMux  sync.Mutex
	pendingSubs map[string]subMixedEvent
}

func Setup(ctx context.Context, db database.Database, logger *slog.Logger, templater templater.Engine) *Module {
	mod := &Module{
		ctx:         ctx,
		db:          db,
		logger:      logger,
		templater:   templater,
		pendingMux:  sync.Mutex{},
		pendingSubs: make(map[string]subMixedEvent),
	}

	// Load config from database
	if err := db.GetJSON(ConfigKey, &mod.Config); err != nil {
		logger.Debug("Config load error", log.Error(err))
		mod.Config = Config{}
		// Save empty config
		err = db.PutJSON(ConfigKey, mod.Config)
		if err != nil {
			logger.Warn("Could not save default config for bot alerts", log.Error(err))
		}
	}

	mod.compileTemplates()

	if err := db.SubscribeKeyContext(ctx, ConfigKey, func(value string) {
		err := json.Unmarshal([]byte(value), &mod.Config)
		if err != nil {
			logger.Warn("Error loading alert config", log.Error(err))
		} else {
			logger.Info("Reloaded alert config")
		}
		mod.compileTemplates()
	}); err != nil {
		logger.Error("Could not set-up bot alert reload subscription", log.Error(err))
	}

	if err := db.SubscribePrefixContext(ctx, mod.onEventSubEvent, eventsub.EventKeyPrefix); err != nil {
		logger.Error("Could not setup twitch alert subscription", log.Error(err))
	}

	logger.Debug("Loaded bot alerts")

	return mod
}
