package useridinput

import (
	"context"
	"strconv"
	"strings"

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

type DisplayResolver interface {
	ResolveDisplayUserID(ctx context.Context, req *userv1.ResolveDisplayUserIDRequest) (*userv1.ResolveDisplayUserIDResponse, error)
}

// Resolve 把 H5、后台、运营入口里用户手填的“用户标识”统一转换成服务内部 user_id。
// 解析顺序必须先查 active display_user_id：靓号、当前短号、数字短号都属于 display 体系，优先级高于纯数字 user_id。
// 只有 user-service 明确返回 DISPLAY_USER_ID_NOT_FOUND，或者旧 fake 返回空 identity 时，纯数字输入才回退成 user_id。
// 非 NOT_FOUND 错误不能被兜底吞掉，否则 user-service 抖动时会把请求错误地路由到同名数字 user_id。
func Resolve(ctx context.Context, resolver DisplayResolver, meta *userv1.RequestMeta, raw string) (int64, error) {
	input := strings.TrimSpace(raw)
	if input == "" {
		return 0, xerr.New(xerr.InvalidArgument, "user identifier is required")
	}
	if resolver == nil {
		return 0, xerr.New(xerr.Unavailable, "user identity resolver is not configured")
	}
	resp, err := resolver.ResolveDisplayUserID(ctx, &userv1.ResolveDisplayUserIDRequest{
		Meta:          meta,
		DisplayUserId: input,
	})
	if err == nil {
		if userID := resp.GetIdentity().GetUserId(); userID > 0 {
			return userID, nil
		}
		if userID, ok := numericUserID(input); ok {
			return userID, nil
		}
		return 0, xerr.New(xerr.DisplayUserIDNotFound, "not found")
	}
	if !xerr.IsCode(err, xerr.DisplayUserIDNotFound) {
		return 0, err
	}
	if userID, ok := numericUserID(input); ok {
		return userID, nil
	}
	return 0, err
}

func numericUserID(value string) (int64, bool) {
	userID, err := strconv.ParseInt(strings.TrimSpace(value), 10, 64)
	if err != nil || userID <= 0 {
		return 0, false
	}
	return userID, true
}
