package miner

import (
	"sync"
	"time"

	"crypto-miner-agent/config"
	"crypto-miner-agent/stats"
)

type ScheduleGuard struct {
	cfg      config.RuntimeConfig
	reporter *stats.Reporter

	mu        sync.Mutex
	idleSince time.Time
	idleReady bool
}

func NewScheduleGuard(cfg config.RuntimeConfig, reporter *stats.Reporter) *ScheduleGuard {
	return &ScheduleGuard{
		cfg:      cfg,
		reporter: reporter,
	}
}

func (g *ScheduleGuard) Allowed() bool {
	return g.allowedAt(time.Now())
}

func (g *ScheduleGuard) allowedAt(now time.Time) bool {
	switch g.cfg.MiningModeNormalized() {
	case "idle":
		return g.idleAllowed()
	case "scheduled", "schedule":
		return g.cfg.InScheduleWindow(now)
	default:
		return true
	}
}

func (g *ScheduleGuard) idleAllowed() bool {
	cpu := g.reporter.SystemCPUPercent()
	threshold := float64(g.cfg.IdleThresholdPct)
	if threshold <= 0 {
		threshold = 20
	}
	duration := time.Duration(g.cfg.IdleDurationMinutes) * time.Minute
	if duration <= 0 {
		duration = 5 * time.Minute
	}

	g.mu.Lock()
	defer g.mu.Unlock()

	if cpu == 0 {
		// First sample has no delta yet; treat as not idle.
		g.idleSince = time.Time{}
		g.idleReady = false
		return false
	}

	if cpu <= threshold {
		if g.idleSince.IsZero() {
			g.idleSince = time.Now()
		}
		if time.Since(g.idleSince) >= duration {
			g.idleReady = true
		}
	} else {
		g.idleSince = time.Time{}
		g.idleReady = false
	}
	return g.idleReady
}
