package auth

import (
	"bytes"
	"net/http"
	"net/http/httptest"
	"testing"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/AgentTeam/internal/api"
	"github.com/tidbcloud/AgentTeam/internal/api/dto"
	"github.com/tidbcloud/AgentTeam/internal/store/identity"
)

func TestPasswordTooShortMessageIncludesMinimum(t *testing.T) {
	t.Parallel()

	require.Equal(t, "Password must be at least 6 characters", passwordTooShortMessage(6))
}

func TestProfileMeReturnsAuthenticatedUserShape(t *testing.T) {
	t.Parallel()

	now := httptest.NewRecorder()
	handler := &ProfileHandler{}
	router := gin.New()
	createdAt := time.Date(2026, time.August, 6, 8, 30, 0, 0, time.UTC)
	router.GET("/api/v1/me", func(ctx *gin.Context) {
		api.SetAuthenticatedUser(ctx, identity.AuthenticatedUser{User: identity.User{ID: "usr_1", Email: "user@example.com", Name: "user", CreatedAt: createdAt}})
	}, handleAuth(handler.Me))

	request := httptest.NewRequest(http.MethodGet, "/api/v1/me", nil)
	router.ServeHTTP(now, request)

	require.Equal(t, http.StatusOK, now.Code)
	require.JSONEq(t, `{"id":"usr_1","email":"user@example.com","name":"user","isAdmin":false,"emailVerified":false,"mobileVerified":false,"createdAt":"2026-08-06T08:30:00Z"}`, now.Body.String())
}

func TestProfileUpdateMeRejectsIncompletePasswordChange(t *testing.T) {
	t.Parallel()

	handler := &ProfileHandler{}
	router := gin.New()
	router.PATCH("/api/v1/me", func(ctx *gin.Context) {
		api.SetAuthenticatedUser(ctx, identity.AuthenticatedUser{User: identity.User{ID: "usr_1", Email: "user@example.com"}})
	}, handleAuthJSON[dto.UpdateProfileRequest](handler.UpdateMe))

	recorder := httptest.NewRecorder()
	request := httptest.NewRequest(http.MethodPatch, "/api/v1/me", bytes.NewBufferString(`{"currentPassword":"old-password"}`))
	router.ServeHTTP(recorder, request)

	require.Equal(t, http.StatusBadRequest, recorder.Code)
	require.Contains(t, recorder.Body.String(), "currentPassword and newPassword are required")
}

func TestProfileUpdateMeReturnsUnavailableWhenPasswordAuthDisabled(t *testing.T) {
	t.Parallel()

	handler := &ProfileHandler{passwordAuthDisabled: true}
	router := gin.New()
	router.PATCH("/api/v1/me", func(ctx *gin.Context) {
		api.SetAuthenticatedUser(ctx, identity.AuthenticatedUser{User: identity.User{ID: "usr_1", Email: "user@example.com"}})
	}, handleAuthJSON[dto.UpdateProfileRequest](handler.UpdateMe))

	recorder := httptest.NewRecorder()
	request := httptest.NewRequest(http.MethodPatch, "/api/v1/me", bytes.NewBufferString(`{"displayName":"New Name","currentPassword":"old-password","newPassword":"new-password"}`))
	router.ServeHTTP(recorder, request)

	require.Equal(t, http.StatusServiceUnavailable, recorder.Code)
	require.Contains(t, recorder.Body.String(), "Password auth is disabled")
}
