//go:build test

package admin

import (
	"bytes"
	"context"
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"strings"

	"crussell/mw"

	"github.com/go-chi/chi/v5"
)

// makeAdminRequest creates a request with admin context
// Note: Using 12-char IDs to match CHAR(12) columns in schema (e.g., created_by)
func makeAdminRequest(handler http.Handler, method, path string, body interface{}, ctx context.Context) *httptest.ResponseRecorder {
	return makeRequestWithContext(handler, method, path, body, "admin001", "admin", ctx)
}

// makeUserRequest creates a request with regular user context
// Note: Using 12-char IDs to match CHAR(12) columns in schema (e.g., created_by)
func makeUserRequest(handler http.Handler, method, path string, body interface{}, ctx context.Context) *httptest.ResponseRecorder {
	return makeRequestWithContext(handler, method, path, body, "user001", "verified_email", ctx)
}

// makeRequestWithContext creates a request with specific user context

func makeRequestWithContext(handler http.Handler, method, path string, body interface{}, userID, role string, ctx context.Context) *httptest.ResponseRecorder {
	var req *http.Request
	if body != nil {
		bodyBytes, _ := json.Marshal(body)
		req = httptest.NewRequest(method, path, bytes.NewReader(bodyBytes))
		req.Header.Set("Content-Type", "application/json")
	} else {
		req = httptest.NewRequest(method, path, nil)
	}

	rctx := chi.NewRouteContext()
	if method == "GET" || method == "PUT" || method == "POST" || method == "DELETE" || method == "PATCH" {
		if id, paramName := extractIDFromPath(path); id != "" {
			rctx.URLParams.Add(paramName, id)
		}
		// Extract request_id for: /api/admin/bookings/{id}/edit-requests/{request_id}/approve
		if parts := strings.Split(path, "/"); len(parts) >= 8 && parts[5] == "edit-requests" {
			rctx.URLParams.Add("request_id", parts[6])
		}
	}

	ctx = context.WithValue(ctx, chi.RouteCtxKey, rctx)
	ctx = context.WithValue(ctx, mw.UserIDKey, userID)
	ctx = context.WithValue(ctx, mw.UserRoleKey, role)
	req = req.WithContext(ctx)

	w := httptest.NewRecorder()
	handler.ServeHTTP(w, req)
	return w
}

func extractIDFromPath(path string) (string, string) {
	patterns := []struct {
		prefix    string
		paramName string
	}{
		{"/api/admin/bookings/user/", "user_id"},
		{"/api/admin/users/", "id"},
		{"/api/admin/bookings/", "id"},
		{"/api/admin/services/", "id"},
		{"/api/admin/patch-tests/", "id"},
		{"/api/bookings/", "id"},
		{"/api/services/eligible-for/", "userId"},
		{"/api/services/", "id"},
	}

	for _, p := range patterns {
		if strings.HasPrefix(path, p.prefix) {
			suffix := path[len(p.prefix):]
			if slashIdx := strings.Index(suffix, "/"); slashIdx >= 0 {
				return suffix[:slashIdx], p.paramName
			}
			return suffix, p.paramName
		}
	}
	return "", ""
}

func parseResponseBody(w *httptest.ResponseRecorder, dest interface{}) error {
	return json.Unmarshal(w.Body.Bytes(), dest)
}
