package middleware

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

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

	"github.com/treytartt/honeydue-api/internal/models"
)

func TestStructuredLogger_Passes_Request(t *testing.T) {
	mw := StructuredLogger()
	e := echo.New()
	handler := mw(func(c echo.Context) error {
		return c.String(http.StatusOK, "ok")
	})

	req := httptest.NewRequest(http.MethodGet, "/api/test/", nil)
	rec := httptest.NewRecorder()
	c := e.NewContext(req, rec)

	err := handler(c)
	require.NoError(t, err)
	assert.Equal(t, http.StatusOK, rec.Code)
	assert.Equal(t, "ok", rec.Body.String())
}

func TestStructuredLogger_WithUser(t *testing.T) {
	mw := StructuredLogger()
	e := echo.New()

	user := &models.User{Username: "loguser"}
	user.ID = 42

	handler := mw(func(c echo.Context) error {
		return c.String(http.StatusOK, "ok")
	})

	req := httptest.NewRequest(http.MethodGet, "/api/test/", nil)
	rec := httptest.NewRecorder()
	c := e.NewContext(req, rec)
	c.Set(AuthUserKey, user)

	err := handler(c)
	require.NoError(t, err)
	assert.Equal(t, http.StatusOK, rec.Code)
}

func TestStructuredLogger_WithRequestID(t *testing.T) {
	mw := StructuredLogger()
	e := echo.New()

	handler := mw(func(c echo.Context) error {
		return c.String(http.StatusOK, "ok")
	})

	req := httptest.NewRequest(http.MethodGet, "/api/test/", nil)
	rec := httptest.NewRecorder()
	c := e.NewContext(req, rec)
	c.Set(ContextKeyRequestID, "test-request-id-123")

	err := handler(c)
	require.NoError(t, err)
	assert.Equal(t, http.StatusOK, rec.Code)
}

func TestStructuredLogger_ErrorStatus(t *testing.T) {
	mw := StructuredLogger()
	e := echo.New()

	handler := mw(func(c echo.Context) error {
		return c.String(http.StatusInternalServerError, "error")
	})

	req := httptest.NewRequest(http.MethodGet, "/api/test/", nil)
	rec := httptest.NewRecorder()
	c := e.NewContext(req, rec)

	err := handler(c)
	require.NoError(t, err)
	assert.Equal(t, http.StatusInternalServerError, rec.Code)
}

func TestStructuredLogger_ClientError(t *testing.T) {
	mw := StructuredLogger()
	e := echo.New()

	handler := mw(func(c echo.Context) error {
		return c.String(http.StatusBadRequest, "bad request")
	})

	req := httptest.NewRequest(http.MethodGet, "/api/test/", nil)
	rec := httptest.NewRecorder()
	c := e.NewContext(req, rec)

	err := handler(c)
	require.NoError(t, err)
	assert.Equal(t, http.StatusBadRequest, rec.Code)
}
