package scheduler

import (
	"testing"
	"time"

	"git.az-it.net/az/morz-infoboard/server/backend/internal/store"
)

func ptrTime(t time.Time) *time.Time { return &t }

func TestResolveDesiredState(t *testing.T) {
	// Donnerstag 10:00 UTC
	thu := time.Date(2026, 3, 26, 10, 0, 0, 0, time.UTC)
	// Samstag 10:00 UTC
	sat := time.Date(2026, 3, 28, 10, 0, 0, 0, time.UTC)

	tests := []struct {
		name        string
		sc          store.ScreenSchedule
		override    *store.GlobalOverride
		now         time.Time
		wantDesired string
		wantControl bool
	}{
		{
			name:        "per-screen override aktiv → on",
			sc:          store.ScreenSchedule{OverrideOnUntil: ptrTime(thu.Add(time.Hour))},
			now:         thu,
			wantDesired: "on", wantControl: true,
		},
		{
			name: "per-screen override abgelaufen → fällt durch zu Zeitplan",
			sc: store.ScreenSchedule{
				ScheduleEnabled: true,
				PowerOnTime:     "09:00", PowerOffTime: "17:00",
				OverrideOnUntil: ptrTime(thu.Add(-time.Hour)), // abgelaufen
			},
			now:         thu,
			wantDesired: "on", wantControl: true, // Zeitplan: 09:00–17:00, jetzt 10:00
		},
		{
			name: "per-screen override schlägt globalen Override off",
			sc:   store.ScreenSchedule{OverrideOnUntil: ptrTime(thu.Add(time.Hour))},
			override: &store.GlobalOverride{
				Type:  "off",
				Until: thu.Add(time.Hour),
			},
			now:         thu,
			wantDesired: "on", wantControl: true,
		},
		{
			name: "globaler Override off aktiv → off",
			sc:   store.ScreenSchedule{ScheduleEnabled: true, PowerOnTime: "09:00", PowerOffTime: "17:00"},
			override: &store.GlobalOverride{
				Type:  "off",
				Until: thu.Add(time.Hour),
			},
			now:         thu,
			wantDesired: "off", wantControl: true,
		},
		{
			name: "globaler Override on aktiv → on",
			sc:   store.ScreenSchedule{},
			override: &store.GlobalOverride{
				Type:  "on",
				Until: thu.Add(time.Hour),
			},
			now:         thu,
			wantDesired: "on", wantControl: true,
		},
		{
			name: "globaler Override abgelaufen → fällt durch",
			sc:   store.ScreenSchedule{ScheduleEnabled: true, PowerOnTime: "09:00", PowerOffTime: "17:00"},
			override: &store.GlobalOverride{
				Type:  "off",
				Until: thu.Add(-time.Hour), // abgelaufen
			},
			now:         thu,
			wantDesired: "on", wantControl: true,
		},
		{
			name:        "Wochenende → off",
			sc:          store.ScreenSchedule{ScheduleEnabled: true, PowerOnTime: "09:00", PowerOffTime: "17:00"},
			now:         sat,
			wantDesired: "off", wantControl: true,
		},
		{
			name:        "Wochenende + per-screen override → on",
			sc:          store.ScreenSchedule{OverrideOnUntil: ptrTime(sat.Add(time.Hour))},
			now:         sat,
			wantDesired: "on", wantControl: true,
		},
		{
			name:        "normaler Zeitplan: innerhalb → on",
			sc:          store.ScreenSchedule{ScheduleEnabled: true, PowerOnTime: "09:00", PowerOffTime: "17:00"},
			now:         thu, // 10:00
			wantDesired: "on", wantControl: true,
		},
		{
			name:        "normaler Zeitplan: außerhalb → off",
			sc:          store.ScreenSchedule{ScheduleEnabled: true, PowerOnTime: "09:00", PowerOffTime: "17:00"},
			now:         time.Date(2026, 3, 26, 8, 0, 0, 0, time.UTC), // 08:00
			wantDesired: "off", wantControl: true,
		},
		{
			name:        "kein Zeitplan, kein Override → keine Steuerung",
			sc:          store.ScreenSchedule{},
			now:         thu,
			wantDesired: "", wantControl: false,
		},
		{
			name:        "Zeitplan deaktiviert → keine Steuerung",
			sc:          store.ScreenSchedule{ScheduleEnabled: false, PowerOnTime: "09:00", PowerOffTime: "17:00"},
			now:         thu,
			wantDesired: "", wantControl: false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			gotDesired, gotControl := resolveDesiredState(tt.sc, tt.override, tt.now)
			if gotDesired != tt.wantDesired || gotControl != tt.wantControl {
				t.Errorf("resolveDesiredState() = (%q, %v), want (%q, %v)",
					gotDesired, gotControl, tt.wantDesired, tt.wantControl)
			}
		})
	}
}
