package job

import (
	"context"
	"log"
	"time"

	jobdom "haixun-backend/internal/model/job/domain/usecase"
	threadsaccountdomain "haixun-backend/internal/model/threads_account/domain/usecase"
)

const refreshThreadsTokenTemplateType = "refresh-threads-token"

type ThreadsTokenSweeper struct {
	accounts threadsaccountdomain.UseCase
	jobs     jobdom.UseCase
	leadTime time.Duration
}

func NewThreadsTokenSweeper(
	accounts threadsaccountdomain.UseCase,
	jobs jobdom.UseCase,
	leadTime time.Duration,
) *ThreadsTokenSweeper {
	if leadTime <= 0 {
		leadTime = 7 * 24 * time.Hour
	}
	return &ThreadsTokenSweeper{
		accounts: accounts,
		jobs:     jobs,
		leadTime: leadTime,
	}
}

func (s *ThreadsTokenSweeper) Start(ctx context.Context, interval time.Duration) {
	if s == nil || s.accounts == nil || s.jobs == nil {
		return
	}
	if interval <= 0 {
		interval = time.Hour
	}
	log.Printf("threads token sweeper started: interval=%s lead_time=%s", interval, s.leadTime)
	ticker := time.NewTicker(interval)
	defer ticker.Stop()

	for {
		select {
		case <-ctx.Done():
			log.Printf("threads token sweeper stopped")
			return
		case <-ticker.C:
			created, err := s.tick(ctx)
			if err != nil {
				log.Printf("threads token sweeper tick error: %v", err)
				continue
			}
			if created > 0 {
				log.Printf("threads token sweeper enqueued %d refresh job(s)", created)
			}
		}
	}
}

func (s *ThreadsTokenSweeper) tick(ctx context.Context) (int, error) {
	candidates, err := s.accounts.ListTokenRefreshCandidates(ctx, s.leadTime)
	if err != nil {
		return 0, err
	}
	created := 0
	for _, item := range candidates {
		if item.AccountID == "" || item.TenantID == "" || item.OwnerUID == "" {
			continue
		}
		_, err := s.jobs.CreateRun(ctx, jobdom.CreateRunRequest{
			TemplateType: refreshThreadsTokenTemplateType,
			Scope:        "threads_account",
			ScopeID:      item.AccountID,
			TenantID:     item.TenantID,
			OwnerUID:     item.OwnerUID,
			Payload: map[string]any{
				"tenant_id":  item.TenantID,
				"owner_uid":  item.OwnerUID,
				"account_id": item.AccountID,
				"expires_at": item.ExpiresAt,
			},
		})
		if err != nil {
			log.Printf("threads token sweeper skip account=%s: %v", item.AccountID, err)
			continue
		}
		created++
	}
	return created, nil
}
