package stepper

import (
	"time"
)

func GenerateTimes(start, end time.Time) []time.Time {
	startRounded := start.Truncate(time.Minute)
	endRounded := end.Truncate(time.Minute)
	if startRounded.After(endRounded) {
		return []time.Time{}
	}
	type intervalConfig struct {
		startOffset time.Duration
		endOffset   time.Duration
		step        time.Duration
		includeEnd  bool
	}
	intervals := []intervalConfig{
		{startOffset: -7 * 24 * time.Hour, endOffset: -24 * time.Hour, step: 60 * time.Minute, includeEnd: false}, // 24h-7d
		{startOffset: -24 * time.Hour, endOffset: -12 * time.Hour, step: 30 * time.Minute, includeEnd: false},     // 12h-24h
		{startOffset: -12 * time.Hour, endOffset: -6 * time.Hour, step: 10 * time.Minute, includeEnd: false},      // 6h-12h
		{startOffset: -6 * time.Hour, endOffset: -1 * time.Hour, step: 5 * time.Minute, includeEnd: false},        // 1h-6h
		{startOffset: -1 * time.Hour, endOffset: 0, step: 1 * time.Minute, includeEnd: true},                      // 0h-1h
	}
	var timestamps []time.Time
	for _, config := range intervals {
		intervalStart := endRounded.Add(config.startOffset)
		intervalEnd := endRounded.Add(config.endOffset)
		effectiveStart := maxTime(startRounded, intervalStart)
		effectiveEnd := minTime(endRounded, intervalEnd)
		if config.includeEnd {
			if effectiveStart.After(effectiveEnd) {
				continue
			}
		} else {
			if effectiveStart.After(effectiveEnd) || effectiveStart.Equal(effectiveEnd) {
				continue
			}
		}
		truncated := effectiveStart.Truncate(config.step)
		if truncated.Before(effectiveStart) {
			truncated = truncated.Add(config.step)
		}
		current := truncated
		for {
			if config.includeEnd {
				if current.After(effectiveEnd) {
					break
				}
			} else {
				if !current.Before(effectiveEnd) {
					break
				}
			}
			if current.Before(intervalStart) {
				break
			}
			if !config.includeEnd && !current.Before(intervalEnd) {
				break
			}
			timestamps = append(timestamps, current)
			current = current.Add(config.step)
		}
	}
	return timestamps
}

func maxTime(a, b time.Time) time.Time {
	if a.After(b) {
		return a
	}
	return b
}

func minTime(a, b time.Time) time.Time {
	if a.Before(b) {
		return a
	}
	return b
}
