package echohelpers

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

	"github.com/labstack/echo/v4"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

func TestDefaultQuery(t *testing.T) {
	tests := []struct {
		name         string
		query        string
		key          string
		defaultValue string
		expected     string
	}{
		{"returns value when present", "/?status=active", "status", "all", "active"},
		{"returns default when absent", "/", "status", "all", "all"},
		{"returns default for empty value", "/?status=", "status", "all", "all"},
	}

	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			e := echo.New()
			req := httptest.NewRequest(http.MethodGet, tc.query, nil)
			rec := httptest.NewRecorder()
			c := e.NewContext(req, rec)

			result := DefaultQuery(c, tc.key, tc.defaultValue)
			assert.Equal(t, tc.expected, result)
		})
	}
}

func TestParseUintParam(t *testing.T) {
	tests := []struct {
		name        string
		paramValue  string
		expected    uint
		expectError bool
	}{
		{"valid uint", "42", 42, false},
		{"zero", "0", 0, false},
		{"invalid string", "abc", 0, true},
		{"negative", "-1", 0, true},
		{"empty", "", 0, true},
	}

	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			e := echo.New()
			req := httptest.NewRequest(http.MethodGet, "/", nil)
			rec := httptest.NewRecorder()
			c := e.NewContext(req, rec)
			c.SetParamNames("id")
			c.SetParamValues(tc.paramValue)

			result, err := ParseUintParam(c, "id")
			if tc.expectError {
				require.Error(t, err)
			} else {
				require.NoError(t, err)
				assert.Equal(t, tc.expected, result)
			}
		})
	}
}

func TestParseIntParam(t *testing.T) {
	tests := []struct {
		name        string
		paramValue  string
		expected    int
		expectError bool
	}{
		{"valid int", "42", 42, false},
		{"zero", "0", 0, false},
		{"negative", "-5", -5, false},
		{"invalid string", "abc", 0, true},
		{"empty", "", 0, true},
	}

	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			e := echo.New()
			req := httptest.NewRequest(http.MethodGet, "/", nil)
			rec := httptest.NewRecorder()
			c := e.NewContext(req, rec)
			c.SetParamNames("id")
			c.SetParamValues(tc.paramValue)

			result, err := ParseIntParam(c, "id")
			if tc.expectError {
				require.Error(t, err)
			} else {
				require.NoError(t, err)
				assert.Equal(t, tc.expected, result)
			}
		})
	}
}
