package errors

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestAppError_WithContext(t *testing.T) {
	err := New(ErrCodeValidation, "Invalid input")
	err.Context = map[string]interface{}{
		"request_id": "abc123",
		"user_id":    42,
	}

	assert.NotNil(t, err.Context)
	assert.Equal(t, "abc123", err.Context["request_id"])
	assert.Equal(t, 42, err.Context["user_id"])
}

func TestAppError_ContextNil(t *testing.T) {
	err := New(ErrCodeValidation, "Invalid input")
	assert.Nil(t, err.Context)
}

func TestAppError_ContextEmpty(t *testing.T) {
	err := New(ErrCodeValidation, "Invalid input")
	err.Context = make(map[string]interface{})
	assert.NotNil(t, err.Context)
	assert.Equal(t, 0, len(err.Context))
}

func TestAppError_ContextWithMultipleFields(t *testing.T) {
	err := New(ErrCodeInternal, "Internal error")
	err.Context = map[string]interface{}{
		"request_id": "req-123",
		"user_id":    int64(100),
		"ip_address": "192.168.1.1",
		"path":       "/api/test",
	}

	assert.Equal(t, "req-123", err.Context["request_id"])
	assert.Equal(t, int64(100), err.Context["user_id"])
	assert.Equal(t, "192.168.1.1", err.Context["ip_address"])
	assert.Equal(t, "/api/test", err.Context["path"])
}

func TestNewValidationError_Context(t *testing.T) {
	err := NewValidationError("Validation failed",
		ErrorDetail{Field: "email", Message: "Invalid format"},
	)

	// Context devrait être nil par défaut
	assert.Nil(t, err.Context)

	// Mais on peut l'ajouter après
	err.Context = map[string]interface{}{
		"request_id": "xyz789",
	}
	assert.Equal(t, "xyz789", err.Context["request_id"])
}

func TestNewNotFoundError_Context(t *testing.T) {
	err := NewNotFoundError("User")

	assert.Nil(t, err.Context)
	err.Context = map[string]interface{}{
		"resource_id": 123,
	}
	assert.Equal(t, 123, err.Context["resource_id"])
}

func TestWrap_Context(t *testing.T) {
	originalErr := New(ErrCodeInternal, "Original error")
	wrappedErr := Wrap(ErrCodeValidation, "Wrapped error", originalErr)

	assert.Nil(t, wrappedErr.Context)
	wrappedErr.Context = map[string]interface{}{
		"wrapped": true,
	}
	assert.Equal(t, true, wrappedErr.Context["wrapped"])
}
