package handler

import (
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/gofiber/fiber/v2"
	"github.com/stretchr/testify/require"
)

func TestGetMe_IncludesSessionAuthenticatedAtFromKratosSession(t *testing.T) {
	const (
		token                = "token-session"
		identityID           = "user-session"
		sessionAuthenticated = "2026-03-23T15:30:00Z"
	)

	transport := roundTripFunc(func(r *http.Request) (*http.Response, error) {
		if r.URL.Host == "kratos.test" &&
			r.URL.Path == "/sessions/whoami" &&
			r.Method == http.MethodGet {
			require.Equal(t, token, r.Header.Get("X-Session-Token"))
			return httpJSONAny(r, http.StatusOK, map[string]any{
				"id":               "kratos-session-1",
				"authenticated_at": sessionAuthenticated,
				"identity": map[string]any{
					"id": identityID,
					"traits": map[string]any{
						"email":           "qa@example.com",
						"name":            "QA User",
						"department":      "Platform",
						"affiliationType": "GENERAL",
					},
				},
			}), nil
		}

		return httpResponse(r, http.StatusNotFound, "not found"), nil
	})
	setDefaultHTTPClientForTest(t, transport)
	t.Setenv("KRATOS_PUBLIC_URL", "http://kratos.test")

	h := &AuthHandler{}
	app := fiber.New()
	app.Get("/api/v1/user/me", h.GetMe)

	req := httptest.NewRequest(http.MethodGet, "/api/v1/user/me", nil)
	req.Header.Set("Authorization", "Bearer "+token)
	resp, err := app.Test(req, -1)
	require.NoError(t, err)
	require.Equal(t, http.StatusOK, resp.StatusCode)

	var profile map[string]any
	require.NoError(t, json.NewDecoder(resp.Body).Decode(&profile))
	require.Equal(t, sessionAuthenticated, profile["sessionAuthenticatedAt"])
}

func TestGetMe_IncludesSessionAuthenticatedAtForCookieSession(t *testing.T) {
	const (
		cookieHeader         = "ory_kratos_session=session-cookie"
		identityID           = "user-cookie"
		sessionAuthenticated = "2026-03-24T01:20:00Z"
	)

	transport := roundTripFunc(func(r *http.Request) (*http.Response, error) {
		if r.URL.Host == "kratos.test" &&
			r.URL.Path == "/sessions/whoami" &&
			r.Method == http.MethodGet {
			require.Equal(t, cookieHeader, r.Header.Get("Cookie"))
			return httpJSONAny(r, http.StatusOK, map[string]any{
				"id":               "kratos-session-cookie",
				"authenticated_at": sessionAuthenticated,
				"identity": map[string]any{
					"id": identityID,
					"traits": map[string]any{
						"email":           "cookie@example.com",
						"name":            "Cookie User",
						"department":      "Platform",
						"affiliationType": "GENERAL",
					},
				},
			}), nil
		}

		return httpResponse(r, http.StatusNotFound, "not found"), nil
	})
	setDefaultHTTPClientForTest(t, transport)
	t.Setenv("KRATOS_PUBLIC_URL", "http://kratos.test")

	h := &AuthHandler{}
	app := fiber.New()
	app.Get("/api/v1/user/me", h.GetMe)

	req := httptest.NewRequest(http.MethodGet, "/api/v1/user/me", nil)
	req.Header.Set("Cookie", cookieHeader)
	resp, err := app.Test(req, -1)
	require.NoError(t, err)
	require.Equal(t, http.StatusOK, resp.StatusCode)

	var profile map[string]any
	require.NoError(t, json.NewDecoder(resp.Body).Decode(&profile))
	require.Equal(t, sessionAuthenticated, profile["sessionAuthenticatedAt"])
}
