package auth

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

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

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

	handler := &EmailVerificationHandler{}
	router := gin.New()
	router.POST("/api/v1/auth/forgot-password", handler.ForgotPassword)

	recorder := httptest.NewRecorder()
	request := httptest.NewRequest(http.MethodPost, "/api/v1/auth/forgot-password", bytes.NewBufferString(`{"email":"not-an-email"}`))
	router.ServeHTTP(recorder, request)

	require.Equal(t, http.StatusBadRequest, recorder.Code)
	require.Contains(t, recorder.Body.String(), "invalid email address")
}

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

	handler := &EmailVerificationHandler{passwordAuthDisabled: true}
	router := gin.New()
	router.POST("/api/v1/auth/forgot-password", handler.ForgotPassword)

	recorder := httptest.NewRecorder()
	request := httptest.NewRequest(http.MethodPost, "/api/v1/auth/forgot-password", bytes.NewBufferString(`{"email":"user@example.com"}`))
	router.ServeHTTP(recorder, request)

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

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

	tests := []struct {
		name     string
		body     string
		wantBody string
	}{
		{
			name:     "empty token",
			body:     `{"token":"   ","password":"secret"}`,
			wantBody: "token is required",
		},
		{
			name:     "short password",
			body:     `{"token":"rst_test","password":"12345"}`,
			wantBody: "Password must be at least 6 characters",
		},
	}

	handler := &EmailVerificationHandler{}
	router := gin.New()
	router.POST("/api/v1/auth/reset-password", handler.ResetPassword)

	for _, tt := range tests {
		tt := tt
		t.Run(tt.name, func(t *testing.T) {
			t.Parallel()

			recorder := httptest.NewRecorder()
			request := httptest.NewRequest(http.MethodPost, "/api/v1/auth/reset-password", bytes.NewBufferString(tt.body))
			router.ServeHTTP(recorder, request)

			require.Equal(t, http.StatusBadRequest, recorder.Code)
			require.Contains(t, recorder.Body.String(), tt.wantBody)
		})
	}
}

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

	handler := &EmailVerificationHandler{passwordAuthDisabled: true}
	router := gin.New()
	router.POST("/api/v1/auth/reset-password", handler.ResetPassword)

	recorder := httptest.NewRecorder()
	request := httptest.NewRequest(http.MethodPost, "/api/v1/auth/reset-password", bytes.NewBufferString(`{"token":"rst_test","password":"secret"}`))
	router.ServeHTTP(recorder, request)

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