package jobs

import (
	"log/slog"
	"sync"
	"time"

	"warpbox.dev/backend/libs/config"
	"warpbox.dev/backend/libs/services"
)

type job struct {
	name     string
	enabled  bool
	interval time.Duration
	run      func()
}

func StartAll(cfg config.Config, logger *slog.Logger, uploadService *services.UploadService, banService *services.BanService) func() {
	if !cfg.JobsEnabled {
		logger.Info("background jobs disabled", "source", "jobs", "severity", "dev")
		return func() {}
	}

	stops := []func(){
		start(newCleanupJob(cfg, logger, uploadService, banService), logger),
		start(newThumbnailsJob(cfg, logger, uploadService), logger),
	}

	var once sync.Once
	return func() {
		once.Do(func() {
			for _, stop := range stops {
				stop()
			}
		})
	}
}

func start(j job, logger *slog.Logger) func() {
	if !j.enabled {
		logger.Info("background job disabled", "source", "jobs", "severity", "dev", "job", j.name)
		return func() {}
	}
	if j.interval <= 0 {
		logger.Info("background job disabled by interval", "source", "jobs", "severity", "dev", "job", j.name, "interval", j.interval.String())
		return func() {}
	}

	stop := make(chan struct{})
	done := make(chan struct{})
	go func() {
		defer close(done)
		j.run()

		ticker := time.NewTicker(j.interval)
		defer ticker.Stop()
		for {
			select {
			case <-ticker.C:
				j.run()
			case <-stop:
				return
			}
		}
	}()

	var once sync.Once
	return func() {
		once.Do(func() {
			close(stop)
			<-done
		})
	}
}
