package workers

import (
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
)

func TestShouldRunEstimatedWorker(t *testing.T) {
	tests := []struct {
		name      string
		now       time.Time
		wantRun   bool
		wantYear  int
		wantMonth time.Month
	}{
		// 1st of month — run for previous month
		{
			name:      "1st at 00:00",
			now:       time.Date(2026, 7, 1, 0, 0, 0, 0, time.UTC),
			wantRun:   true,
			wantYear:  2026,
			wantMonth: 6,
		},
		{
			name:      "1st at 12:00",
			now:       time.Date(2026, 7, 1, 12, 0, 0, 0, time.UTC),
			wantRun:   true,
			wantYear:  2026,
			wantMonth: 6,
		},
		{
			name:      "1st at 23:59",
			now:       time.Date(2026, 7, 1, 23, 59, 0, 0, time.UTC),
			wantRun:   true,
			wantYear:  2026,
			wantMonth: 6,
		},
		// 2nd of month — fallback for retries
		{
			name:      "2nd at 00:00",
			now:       time.Date(2026, 7, 2, 0, 0, 0, 0, time.UTC),
			wantRun:   true,
			wantYear:  2026,
			wantMonth: 6,
		},
		{
			name:      "2nd at 23:59",
			now:       time.Date(2026, 7, 2, 23, 59, 0, 0, time.UTC),
			wantRun:   true,
			wantYear:  2026,
			wantMonth: 6,
		},
		// 3rd of month — skip
		{
			name:    "3rd skip",
			now:     time.Date(2026, 7, 3, 0, 0, 0, 0, time.UTC),
			wantRun: false,
		},
		// Last day of month — skip
		{
			name:    "last day of month",
			now:     time.Date(2026, 6, 30, 0, 0, 0, 0, time.UTC),
			wantRun: false,
		},
		// Middle of month — skip
		{
			name:    "middle of month",
			now:     time.Date(2026, 6, 15, 12, 0, 0, 0, time.UTC),
			wantRun: false,
		},
		// Cross-year: Jan 1 → December estimate
		{
			name:      "jan 1 cross-year",
			now:       time.Date(2027, 1, 1, 0, 0, 0, 0, time.UTC),
			wantRun:   true,
			wantYear:  2026,
			wantMonth: 12,
		},
		// Cross-year fallback: Jan 2 → December estimate
		{
			name:      "jan 2 cross-year fallback",
			now:       time.Date(2027, 1, 2, 0, 0, 0, 0, time.UTC),
			wantRun:   true,
			wantYear:  2026,
			wantMonth: 12,
		},
		// Cross-year skip: Jan 3
		{
			name:    "jan 3 cross-year skip",
			now:     time.Date(2027, 1, 3, 0, 0, 0, 0, time.UTC),
			wantRun: false,
		},
		// Leap year: March 1 → February estimate
		{
			name:      "mar 1 after leap year",
			now:       time.Date(2028, 3, 1, 0, 0, 0, 0, time.UTC),
			wantRun:   true,
			wantYear:  2028,
			wantMonth: 2,
		},
		// Leap year fallback: March 2 → February estimate
		{
			name:      "mar 2 after leap year fallback",
			now:       time.Date(2028, 3, 2, 0, 0, 0, 0, time.UTC),
			wantRun:   true,
			wantYear:  2028,
			wantMonth: 2,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			ok, date := shouldRunEstimatedWorker(tt.now)
			assert.Equal(t, tt.wantRun, ok)
			if tt.wantRun {
				assert.Equal(t, tt.wantYear, date.Year())
				assert.Equal(t, tt.wantMonth, date.Month())
				assert.Equal(t, 1, date.Day())
			}
		})
	}
}
