package handlers

import (
	"net/http"
	"net/http/httptest"
	"testing"
)

// Ensures the /projects/{id}/sub-projects alias from F-48 lands on the
// canonical /projects/{id}/children URL. The redirect is wired on the OUTER
// mux so it fires before auth middleware.
func TestRegisterLegacyRedirects_SubProjectsAlias(t *testing.T) {
	mux := http.NewServeMux()
	registerLegacyRedirects(mux)

	cases := []struct {
		path string
		want string
	}{
		{"/projects/abc-123/sub-projects", "/projects/abc-123/children"},
		{"/projects/abc-123/sub-projects?foo=bar", "/projects/abc-123/children?foo=bar"},
	}
	for _, tc := range cases {
		req := httptest.NewRequest(http.MethodGet, tc.path, nil)
		w := httptest.NewRecorder()
		mux.ServeHTTP(w, req)
		if w.Code != http.StatusMovedPermanently {
			t.Fatalf("%s: status = %d, want %d", tc.path, w.Code, http.StatusMovedPermanently)
		}
		if got := w.Header().Get("Location"); got != tc.want {
			t.Fatalf("%s: Location = %q, want %q", tc.path, got, tc.want)
		}
	}
}

// t-paliad-224: /deadlines/calendar and /appointments/calendar 301 to
// the canonical /events Kalender tab. Pins the redirect target so a
// future refactor doesn't silently break the bookmark contract.
func TestStandaloneCalendarHandlers_RedirectToEventsKalender(t *testing.T) {
	cases := []struct {
		name    string
		handler http.HandlerFunc
		want    string
	}{
		{"deadlines", handleDeadlinesCalendarPage, "/events?type=deadline&view=calendar"},
		{"appointments", handleAppointmentsCalendarPage, "/events?type=appointment&view=calendar"},
	}
	for _, tc := range cases {
		req := httptest.NewRequest(http.MethodGet, "/x", nil) // path ignored — handler is direct
		w := httptest.NewRecorder()
		tc.handler(w, req)
		if w.Code != http.StatusMovedPermanently {
			t.Fatalf("%s: status = %d, want %d", tc.name, w.Code, http.StatusMovedPermanently)
		}
		if got := w.Header().Get("Location"); got != tc.want {
			t.Fatalf("%s: Location = %q, want %q", tc.name, got, tc.want)
		}
	}
}

// /deadlines list redirect must forward the incoming query string so legacy
// dashboard cards and external bookmarks like /deadlines?status=this_week
// land at /events?type=deadline&status=this_week instead of losing the
// filter. Regression for m's 2026-05-21 14:20 report.
func TestDeadlinesListRedirect_PreservesQueryString(t *testing.T) {
	cases := []struct {
		path string
		want string
	}{
		{"/deadlines", "/events?type=deadline"},
		{"/deadlines?status=this_week", "/events?type=deadline&status=this_week"},
		{"/deadlines?status=overdue&project_id=abc", "/events?type=deadline&status=overdue&project_id=abc"},
	}
	for _, tc := range cases {
		req := httptest.NewRequest(http.MethodGet, tc.path, nil)
		w := httptest.NewRecorder()
		handleDeadlinesListRedirect(w, req)
		if w.Code != http.StatusMovedPermanently {
			t.Fatalf("%s: status = %d, want 301", tc.path, w.Code)
		}
		if got := w.Header().Get("Location"); got != tc.want {
			t.Fatalf("%s: Location = %q, want %q", tc.path, got, tc.want)
		}
	}
}
