//go:build test && dev

package bookings

import (
	"testing"
	"time"
)

func TestCheckClosingHours_WithinHours(t *testing.T) {
	// Closing at 17:00, booking ends at 16:30 — should pass.
	london, err := time.LoadLocation("Europe/London")
	if err != nil {
		t.Fatalf("failed to load location: %v", err)
	}
	localEnd := time.Date(2026, 6, 24, 16, 30, 0, 0, london)
	if err := checkClosingHours(localEnd, "17:00"); err != nil {
		t.Errorf("expected no error for 16:30 end vs 17:00 close, got: %v", err)
	}
}

func TestCheckClosingHours_AtClosing(t *testing.T) {
	// Closing at 17:00, booking ends exactly at 17:00 — should pass.
	london, err := time.LoadLocation("Europe/London")
	if err != nil {
		t.Fatalf("failed to load location: %v", err)
	}
	localEnd := time.Date(2026, 6, 24, 17, 0, 0, 0, london)
	if err := checkClosingHours(localEnd, "17:00"); err != nil {
		t.Errorf("expected no error for 17:00 end vs 17:00 close, got: %v", err)
	}
}

func TestCheckClosingHours_PastClosing(t *testing.T) {
	// Closing at 17:00, booking ends at 17:01 — should return ErrPastClosing.
	london, err := time.LoadLocation("Europe/London")
	if err != nil {
		t.Fatalf("failed to load location: %v", err)
	}
	localEnd := time.Date(2026, 6, 24, 17, 1, 0, 0, london)
	if err := checkClosingHours(localEnd, "17:00"); !IsPastClosing(err) {
		t.Errorf("expected ErrPastClosing for 17:01 end vs 17:00 close, got: %v", err)
	}
}

func TestCheckClosingHours_WellPastClosing(t *testing.T) {
	// Closing at 17:00, booking ends at 18:00 — should return ErrPastClosing.
	london, err := time.LoadLocation("Europe/London")
	if err != nil {
		t.Fatalf("failed to load location: %v", err)
	}
	localEnd := time.Date(2026, 6, 24, 18, 0, 0, 0, london)
	if err := checkClosingHours(localEnd, "17:00"); !IsPastClosing(err) {
		t.Errorf("expected ErrPastClosing for 18:00 end vs 17:00 close, got: %v", err)
	}
}

func TestCheckClosingHours_InvalidFormat(t *testing.T) {
	// Malformed closing time string — should return a generic error, not ErrPastClosing.
	london, err := time.LoadLocation("Europe/London")
	if err != nil {
		t.Fatalf("failed to load location: %v", err)
	}
	localEnd := time.Date(2026, 6, 24, 14, 0, 0, 0, london)

	tests := []struct {
		name     string
		closeStr string
	}{
		{"empty string", ""},
		{"no colon", "1700"},
		{"non-numeric hour", "ab:00"},
		{"non-numeric minute", "17:ab"},
		{"only hour", "17"},
	}
	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			err := checkClosingHours(localEnd, tc.closeStr)
			if err == nil {
				t.Error("expected error for invalid format, got nil")
			}
			if IsPastClosing(err) {
				t.Errorf("expected non-past-closing error for invalid format %q, got ErrPastClosing", tc.closeStr)
			}
		})
	}
}

// IsPastClosing reports whether err indicates the booking extends beyond closing hours.
// Exported helper for tests.
func IsPastClosing(err error) bool {
	return err == ErrPastClosing
}
