package jobs

import (
	"context"
	"log/slog"
	"time"

	"gorm.io/gorm"

	"qycw/go-server/internal/domain/commerce"
)

type UpstreamActionWorker struct {
	db        *gorm.DB
	logger    *slog.Logger
	interval  time.Duration
	batchSize int
	license   workerLicenseGate
}

func NewUpstreamActionWorker(db *gorm.DB, logger *slog.Logger, interval time.Duration, batchSize int) *UpstreamActionWorker {
	if interval <= 0 {
		interval = 45 * time.Second
	}
	if batchSize <= 0 {
		batchSize = 100
	}
	return &UpstreamActionWorker{db: db, logger: logger, interval: interval, batchSize: batchSize}
}

func (w *UpstreamActionWorker) Run(ctx context.Context) error {
	ticker := time.NewTicker(w.interval)
	defer ticker.Stop()
	if err := w.ProcessOnce(ctx); err != nil && w.logger != nil {
		w.logger.Warn("upstream action worker initial scan failed", "error", err)
	}
	for {
		select {
		case <-ctx.Done():
			return nil
		case <-ticker.C:
			if err := w.ProcessOnce(ctx); err != nil {
				if w.logger != nil {
					w.logger.Warn("upstream action worker scan failed", "error", err)
				}
			}
		}
	}
}

func (w *UpstreamActionWorker) ProcessOnce(ctx context.Context) error {
	if err := w.license.check(); err != nil {
		return err
	}
	if w.db == nil {
		return nil
	}
	service := commerce.NewService(w.db, nil, w.logger)
	summary, err := service.SyncPendingUpstreamActions(ctx, w.batchSize)
	if err != nil {
		return err
	}
	if w.logger != nil && summary["checked"] > 0 {
		w.logger.Info("upstream action worker synced actions",
			"checked", summary["checked"],
			"success", summary["success"],
			"failed", summary["failed"],
			"running", summary["running"],
			"no_task", summary["no_task"],
			"errored", summary["errored"],
		)
	}
	return nil
}
