package useridinput

import (
	"context"
	"testing"

	userv1 "hyapp.local/api/proto/user/v1"
	"hyapp/pkg/xerr"
)

type fakeDisplayResolver struct {
	userID int64
	err    error
	last   *userv1.ResolveDisplayUserIDRequest
}

func (f *fakeDisplayResolver) ResolveDisplayUserID(_ context.Context, req *userv1.ResolveDisplayUserIDRequest) (*userv1.ResolveDisplayUserIDResponse, error) {
	f.last = req
	if f.err != nil {
		return nil, f.err
	}
	return &userv1.ResolveDisplayUserIDResponse{Identity: &userv1.UserIdentity{
		UserId:        f.userID,
		DisplayUserId: req.GetDisplayUserId(),
		Status:        "active",
		AppCode:       req.GetMeta().GetAppCode(),
	}}, nil
}

func TestResolvePrefersActiveDisplayIDBeforeNumericUserID(t *testing.T) {
	resolver := &fakeDisplayResolver{userID: 900001}
	userID, err := Resolve(context.Background(), resolver, &userv1.RequestMeta{AppCode: "lalu"}, "123456")
	if err != nil {
		t.Fatalf("Resolve failed: %v", err)
	}
	if userID != 900001 {
		t.Fatalf("active display id should win over numeric fallback, got %d", userID)
	}
	if resolver.last == nil || resolver.last.GetDisplayUserId() != "123456" {
		t.Fatalf("display resolver was not called first: %+v", resolver.last)
	}
}

func TestResolveFallsBackToNumericUserIDWhenDisplayIDNotFound(t *testing.T) {
	resolver := &fakeDisplayResolver{err: xerr.New(xerr.DisplayUserIDNotFound, "not found")}
	userID, err := Resolve(context.Background(), resolver, &userv1.RequestMeta{AppCode: "lalu"}, "123456")
	if err != nil {
		t.Fatalf("Resolve failed: %v", err)
	}
	if userID != 123456 {
		t.Fatalf("numeric user id fallback mismatch: got %d", userID)
	}
}

func TestResolveKeepsPrettyDisplayIDOnDisplayResolver(t *testing.T) {
	resolver := &fakeDisplayResolver{userID: 123456}
	userID, err := Resolve(context.Background(), resolver, &userv1.RequestMeta{AppCode: "lalu"}, "1111cc1111")
	if err != nil {
		t.Fatalf("Resolve failed: %v", err)
	}
	if userID != 123456 {
		t.Fatalf("pretty display id resolve mismatch: got %d", userID)
	}
	if resolver.last == nil || resolver.last.GetDisplayUserId() != "1111cc1111" {
		t.Fatalf("pretty display id was not passed through: %+v", resolver.last)
	}
}

func TestResolveDoesNotHideNonNotFoundErrors(t *testing.T) {
	resolver := &fakeDisplayResolver{err: xerr.New(xerr.Unavailable, "user-service unavailable")}
	if _, err := Resolve(context.Background(), resolver, &userv1.RequestMeta{AppCode: "lalu"}, "123456"); !xerr.IsCode(err, xerr.Unavailable) {
		t.Fatalf("non-not-found error should pass through, got %v", err)
	}
}
