package jobs

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

	"gorm.io/gorm"

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

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

func NewSettlementWorker(db *gorm.DB, logger *slog.Logger, interval time.Duration, batchSize int) *SettlementWorker {
	if interval <= 0 {
		interval = time.Minute
	}
	if batchSize <= 0 {
		batchSize = 100
	}
	return &SettlementWorker{db: db, logger: logger, interval: interval, batchSize: batchSize}
}

func (w *SettlementWorker) Run(ctx context.Context) error {
	if w.db == nil {
		w.logger.Warn("settlement worker disabled: database is not configured")
		<-ctx.Done()
		return nil
	}

	w.logger.Info("settlement worker started", "interval", w.interval, "batch_size", w.batchSize)
	if err := w.ProcessOnce(ctx); err != nil {
		w.logger.Error("settlement worker initial scan failed", "error", err)
	}

	ticker := time.NewTicker(w.interval)
	defer ticker.Stop()
	for {
		select {
		case <-ctx.Done():
			w.logger.Info("settlement worker stopped")
			return nil
		case <-ticker.C:
			if err := w.ProcessOnce(ctx); err != nil {
				w.logger.Error("settlement worker scan failed", "error", err)
			}
		}
	}
}

func (w *SettlementWorker) ProcessOnce(ctx context.Context) error {
	if err := w.license.check(); err != nil {
		return err
	}
	summary, err := commerce.NewService(w.db, nil, w.logger).SettleDueRewards(ctx, w.batchSize)
	if err != nil {
		return err
	}
	if summary.Orders > 0 || summary.Settlements > 0 {
		w.logger.Info("settlement worker released rewards", "orders", summary.Orders, "settlements", summary.Settlements)
	}
	return nil
}
