package e2e

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/http/httptest"
	"testing"
	"time"

	"git.kirlllll.ru/volontery/backend/internal/api"
	"git.kirlllll.ru/volontery/backend/internal/config"
	"git.kirlllll.ru/volontery/backend/internal/database"
	"git.kirlllll.ru/volontery/backend/internal/pkg/jwt"
	"git.kirlllll.ru/volontery/backend/internal/repository"
	"git.kirlllll.ru/volontery/backend/internal/service"
	"github.com/jackc/pgx/v5/pgtype"
	"github.com/jackc/pgx/v5/pgxpool"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"github.com/stretchr/testify/suite"
)

// APITestSuite - набор E2E тестов для API
type APITestSuite struct {
	suite.Suite
	server      *api.Server
	db          *pgxpool.Pool
	queries     *database.Queries
	cfg         *config.Config
	accessToken string
	userID      int64
}

// SetupSuite запускается один раз перед всеми тестами
func (suite *APITestSuite) SetupSuite() {
	// Загрузка конфигурации
	cfg, err := config.Load()
	require.NoError(suite.T(), err)
	suite.cfg = cfg

	// Подключение к БД
	ctx := context.Background()
	db, err := pgxpool.New(ctx, cfg.DatabaseURL)
	require.NoError(suite.T(), err)
	suite.db = db

	suite.queries = database.New(db)

	// Инициализация зависимостей
	jwtManager := jwt.NewManager(cfg.JWTSecret, cfg.JWTAccessTokenTTL, cfg.JWTRefreshTokenTTL)
	require.NoError(suite.T(), err)

	authRepo := repository.NewAuthRepository(suite.queries)
	userRepo := repository.NewUserRepository(suite.queries)
	rbacRepo := repository.NewRBACRepository(suite.queries)
	authService := service.NewAuthService(userRepo, authRepo, rbacRepo, jwtManager)
	userService := service.NewUserService(userRepo, rbacRepo)
	requestRepo := repository.NewRequestRepository(suite.queries)
	requestService := service.NewRequestService(requestRepo)

	// Создание сервера
	suite.server = api.NewServer(cfg, authService, userService, requestService, jwtManager)
}

// TearDownSuite запускается один раз после всех тестов
func (suite *APITestSuite) TearDownSuite() {
	if suite.db != nil {
		suite.db.Close()
	}
}

// TestAPITestSuite - точка входа для запуска набора тестов
func TestAPITestSuite(t *testing.T) {
	suite.Run(t, new(APITestSuite))
}

// Helper функции

// createModerator создает пользователя с ролью moderator
func (suite *APITestSuite) createModerator() (userID int64, token string) {
	// Создаем пользователя
	email := fmt.Sprintf("moderator_%d@example.com", time.Now().UnixNano())
	registerReq := map[string]interface{}{
		"email":      email,
		"password":   "SecureP@ssw0rd123",
		"first_name": "Moderator",
		"last_name":  "User",
	}

	_, regBody := suite.makeRequest("POST", "/api/v1/auth/register", registerReq, "")
	var authResp map[string]interface{}
	err := json.Unmarshal(regBody, &authResp)
	require.NoError(suite.T(), err)

	token = authResp["access_token"].(string)
	user := authResp["user"].(map[string]interface{})
	userID = int64(user["id"].(float64))

	// Получаем роль moderator
	role, err := suite.queries.GetRoleByName(context.Background(), "moderator")
	require.NoError(suite.T(), err)

	// Назначаем роль модератора
	_, err = suite.queries.AssignRoleToUser(context.Background(), database.AssignRoleToUserParams{
		UserID: userID,
		RoleID: role.ID,
		AssignedBy: pgtype.Int8{
			Int64: userID,
			Valid: true,
		}, // self-assigned for testing
	})
	require.NoError(suite.T(), err)

	return userID, token
}

// createApprovedRequest создает заявку и одобряет её
func (suite *APITestSuite) createApprovedRequest(requesterToken string) int64 {
	// Получаем типы заявок
	_, body := suite.makeRequest("GET", "/api/v1/request-types", nil, "")
	var types []map[string]interface{}
	json.Unmarshal(body, &types)
	require.NotEmpty(suite.T(), types)

	requestTypeID := int64(types[0]["id"].(float64))

	// Создаем заявку
	createReq := map[string]interface{}{
		"request_type_id": requestTypeID,
		"title":           fmt.Sprintf("Test Request %d", time.Now().UnixNano()),
		"description":     "Test description",
		"latitude":        55.751244,
		"longitude":       37.618423,
		"address":         "Test Address",
		"city":            "Москва",
		"urgency":         "medium",
	}

	_, respBody := suite.makeRequest("POST", "/api/v1/requests", createReq, requesterToken)
	var request map[string]interface{}
	json.Unmarshal(respBody, &request)
	requestID := int64(request["id"].(float64))

	// Создаем модератора и одобряем заявку
	moderatorID, moderatorToken := suite.createModerator()
	url := fmt.Sprintf("/api/v1/moderation/requests/%d/approve", requestID)
	approveReq := map[string]interface{}{
		"comment": "Approved for testing",
	}
	resp, _ := suite.makeRequest("POST", url, approveReq, moderatorToken)
	require.Equal(suite.T(), http.StatusOK, resp.StatusCode, "Failed to approve request, moderator_id=%d", moderatorID)

	return requestID
}

// createVolunteerWithResponse создает волонтера и отклик
func (suite *APITestSuite) createVolunteerWithResponse(requestID int64) (volunteerID int64, responseID int64, token string) {
	// Создаем волонтера
	email := fmt.Sprintf("volunteer_%d@example.com", time.Now().UnixNano())
	registerReq := map[string]interface{}{
		"email":      email,
		"password":   "SecureP@ssw0rd123",
		"first_name": "Volunteer",
		"last_name":  "User",
	}

	_, regBody := suite.makeRequest("POST", "/api/v1/auth/register", registerReq, "")
	var authResp map[string]interface{}
	json.Unmarshal(regBody, &authResp)
	token = authResp["access_token"].(string)
	user := authResp["user"].(map[string]interface{})
	volunteerID = int64(user["id"].(float64))

	// Создаем отклик
	responseReq := map[string]interface{}{
		"message": "I can help with this request",
	}
	url := fmt.Sprintf("/api/v1/requests/%d/responses", requestID)
	_, respBody := suite.makeRequest("POST", url, responseReq, token)
	var response map[string]interface{}
	json.Unmarshal(respBody, &response)
	responseID = int64(response["id"].(float64))

	return volunteerID, responseID, token
}

// checkModeratorAction проверяет наличие записи в moderator_actions
func (suite *APITestSuite) checkModeratorAction(moderatorID, requestID int64, actionType string) {
	actions, err := suite.queries.GetModeratorActionsByRequest(context.Background(), pgtype.Int8{
		Int64: requestID,
		Valid: true,
	})
	require.NoError(suite.T(), err)

	found := false
	for _, action := range actions {
		if action.ModeratorID == moderatorID && string(action.ActionType) == actionType {
			found = true
			break
		}
	}
	assert.True(suite.T(), found, "Moderator action not found: moderator_id=%d, request_id=%d, action_type=%s", moderatorID, requestID, actionType)
}

// checkRequestStatusHistory проверяет историю статусов
func (suite *APITestSuite) checkRequestStatusHistory(requestID int64, expectedStatuses []string) {
	history, err := suite.queries.GetRequestStatusHistory(context.Background(), requestID)
	require.NoError(suite.T(), err)

	// Получаем список статусов из истории (в обратном порядке - от новых к старым)
	var actualStatuses []string
	for i := len(history) - 1; i >= 0; i-- {
		actualStatuses = append(actualStatuses, string(history[i].ToStatus))
	}

	// Проверяем, что все ожидаемые статусы присутствуют
	for _, expectedStatus := range expectedStatuses {
		found := false
		for _, actualStatus := range actualStatuses {
			if actualStatus == expectedStatus {
				found = true
				break
			}
		}
		assert.True(suite.T(), found, "Expected status %s not found in history for request %d. Actual: %v", expectedStatus, requestID, actualStatuses)
	}
}

func (suite *APITestSuite) makeRequest(method, path string, body interface{}, token string) (*http.Response, []byte) {
	var bodyReader io.Reader
	if body != nil {
		jsonBody, err := json.Marshal(body)
		require.NoError(suite.T(), err)
		bodyReader = bytes.NewReader(jsonBody)
	}

	req := httptest.NewRequest(method, path, bodyReader)
	if bodyReader != nil {
		req.Header.Set("Content-Type", "application/json")
	}
	if token != "" {
		req.Header.Set("Authorization", "Bearer "+token)
	}

	w := httptest.NewRecorder()
	suite.server.ServeHTTP(w, req)

	resp := w.Result()
	respBody, err := io.ReadAll(resp.Body)
	require.NoError(suite.T(), err)
	defer resp.Body.Close()

	return resp, respBody
}

// Test 1: Health Check
func (suite *APITestSuite) Test01_HealthCheck() {
	suite.T().Log("Testing: GET /health")

	resp, body := suite.makeRequest("GET", "/health", nil, "")

	assert.Equal(suite.T(), http.StatusOK, resp.StatusCode)
	assert.Equal(suite.T(), "OK", string(body))
}

// Test 2: User Registration
func (suite *APITestSuite) Test02_Register() {
	suite.T().Log("Testing: POST /api/v1/auth/register")

	registerReq := map[string]interface{}{
		"email":      fmt.Sprintf("test_%d@example.com", time.Now().Unix()),
		"password":   "SecureP@ssw0rd123",
		"first_name": "Test",
		"last_name":  "User",
		"phone":      "+79001234567",
		"latitude":   55.751244,
		"longitude":  37.618423,
		"city":       "Москва",
		"bio":        "Test bio",
	}

	resp, body := suite.makeRequest("POST", "/api/v1/auth/register", registerReq, "")

	assert.Equal(suite.T(), http.StatusCreated, resp.StatusCode)
	assert.Equal(suite.T(), "application/json", resp.Header.Get("Content-Type"))

	var authResp map[string]interface{}
	err := json.Unmarshal(body, &authResp)
	require.NoError(suite.T(), err)

	assert.Contains(suite.T(), authResp, "access_token")
	assert.Contains(suite.T(), authResp, "refresh_token")
	assert.Contains(suite.T(), authResp, "expires_in")
	assert.Contains(suite.T(), authResp, "user")

	// Сохраняем токен для последующих тестов
	suite.accessToken = authResp["access_token"].(string)

	user := authResp["user"].(map[string]interface{})
	suite.userID = int64(user["id"].(float64))
}

// Test 3: Login
func (suite *APITestSuite) Test03_Login() {
	suite.T().Log("Testing: POST /api/v1/auth/login")

	// Сначала регистрируем пользователя
	email := fmt.Sprintf("login_test_%d@example.com", time.Now().Unix())
	password := "SecureP@ssw0rd123"

	registerReq := map[string]interface{}{
		"email":      email,
		"password":   password,
		"first_name": "Login",
		"last_name":  "Test User",
	}

	suite.makeRequest("POST", "/api/v1/auth/register", registerReq, "")

	// Теперь логинимся
	loginReq := map[string]interface{}{
		"email":    email,
		"password": password,
	}

	resp, body := suite.makeRequest("POST", "/api/v1/auth/login", loginReq, "")

	assert.Equal(suite.T(), http.StatusOK, resp.StatusCode)

	var authResp map[string]interface{}
	err := json.Unmarshal(body, &authResp)
	require.NoError(suite.T(), err)

	assert.Contains(suite.T(), authResp, "access_token")
	assert.Contains(suite.T(), authResp, "refresh_token")
}

// Test 4: Login with wrong credentials
func (suite *APITestSuite) Test04_Login_WrongCredentials() {
	suite.T().Log("Testing: POST /api/v1/auth/login (invalid credentials)")

	loginReq := map[string]interface{}{
		"email":    "nonexistent@example.com",
		"password": "wrongpassword",
	}

	resp, body := suite.makeRequest("POST", "/api/v1/auth/login", loginReq, "")

	assert.Equal(suite.T(), http.StatusUnauthorized, resp.StatusCode)

	var errorResp map[string]interface{}
	err := json.Unmarshal(body, &errorResp)
	require.NoError(suite.T(), err)

	assert.Contains(suite.T(), errorResp, "error")
}

// Test 5: Get current user info
func (suite *APITestSuite) Test05_AuthMe() {
	suite.T().Log("Testing: GET /api/v1/auth/me")

	resp, body := suite.makeRequest("GET", "/api/v1/auth/me", nil, suite.accessToken)

	assert.Equal(suite.T(), http.StatusOK, resp.StatusCode)

	var userInfo map[string]interface{}
	err := json.Unmarshal(body, &userInfo)
	require.NoError(suite.T(), err)

	assert.Contains(suite.T(), userInfo, "id")
	assert.Contains(suite.T(), userInfo, "email")
	assert.Equal(suite.T(), float64(suite.userID), userInfo["id"].(float64))
}

// Test 6: Get current user profile
func (suite *APITestSuite) Test06_GetMyProfile() {
	suite.T().Log("Testing: GET /api/v1/users/me")

	resp, body := suite.makeRequest("GET", "/api/v1/users/me", nil, suite.accessToken)

	assert.Equal(suite.T(), http.StatusOK, resp.StatusCode)

	var profile map[string]interface{}
	err := json.Unmarshal(body, &profile)
	require.NoError(suite.T(), err)

	assert.Contains(suite.T(), profile, "id")
	assert.Contains(suite.T(), profile, "email")
	assert.Contains(suite.T(), profile, "first_name")
	assert.Contains(suite.T(), profile, "last_name")
	assert.Contains(suite.T(), profile, "created_at")
}

// Test 7: Update profile
func (suite *APITestSuite) Test07_UpdateProfile() {
	suite.T().Log("Testing: PATCH /api/v1/users/me")

	updateReq := map[string]interface{}{
		"first_name": "Updated",
		"last_name":  "Name",
		"city":       "Санкт-Петербург",
	}

	resp, body := suite.makeRequest("PATCH", "/api/v1/users/me", updateReq, suite.accessToken)

	assert.Equal(suite.T(), http.StatusOK, resp.StatusCode)

	var result map[string]interface{}
	err := json.Unmarshal(body, &result)
	require.NoError(suite.T(), err)

	assert.Contains(suite.T(), result, "message")
}

// Test 8: Update location
func (suite *APITestSuite) Test08_UpdateLocation() {
	suite.T().Log("Testing: POST /api/v1/users/me/location")

	locationReq := map[string]interface{}{
		"latitude":  59.9343,
		"longitude": 30.3351,
	}

	resp, body := suite.makeRequest("POST", "/api/v1/users/me/location", locationReq, suite.accessToken)

	assert.Equal(suite.T(), http.StatusOK, resp.StatusCode)

	var result map[string]interface{}
	err := json.Unmarshal(body, &result)
	require.NoError(suite.T(), err)

	assert.Contains(suite.T(), result, "message")
}

// Test 9: Get user roles
func (suite *APITestSuite) Test09_GetMyRoles() {
	suite.T().Log("Testing: GET /api/v1/users/me/roles")

	resp, body := suite.makeRequest("GET", "/api/v1/users/me/roles", nil, suite.accessToken)

	assert.Equal(suite.T(), http.StatusOK, resp.StatusCode)

	var roles []map[string]interface{}
	err := json.Unmarshal(body, &roles)
	require.NoError(suite.T(), err)

	// Пользователь должен иметь хотя бы одну роль
	assert.NotEmpty(suite.T(), roles)
}

// Test 10: Get user permissions
func (suite *APITestSuite) Test10_GetMyPermissions() {
	suite.T().Log("Testing: GET /api/v1/users/me/permissions")

	resp, body := suite.makeRequest("GET", "/api/v1/users/me/permissions", nil, suite.accessToken)

	assert.Equal(suite.T(), http.StatusOK, resp.StatusCode)

	var permissions []map[string]interface{}
	err := json.Unmarshal(body, &permissions)
	require.NoError(suite.T(), err)

	// Пользователь должен иметь разрешения
	assert.NotEmpty(suite.T(), permissions)
}

// Test 11: Get request types
func (suite *APITestSuite) Test11_GetRequestTypes() {
	suite.T().Log("Testing: GET /api/v1/request-types")

	resp, body := suite.makeRequest("GET", "/api/v1/request-types", nil, "")

	assert.Equal(suite.T(), http.StatusOK, resp.StatusCode)

	var types []map[string]interface{}
	err := json.Unmarshal(body, &types)
	require.NoError(suite.T(), err)

	// Должны быть типы заявок в БД
	assert.NotEmpty(suite.T(), types)

	// Проверяем структуру
	if len(types) > 0 {
		assert.Contains(suite.T(), types[0], "id")
		assert.Contains(suite.T(), types[0], "name")
	}
}

// Test 12: Create request
func (suite *APITestSuite) Test12_CreateRequest() {
	suite.T().Log("Testing: POST /api/v1/requests")

	// Получаем типы заявок
	_, body := suite.makeRequest("GET", "/api/v1/request-types", nil, "")
	var types []map[string]interface{}
	json.Unmarshal(body, &types)
	require.NotEmpty(suite.T(), types)

	requestTypeID := int64(types[0]["id"].(float64))

	createReq := map[string]interface{}{
		"request_type_id":         requestTypeID,
		"title":                   "Нужна помощь с покупкой продуктов",
		"description":             "Прошу помочь купить продукты в ближайшем магазине. Список прилагается.",
		"latitude":                55.751244,
		"longitude":               37.618423,
		"address":                 "ул. Тверская, д. 1, кв. 10",
		"city":                    "Москва",
		"urgency":                 "high",
		"contact_phone":           "+79001234567",
		"contact_notes":           "Код домофона: 123",
		"desired_completion_date": time.Now().Add(24 * time.Hour).Format(time.RFC3339),
	}

	resp, body := suite.makeRequest("POST", "/api/v1/requests", createReq, suite.accessToken)

	assert.Equal(suite.T(), http.StatusCreated, resp.StatusCode)

	var request map[string]interface{}
	err := json.Unmarshal(body, &request)
	require.NoError(suite.T(), err)

	assert.Contains(suite.T(), request, "id")
	assert.Contains(suite.T(), request, "title")
	assert.Contains(suite.T(), request, "status")
}

// Test 13: Get my requests
func (suite *APITestSuite) Test13_GetMyRequests() {
	suite.T().Log("Testing: GET /api/v1/requests/my")

	resp, body := suite.makeRequest("GET", "/api/v1/requests/my?limit=10&offset=0", nil, suite.accessToken)

	assert.Equal(suite.T(), http.StatusOK, resp.StatusCode)

	var requests []map[string]interface{}
	err := json.Unmarshal(body, &requests)
	require.NoError(suite.T(), err)

	// Должна быть хотя бы одна заявка (созданная в предыдущем тесте)
	assert.NotEmpty(suite.T(), requests)
}

// Test 14: Find nearby requests
func (suite *APITestSuite) Test14_FindNearbyRequests() {
	suite.T().Log("Testing: GET /api/v1/requests/nearby")

	url := "/api/v1/requests/nearby?lat=55.751244&lon=37.618423&radius=5000&limit=10&offset=0"
	resp, body := suite.makeRequest("GET", url, nil, suite.accessToken)

	if resp.StatusCode != http.StatusOK {
		suite.T().Logf("Error response body: %s", string(body))
	}
	assert.Equal(suite.T(), http.StatusOK, resp.StatusCode)

	var requests []map[string]interface{}
	err := json.Unmarshal(body, &requests)
	require.NoError(suite.T(), err)

	// Проверяем наличие distance_meters в ответе
	if len(requests) > 0 {
		assert.Contains(suite.T(), requests[0], "distance_meters")
	}
}

// Test 15: Find requests in bounds
func (suite *APITestSuite) Test15_FindRequestsInBounds() {
	suite.T().Log("Testing: GET /api/v1/requests/bounds")

	url := "/api/v1/requests/bounds?min_lon=37.6&min_lat=55.7&max_lon=37.7&max_lat=55.8"
	resp, body := suite.makeRequest("GET", url, nil, suite.accessToken)

	assert.Equal(suite.T(), http.StatusOK, resp.StatusCode)

	var requests []map[string]interface{}
	err := json.Unmarshal(body, &requests)
	require.NoError(suite.T(), err)

	// Ответ должен быть массивом
	assert.NotNil(suite.T(), requests)
}

// Test 16: Get request by ID
func (suite *APITestSuite) Test16_GetRequestByID() {
	suite.T().Log("Testing: GET /api/v1/requests/{id}")

	// Получаем список своих заявок
	_, body := suite.makeRequest("GET", "/api/v1/requests/my", nil, suite.accessToken)
	var requests []map[string]interface{}
	json.Unmarshal(body, &requests)
	require.NotEmpty(suite.T(), requests)

	requestID := int64(requests[0]["id"].(float64))

	// Получаем заявку по ID
	url := fmt.Sprintf("/api/v1/requests/%d", requestID)
	resp, body := suite.makeRequest("GET", url, nil, suite.accessToken)

	assert.Equal(suite.T(), http.StatusOK, resp.StatusCode)

	var request map[string]interface{}
	err := json.Unmarshal(body, &request)
	require.NoError(suite.T(), err)

	assert.Equal(suite.T(), float64(requestID), request["id"].(float64))
	assert.Contains(suite.T(), request, "title")
	assert.Contains(suite.T(), request, "description")
}

// Test 17: Create volunteer response
func (suite *APITestSuite) Test17_CreateVolunteerResponse() {
	suite.T().Log("Testing: POST /api/v1/requests/{id}/responses")

	// Создаем нового волонтера
	email := fmt.Sprintf("volunteer_%d@example.com", time.Now().Unix())
	registerReq := map[string]interface{}{
		"email":      email,
		"password":   "SecureP@ssw0rd123",
		"first_name": "Volunteer",
		"last_name":  "User",
	}

	_, regBody := suite.makeRequest("POST", "/api/v1/auth/register", registerReq, "")
	var authResp map[string]interface{}
	json.Unmarshal(regBody, &authResp)
	volunteerToken := authResp["access_token"].(string)

	// Получаем список заявок
	_, body := suite.makeRequest("GET", "/api/v1/requests/my", nil, suite.accessToken)
	var requests []map[string]interface{}
	json.Unmarshal(body, &requests)
	require.NotEmpty(suite.T(), requests)

	requestID := int64(requests[0]["id"].(float64))

	// Создаем отклик
	responseReq := map[string]interface{}{
		"message": "Готов помочь завтра после 15:00",
	}

	url := fmt.Sprintf("/api/v1/requests/%d/responses", requestID)
	resp, body := suite.makeRequest("POST", url, responseReq, volunteerToken)

	assert.Equal(suite.T(), http.StatusCreated, resp.StatusCode)

	var response map[string]interface{}
	err := json.Unmarshal(body, &response)
	require.NoError(suite.T(), err)

	assert.Contains(suite.T(), response, "id")
	assert.Contains(suite.T(), response, "volunteer_id")
	assert.Contains(suite.T(), response, "status")
}

// Test 18: Get request responses
func (suite *APITestSuite) Test18_GetRequestResponses() {
	suite.T().Log("Testing: GET /api/v1/requests/{id}/responses")

	// Получаем список своих заявок
	_, body := suite.makeRequest("GET", "/api/v1/requests/my", nil, suite.accessToken)
	var requests []map[string]interface{}
	json.Unmarshal(body, &requests)
	require.NotEmpty(suite.T(), requests)

	requestID := int64(requests[0]["id"].(float64))

	// Получаем отклики
	url := fmt.Sprintf("/api/v1/requests/%d/responses", requestID)
	resp, body := suite.makeRequest("GET", url, nil, suite.accessToken)

	assert.Equal(suite.T(), http.StatusOK, resp.StatusCode)

	var responses []map[string]interface{}
	err := json.Unmarshal(body, &responses)
	require.NoError(suite.T(), err)

	// Должен быть хотя бы один отклик (созданный в предыдущем тесте)
	assert.NotEmpty(suite.T(), responses)

	if len(responses) > 0 {
		assert.Contains(suite.T(), responses[0], "volunteer_id")
		assert.Contains(suite.T(), responses[0], "status")
	}
}

// Test 19: Refresh token
func (suite *APITestSuite) Test19_RefreshToken() {
	suite.T().Log("Testing: POST /api/v1/auth/refresh")

	// Регистрируем нового пользователя
	email := fmt.Sprintf("refresh_test_%d@example.com", time.Now().Unix())
	registerReq := map[string]interface{}{
		"email":      email,
		"password":   "SecureP@ssw0rd123",
		"first_name": "Refresh",
		"last_name":  "Test User",
	}

	_, regBody := suite.makeRequest("POST", "/api/v1/auth/register", registerReq, "")
	var authResp map[string]interface{}
	json.Unmarshal(regBody, &authResp)
	refreshToken := authResp["refresh_token"].(string)

	// Обновляем токен
	refreshReq := map[string]interface{}{
		"refresh_token": refreshToken,
	}

	resp, body := suite.makeRequest("POST", "/api/v1/auth/refresh", refreshReq, "")

	assert.Equal(suite.T(), http.StatusOK, resp.StatusCode)

	var newAuthResp map[string]interface{}
	err := json.Unmarshal(body, &newAuthResp)
	require.NoError(suite.T(), err)

	assert.Contains(suite.T(), newAuthResp, "access_token")
	assert.Contains(suite.T(), newAuthResp, "refresh_token")
	assert.NotEqual(suite.T(), refreshToken, newAuthResp["refresh_token"].(string))
}

// Test 20: Logout
func (suite *APITestSuite) Test20_Logout() {
	suite.T().Log("Testing: POST /api/v1/auth/logout")

	resp, body := suite.makeRequest("POST", "/api/v1/auth/logout", nil, suite.accessToken)

	assert.Equal(suite.T(), http.StatusOK, resp.StatusCode)

	var result map[string]interface{}
	err := json.Unmarshal(body, &result)
	require.NoError(suite.T(), err)

	assert.Contains(suite.T(), result, "message")
}

// Test 21: Unauthorized access
func (suite *APITestSuite) Test21_UnauthorizedAccess() {
	suite.T().Log("Testing: Unauthorized access to protected endpoint")

	resp, body := suite.makeRequest("GET", "/api/v1/users/me", nil, "")

	assert.Equal(suite.T(), http.StatusUnauthorized, resp.StatusCode)

	var errorResp map[string]interface{}
	err := json.Unmarshal(body, &errorResp)
	require.NoError(suite.T(), err)

	assert.Contains(suite.T(), errorResp, "error")
}

// Test 22: Invalid token
func (suite *APITestSuite) Test22_InvalidToken() {
	suite.T().Log("Testing: Invalid token")

	resp, body := suite.makeRequest("GET", "/api/v1/users/me", nil, "invalid.token.here")

	assert.Equal(suite.T(), http.StatusUnauthorized, resp.StatusCode)

	var errorResp map[string]interface{}
	err := json.Unmarshal(body, &errorResp)
	require.NoError(suite.T(), err)

	assert.Contains(suite.T(), errorResp, "error")
}

// Test 23: Get user by ID
func (suite *APITestSuite) Test23_GetUserByID() {
	suite.T().Log("Testing: GET /api/v1/users/{id}")

	url := fmt.Sprintf("/api/v1/users/%d", suite.userID)
	resp, body := suite.makeRequest("GET", url, nil, suite.accessToken)

	assert.Equal(suite.T(), http.StatusOK, resp.StatusCode)

	var profile map[string]interface{}
	err := json.Unmarshal(body, &profile)
	require.NoError(suite.T(), err)

	assert.Equal(suite.T(), float64(suite.userID), profile["id"].(float64))
	assert.Contains(suite.T(), profile, "email")
	assert.Contains(suite.T(), profile, "first_name")
	assert.Contains(suite.T(), profile, "last_name")
}

// Test 24: Invalid request body
func (suite *APITestSuite) Test24_InvalidRequestBody() {
	suite.T().Log("Testing: Invalid request body")

	// Пытаемся зарегистрироваться с невалидными данными
	registerReq := map[string]interface{}{
		"email": "invalid-email", // невалидный email
	}

	resp, body := suite.makeRequest("POST", "/api/v1/auth/register", registerReq, "")

	assert.Equal(suite.T(), http.StatusBadRequest, resp.StatusCode)

	var errorResp map[string]interface{}
	err := json.Unmarshal(body, &errorResp)
	require.NoError(suite.T(), err)

	assert.Contains(suite.T(), errorResp, "error")
}

// Test 25: Pagination
func (suite *APITestSuite) Test25_Pagination() {
	suite.T().Log("Testing: Pagination parameters")

	// Тест с разными параметрами пагинации
	testCases := []struct {
		limit  int
		offset int
	}{
		{10, 0},
		{5, 5},
		{20, 0},
	}

	for _, tc := range testCases {
		url := fmt.Sprintf("/api/v1/requests/my?limit=%d&offset=%d", tc.limit, tc.offset)
		resp, _ := suite.makeRequest("GET", url, nil, suite.accessToken)

		assert.Equal(suite.T(), http.StatusOK, resp.StatusCode)
	}
}

// ============================================================================
// ТЕСТЫ МОДЕРАЦИИ (Test26-Test32)
// ============================================================================

// Test 26: Full moderation workflow
func (suite *APITestSuite) Test26_ModerationWorkflow() {
	suite.T().Log("Testing: Full moderation workflow")

	// 1. Создаем заявку (автоматически pending_moderation)
	_, body := suite.makeRequest("GET", "/api/v1/request-types", nil, "")
	var types []map[string]interface{}
	json.Unmarshal(body, &types)
	require.NotEmpty(suite.T(), types)

	requestTypeID := int64(types[0]["id"].(float64))
	createReq := map[string]interface{}{
		"request_type_id": requestTypeID,
		"title":           "Moderation Test Request",
		"description":     "This request needs moderation",
		"latitude":        55.751244,
		"longitude":       37.618423,
		"address":         "Test Address",
	}

	_, respBody := suite.makeRequest("POST", "/api/v1/requests", createReq, suite.accessToken)
	var request map[string]interface{}
	json.Unmarshal(respBody, &request)
	requestID := int64(request["id"].(float64))

	// status - это объект NullRequestStatus {request_status: "...", valid: true}
	statusObj := request["status"].(map[string]interface{})
	assert.Equal(suite.T(), "pending_moderation", statusObj["request_status"])

	// 2. Создаем модератора
	moderatorID, moderatorToken := suite.createModerator()

	// 3. Получаем список заявок на модерации
	resp, body := suite.makeRequest("GET", "/api/v1/moderation/requests/pending?limit=10&offset=0", nil, moderatorToken)
	assert.Equal(suite.T(), http.StatusOK, resp.StatusCode)

	var pendingRequests []map[string]interface{}
	json.Unmarshal(body, &pendingRequests)
	assert.NotEmpty(suite.T(), pendingRequests)

	// 4. Одобряем заявку
	url := fmt.Sprintf("/api/v1/moderation/requests/%d/approve", requestID)
	approveReq := map[string]interface{}{
		"comment": "Request looks good",
	}
	resp, _ = suite.makeRequest("POST", url, approveReq, moderatorToken)
	assert.Equal(suite.T(), http.StatusOK, resp.StatusCode)

	// 5. Проверяем статус заявки
	url = fmt.Sprintf("/api/v1/requests/%d", requestID)
	resp, body = suite.makeRequest("GET", url, nil, suite.accessToken)
	json.Unmarshal(body, &request)
	statusObj = request["status"].(map[string]interface{})
	assert.Equal(suite.T(), "approved", statusObj["request_status"])

	// 6. Проверяем запись в moderator_actions
	suite.checkModeratorAction(moderatorID, requestID, "approve_request")

	// 7. Проверяем историю статусов
	suite.checkRequestStatusHistory(requestID, []string{"pending_moderation", "approved"})
}

// Test 27: Approve request
func (suite *APITestSuite) Test27_ModerationApprove() {
	suite.T().Log("Testing: POST /api/v1/moderation/requests/{id}/approve")

	// Создаем заявку
	_, body := suite.makeRequest("GET", "/api/v1/request-types", nil, "")
	var types []map[string]interface{}
	json.Unmarshal(body, &types)
	requestTypeID := int64(types[0]["id"].(float64))

	createReq := map[string]interface{}{
		"request_type_id": requestTypeID,
		"title":           "Approve Test",
		"description":     "Test",
		"latitude":        55.751244,
		"longitude":       37.618423,
		"address":         "Test",
	}
	_, respBody := suite.makeRequest("POST", "/api/v1/requests", createReq, suite.accessToken)
	var request map[string]interface{}
	json.Unmarshal(respBody, &request)
	requestID := int64(request["id"].(float64))

	// Модератор одобряет
	moderatorID, moderatorToken := suite.createModerator()
	url := fmt.Sprintf("/api/v1/moderation/requests/%d/approve", requestID)
	approveReq := map[string]interface{}{}
	resp, body := suite.makeRequest("POST", url, approveReq, moderatorToken)

	if resp.StatusCode != http.StatusOK {
		suite.T().Logf("Approve failed with status %d, body: %s", resp.StatusCode, string(body))
	}
	assert.Equal(suite.T(), http.StatusOK, resp.StatusCode)

	// Проверяем статус
	url = fmt.Sprintf("/api/v1/requests/%d", requestID)
	_, body = suite.makeRequest("GET", url, nil, suite.accessToken)
	json.Unmarshal(body, &request)
	statusObj := request["status"].(map[string]interface{})
	assert.Equal(suite.T(), "approved", statusObj["request_status"])

	suite.checkModeratorAction(moderatorID, requestID, "approve_request")
}

// Test 28: Reject request
func (suite *APITestSuite) Test28_ModerationReject() {
	suite.T().Log("Testing: POST /api/v1/moderation/requests/{id}/reject")

	// Создаем заявку
	_, body := suite.makeRequest("GET", "/api/v1/request-types", nil, "")
	var types []map[string]interface{}
	json.Unmarshal(body, &types)
	requestTypeID := int64(types[0]["id"].(float64))

	createReq := map[string]interface{}{
		"request_type_id": requestTypeID,
		"title":           "Reject Test",
		"description":     "Test",
		"latitude":        55.751244,
		"longitude":       37.618423,
		"address":         "Test",
	}
	_, respBody := suite.makeRequest("POST", "/api/v1/requests", createReq, suite.accessToken)
	var request map[string]interface{}
	json.Unmarshal(respBody, &request)
	requestID := int64(request["id"].(float64))

	// Модератор отклоняет
	moderatorID, moderatorToken := suite.createModerator()
	url := fmt.Sprintf("/api/v1/moderation/requests/%d/reject", requestID)
	rejectReq := map[string]interface{}{
		"comment": "Does not meet requirements",
	}
	resp, _ := suite.makeRequest("POST", url, rejectReq, moderatorToken)

	assert.Equal(suite.T(), http.StatusOK, resp.StatusCode)

	// Проверяем статус
	url = fmt.Sprintf("/api/v1/requests/%d", requestID)
	_, body = suite.makeRequest("GET", url, nil, suite.accessToken)
	json.Unmarshal(body, &request)
	statusObj := request["status"].(map[string]interface{})
	assert.Equal(suite.T(), "rejected", statusObj["request_status"])

	suite.checkModeratorAction(moderatorID, requestID, "reject_request")
}

// Test 29: Reject without comment (should fail)
func (suite *APITestSuite) Test29_ModerationRejectWithoutComment() {
	suite.T().Log("Testing: Reject request without comment")

	// Создаем заявку
	_, body := suite.makeRequest("GET", "/api/v1/request-types", nil, "")
	var types []map[string]interface{}
	json.Unmarshal(body, &types)
	requestTypeID := int64(types[0]["id"].(float64))

	createReq := map[string]interface{}{
		"request_type_id": requestTypeID,
		"title":           "Reject No Comment Test",
		"description":     "Test",
		"latitude":        55.751244,
		"longitude":       37.618423,
		"address":         "Test",
	}
	_, respBody := suite.makeRequest("POST", "/api/v1/requests", createReq, suite.accessToken)
	var request map[string]interface{}
	json.Unmarshal(respBody, &request)
	requestID := int64(request["id"].(float64))

	// Модератор пытается отклонить без комментария
	_, moderatorToken := suite.createModerator()
	url := fmt.Sprintf("/api/v1/moderation/requests/%d/reject", requestID)
	rejectReq := map[string]interface{}{
		"comment": "",
	}
	resp, _ := suite.makeRequest("POST", url, rejectReq, moderatorToken)

	assert.Equal(suite.T(), http.StatusBadRequest, resp.StatusCode)
}

// Test 30: Moderation without permission (should fail)
func (suite *APITestSuite) Test30_ModerationWithoutPermission() {
	suite.T().Log("Testing: Moderation without permission")

	// Создаем заявку
	_, body := suite.makeRequest("GET", "/api/v1/request-types", nil, "")
	var types []map[string]interface{}
	json.Unmarshal(body, &types)
	requestTypeID := int64(types[0]["id"].(float64))

	createReq := map[string]interface{}{
		"request_type_id": requestTypeID,
		"title":           "No Permission Test",
		"description":     "Test",
		"latitude":        55.751244,
		"longitude":       37.618423,
		"address":         "Test",
	}
	_, respBody := suite.makeRequest("POST", "/api/v1/requests", createReq, suite.accessToken)
	var request map[string]interface{}
	json.Unmarshal(respBody, &request)
	requestID := int64(request["id"].(float64))

	// Обычный пользователь пытается модерировать
	url := fmt.Sprintf("/api/v1/moderation/requests/%d/approve", requestID)
	resp, _ := suite.makeRequest("POST", url, nil, suite.accessToken)

	assert.Equal(suite.T(), http.StatusForbidden, resp.StatusCode)
}

// Test 31: Get pending moderation requests
func (suite *APITestSuite) Test31_GetPendingModerationRequests() {
	suite.T().Log("Testing: GET /api/v1/moderation/requests/pending")

	// Создаем несколько заявок
	_, body := suite.makeRequest("GET", "/api/v1/request-types", nil, "")
	var types []map[string]interface{}
	json.Unmarshal(body, &types)
	requestTypeID := int64(types[0]["id"].(float64))

	for i := 0; i < 3; i++ {
		createReq := map[string]interface{}{
			"request_type_id": requestTypeID,
			"title":           fmt.Sprintf("Pending Request %d", i),
			"description":     "Test",
			"latitude":        55.751244,
			"longitude":       37.618423,
			"address":         "Test",
		}
		suite.makeRequest("POST", "/api/v1/requests", createReq, suite.accessToken)
	}

	// Модератор получает список
	_, moderatorToken := suite.createModerator()
	resp, body := suite.makeRequest("GET", "/api/v1/moderation/requests/pending?limit=10&offset=0", nil, moderatorToken)

	assert.Equal(suite.T(), http.StatusOK, resp.StatusCode)

	var requests []map[string]interface{}
	json.Unmarshal(body, &requests)
	assert.NotEmpty(suite.T(), requests)

	// Проверяем, что все заявки в статусе pending_moderation
	for _, req := range requests {
		statusObj := req["status"].(map[string]interface{})
		assert.Equal(suite.T(), "pending_moderation", statusObj["request_status"])
	}
}

// Test 32: Get my moderated requests
func (suite *APITestSuite) Test32_GetMyModeratedRequests() {
	suite.T().Log("Testing: GET /api/v1/moderation/requests/my")

	// Создаем модератора
	moderatorID, moderatorToken := suite.createModerator()

	// Создаем и модерируем несколько заявок
	_, body := suite.makeRequest("GET", "/api/v1/request-types", nil, "")
	var types []map[string]interface{}
	json.Unmarshal(body, &types)
	requestTypeID := int64(types[0]["id"].(float64))

	moderatedCount := 0
	for i := 0; i < 2; i++ {
		createReq := map[string]interface{}{
			"request_type_id": requestTypeID,
			"title":           fmt.Sprintf("Moderated Request %d", i),
			"description":     "Test",
			"latitude":        55.751244,
			"longitude":       37.618423,
			"address":         "Test",
		}
		_, respBody := suite.makeRequest("POST", "/api/v1/requests", createReq, suite.accessToken)
		var request map[string]interface{}
		json.Unmarshal(respBody, &request)
		requestID := int64(request["id"].(float64))

		// Одобряем
		url := fmt.Sprintf("/api/v1/moderation/requests/%d/approve", requestID)
		approveReq := map[string]interface{}{}
		resp, _ := suite.makeRequest("POST", url, approveReq, moderatorToken)
		if resp.StatusCode == http.StatusOK {
			moderatedCount++
		}
	}

	// Получаем историю модерации
	resp, body := suite.makeRequest("GET", "/api/v1/moderation/requests/my?limit=10&offset=0", nil, moderatorToken)

	assert.Equal(suite.T(), http.StatusOK, resp.StatusCode)

	var requests []map[string]interface{}
	json.Unmarshal(body, &requests)
	assert.NotEmpty(suite.T(), requests)

	// Проверяем, что все заявки модерированы этим модератором
	for _, req := range requests {
		if req["moderated_by"] != nil {
			assert.Equal(suite.T(), float64(moderatorID), req["moderated_by"].(float64))
		}
	}
}

// ============================================================================
// Тесты хранимых процедур
// ============================================================================

// Test33_AcceptVolunteerResponse проверяет успешное принятие отклика волонтера
func (suite *APITestSuite) Test33_AcceptVolunteerResponse() {
	// Создаем заявку и одобряем её
	requestID := suite.createApprovedRequest(suite.accessToken)

	// Создаем волонтера и отклик
	volunteerID, responseID, _ := suite.createVolunteerWithResponse(requestID)

	// Принимаем отклик через процедуру
	url := fmt.Sprintf("/api/v1/requests/%d/responses/%d/accept", requestID, responseID)
	resp, body := suite.makeRequest("POST", url, nil, suite.accessToken)

	if resp.StatusCode != http.StatusOK {
		suite.T().Logf("Accept response failed. Status: %d, Body: %s", resp.StatusCode, string(body))
	}
	assert.Equal(suite.T(), http.StatusOK, resp.StatusCode)

	var result map[string]interface{}
	err := json.Unmarshal(body, &result)
	require.NoError(suite.T(), err)

	// Проверяем результат процедуры
	assert.True(suite.T(), result["success"].(bool))
	assert.Contains(suite.T(), result["message"].(string), "successfully")
	assert.Equal(suite.T(), float64(requestID), result["request_id"].(float64))
	assert.Equal(suite.T(), float64(volunteerID), result["volunteer_id"].(float64))

	// Проверяем, что заявка перешла в статус in_progress
	resp2, body2 := suite.makeRequest("GET", fmt.Sprintf("/api/v1/requests/%d", requestID), nil, suite.accessToken)
	assert.Equal(suite.T(), http.StatusOK, resp2.StatusCode)

	var request map[string]interface{}
	json.Unmarshal(body2, &request)
	statusObj := request["status"].(map[string]interface{})
	assert.Equal(suite.T(), "in_progress", statusObj["request_status"])
	assert.Equal(suite.T(), float64(volunteerID), request["assigned_volunteer_id"].(float64))

	// Проверяем историю статусов
	suite.checkRequestStatusHistory(requestID, []string{"approved", "in_progress"})
}

// Test34_AcceptVolunteerResponseValidation проверяет валидацию процедуры accept_volunteer_response
func (suite *APITestSuite) Test34_AcceptVolunteerResponseValidation() {
	// Создаем заявку от первого пользователя
	requestID := suite.createApprovedRequest(suite.accessToken)

	// Создаем волонтера с откликом
	_, responseID, _ := suite.createVolunteerWithResponse(requestID)

	// Создаем второго пользователя (не владелец заявки)
	email := fmt.Sprintf("other_user_%d@example.com", time.Now().UnixNano())
	registerReq := map[string]interface{}{
		"email":      email,
		"password":   "SecureP@ssw0rd123",
		"first_name": "Other",
		"last_name":  "User",
	}
	_, regBody := suite.makeRequest("POST", "/api/v1/auth/register", registerReq, "")
	var authResp map[string]interface{}
	json.Unmarshal(regBody, &authResp)
	otherUserToken := authResp["access_token"].(string)

	// Попытка принять отклик другим пользователем (не владельцем заявки)
	url := fmt.Sprintf("/api/v1/requests/%d/responses/%d/accept", requestID, responseID)
	resp, body := suite.makeRequest("POST", url, nil, otherUserToken)

	// Должна быть ошибка, так как пользователь не владелец заявки
	assert.Equal(suite.T(), http.StatusBadRequest, resp.StatusCode)

	var result map[string]interface{}
	json.Unmarshal(body, &result)

	// Процедура возвращает success: false
	if result["success"] != nil {
		assert.False(suite.T(), result["success"].(bool))
		assert.Contains(suite.T(), result["message"].(string), "not the owner")
	} else {
		// Или ошибка от обработчика
		assert.Contains(suite.T(), result["error"].(string), "owner")
	}
}

// Test35_CompleteRequestWithRating проверяет успешное завершение заявки с рейтингом
func (suite *APITestSuite) Test35_CompleteRequestWithRating() {
	// Создаем заявку, одобряем, принимаем отклик волонтера
	requestID := suite.createApprovedRequest(suite.accessToken)
	volunteerID, responseID, _ := suite.createVolunteerWithResponse(requestID)

	// Принимаем отклик
	acceptURL := fmt.Sprintf("/api/v1/requests/%d/responses/%d/accept", requestID, responseID)
	suite.makeRequest("POST", acceptURL, nil, suite.accessToken)

	// Завершаем заявку с рейтингом
	completeReq := map[string]interface{}{
		"rating":  5,
		"comment": "Отличная работа!",
	}
	completeURL := fmt.Sprintf("/api/v1/requests/%d/complete", requestID)
	resp, body := suite.makeRequest("POST", completeURL, completeReq, suite.accessToken)

	assert.Equal(suite.T(), http.StatusOK, resp.StatusCode)

	var result map[string]interface{}
	err := json.Unmarshal(body, &result)
	require.NoError(suite.T(), err)

	// Проверяем результат процедуры
	assert.True(suite.T(), result["success"].(bool))
	assert.Contains(suite.T(), result["message"].(string), "successfully")
	assert.NotNil(suite.T(), result["rating_id"])

	// Проверяем, что заявка завершена
	resp2, body2 := suite.makeRequest("GET", fmt.Sprintf("/api/v1/requests/%d", requestID), nil, suite.accessToken)
	assert.Equal(suite.T(), http.StatusOK, resp2.StatusCode)

	var request map[string]interface{}
	json.Unmarshal(body2, &request)
	statusObj := request["status"].(map[string]interface{})
	assert.Equal(suite.T(), "completed", statusObj["request_status"])

	// completed_at может быть null, если поле не заполнилось
	if request["completed_at"] == nil {
		suite.T().Logf("Request response: %s", string(body2))
	}
	assert.NotNil(suite.T(), request["completed_at"])

	// Проверяем, что рейтинг создан
	ratingID := int64(result["rating_id"].(float64))
	rating, err := suite.queries.GetRatingByResponseID(context.Background(), responseID)
	require.NoError(suite.T(), err)
	assert.Equal(suite.T(), ratingID, rating.ID)
	assert.Equal(suite.T(), int32(5), rating.Rating)
	assert.Equal(suite.T(), volunteerID, rating.VolunteerID)

	// Проверяем историю статусов
	suite.checkRequestStatusHistory(requestID, []string{"approved", "in_progress", "completed"})
}

// Test36_CompleteRequestWithRatingValidation проверяет валидацию рейтинга
func (suite *APITestSuite) Test36_CompleteRequestWithRatingValidation() {
	// Создаем заявку в статусе in_progress
	requestID := suite.createApprovedRequest(suite.accessToken)
	_, responseID, _ := suite.createVolunteerWithResponse(requestID)

	acceptURL := fmt.Sprintf("/api/v1/requests/%d/responses/%d/accept", requestID, responseID)
	suite.makeRequest("POST", acceptURL, nil, suite.accessToken)

	// Попытка завершить с неправильным рейтингом (вне диапазона 1-5)
	completeReq := map[string]interface{}{
		"rating": 10, // Неверный рейтинг
	}
	completeURL := fmt.Sprintf("/api/v1/requests/%d/complete", requestID)
	resp, body := suite.makeRequest("POST", completeURL, completeReq, suite.accessToken)

	assert.Equal(suite.T(), http.StatusBadRequest, resp.StatusCode)

	var errorResp map[string]interface{}
	json.Unmarshal(body, &errorResp)
	assert.Contains(suite.T(), errorResp["error"].(string), "between 1 and 5")

	// Попытка с рейтингом 0
	completeReq2 := map[string]interface{}{
		"rating": 0,
	}
	resp2, body2 := suite.makeRequest("POST", completeURL, completeReq2, suite.accessToken)

	assert.Equal(suite.T(), http.StatusBadRequest, resp2.StatusCode)

	var errorResp2 map[string]interface{}
	json.Unmarshal(body2, &errorResp2)
	assert.Contains(suite.T(), errorResp2["error"].(string), "between 1 and 5")
}

// Test37_CompleteRequestNotInProgress проверяет, что нельзя завершить заявку не в статусе in_progress
func (suite *APITestSuite) Test37_CompleteRequestNotInProgress() {
	// Создаем заявку (будет в статусе pending_moderation)
	_, body := suite.makeRequest("GET", "/api/v1/request-types", nil, "")
	var types []map[string]interface{}
	json.Unmarshal(body, &types)
	requestTypeID := int64(types[0]["id"].(float64))

	createReq := map[string]interface{}{
		"request_type_id": requestTypeID,
		"title":           "Request to complete",
		"description":     "Test",
		"latitude":        55.751244,
		"longitude":       37.618423,
		"address":         "Test",
	}
	_, respBody := suite.makeRequest("POST", "/api/v1/requests", createReq, suite.accessToken)
	var request map[string]interface{}
	json.Unmarshal(respBody, &request)
	requestID := int64(request["id"].(float64))

	// Попытка завершить заявку в статусе pending_moderation
	completeReq := map[string]interface{}{
		"rating": 5,
	}
	completeURL := fmt.Sprintf("/api/v1/requests/%d/complete", requestID)
	resp, body := suite.makeRequest("POST", completeURL, completeReq, suite.accessToken)

	// Процедура должна вернуть ошибку
	assert.Equal(suite.T(), http.StatusBadRequest, resp.StatusCode)

	var result map[string]interface{}
	json.Unmarshal(body, &result)

	// Хранимая процедура возвращает success: false, которое обработчик преобразует в error
	if result["error"] != nil {
		// Проверяем сообщение об ошибке содержит информацию о статусе
		assert.Contains(suite.T(), result["error"].(string), "in_progress")
	} else {
		suite.T().Logf("Response: %s", string(body))
		suite.T().Fatal("Expected error in response")
	}
}
