package test

import (
	"context"
	"testing"

	"github.com/stretchr/testify/require"

	apiv1 "github.com/usememos/memos/proto/gen/api/v1"
)

func TestUserResourceName(t *testing.T) {
	ctx := context.Background()

	t.Run("GetUser returns username-based canonical name", func(t *testing.T) {
		ts := NewTestService(t)
		defer ts.Cleanup()

		user, err := ts.CreateRegularUser(ctx, "testuser")
		require.NoError(t, err)

		got, err := ts.Service.GetUser(ctx, &apiv1.GetUserRequest{
			Name: "users/testuser",
		})
		require.NoError(t, err)
		require.NotNil(t, got)
		require.Equal(t, "users/testuser", got.Name)
		require.Equal(t, user.Username, got.Username)
	})

	t.Run("CreateUser returns username-based canonical name", func(t *testing.T) {
		ts := NewTestService(t)
		defer ts.Cleanup()

		created, err := ts.Service.CreateUser(ctx, &apiv1.CreateUserRequest{
			User: &apiv1.User{
				Username: "newuser",
				Email:    "newuser@example.com",
				Password: "password123",
			},
		})
		require.NoError(t, err)
		require.NotNil(t, created)
		require.Equal(t, "users/newuser", created.Name)
	})

	t.Run("Mixed-case username remains usable after auth", func(t *testing.T) {
		ts := NewTestService(t)
		defer ts.Cleanup()

		user, err := ts.CreateRegularUser(ctx, "Gnammi")
		require.NoError(t, err)

		userCtx := ts.CreateUserContext(ctx, user.ID)
		currentUser, err := ts.Service.GetCurrentUser(userCtx, &apiv1.GetCurrentUserRequest{})
		require.NoError(t, err)
		require.NotNil(t, currentUser.GetUser())
		require.Equal(t, "users/Gnammi", currentUser.GetUser().Name)

		settings, err := ts.Service.ListUserSettings(userCtx, &apiv1.ListUserSettingsRequest{
			Parent: currentUser.GetUser().Name,
		})
		require.NoError(t, err)
		require.NotNil(t, settings)

		shortcuts, err := ts.Service.ListShortcuts(userCtx, &apiv1.ListShortcutsRequest{
			Parent: currentUser.GetUser().Name,
		})
		require.NoError(t, err)
		require.NotNil(t, shortcuts)
	})

	t.Run("BatchGetUsers preserves mixed-case usernames", func(t *testing.T) {
		ts := NewTestService(t)
		defer ts.Cleanup()

		user, err := ts.CreateRegularUser(ctx, "Gnammi")
		require.NoError(t, err)

		resp, err := ts.Service.BatchGetUsers(ctx, &apiv1.BatchGetUsersRequest{
			Usernames: []string{user.Username},
		})
		require.NoError(t, err)
		require.Len(t, resp.Users, 1)
		require.Equal(t, "users/Gnammi", resp.Users[0].Name)
	})

	t.Run("CreateUser rejects all-numeric usernames", func(t *testing.T) {
		ts := NewTestService(t)
		defer ts.Cleanup()

		_, err := ts.Service.CreateUser(ctx, &apiv1.CreateUserRequest{
			User: &apiv1.User{
				Username: "123",
				Email:    "123@example.com",
				Password: "password123",
			},
		})
		require.Error(t, err)
		require.Contains(t, err.Error(), "invalid username")
	})

	t.Run("GetUser rejects numeric user resource names", func(t *testing.T) {
		ts := NewTestService(t)
		defer ts.Cleanup()

		_, err := ts.CreateRegularUser(ctx, "testuser")
		require.NoError(t, err)

		_, err = ts.Service.GetUser(ctx, &apiv1.GetUserRequest{
			Name: "users/1",
		})
		require.Error(t, err)
		require.Contains(t, err.Error(), "invalid user name")
	})
}
