package user

import (
	"context"
	"strings"

	"hyapp/pkg/appcode"
	"hyapp/pkg/xerr"
	invitedomain "hyapp/services/user-service/internal/domain/invite"
	userdomain "hyapp/services/user-service/internal/domain/user"
)

// SearchInviteReferrer 通过邀请码搜索可绑定邀请人。
// 搜索结果只允许同 App、同国家、已完成资料且 active 的普通用户，避免 H5 枚举跨国家用户资料。
func (s *Service) SearchInviteReferrer(ctx context.Context, userID int64, inviteCode string) (userdomain.User, error) {
	inviteCode = invitedomain.NormalizeCode(inviteCode)
	if userID <= 0 {
		return userdomain.User{}, xerr.New(xerr.InvalidArgument, "user_id is required")
	}
	if !invitedomain.ValidCode(inviteCode) {
		// 对外搜索入口只接受合法邀请码；非法输入直接拒绝，不落入 NotFound 分支。
		return userdomain.User{}, xerr.New(xerr.InvalidInviteCode, "invalid invite code")
	}
	if s.userRepository == nil {
		return userdomain.User{}, xerr.New(xerr.Unavailable, "user repository is not configured")
	}

	current, err := s.userRepository.GetUser(ctx, userID)
	if err != nil {
		return userdomain.User{}, err
	}
	if !current.ProfileCompleted {
		// 当前账号未完成资料时没有稳定国家边界，不能用这个入口搜索邀请人。
		return userdomain.User{}, xerr.New(xerr.ProfileRequired, "profile required")
	}
	if current.Country == "" {
		return userdomain.User{}, xerr.New(xerr.InvalidArgument, "current user country is required")
	}

	inviter, err := s.userRepository.FindInviteReferrerByCode(ctx, appcode.FromContext(ctx), inviteCode)
	if err != nil {
		return userdomain.User{}, err
	}
	if err := validateInviteReferrerPair(current, inviter); err != nil {
		return userdomain.User{}, err
	}

	return s.refreshExpiredUser(ctx, inviter, "")
}

// BindInviteReferrer 原子绑定当前用户的邀请人。
// H5 只能传用户输入的邀请码；归属用户由 repository 在事务内重新解析并复核。
func (s *Service) BindInviteReferrer(ctx context.Context, userID int64, inviteCode string, requestID string) (userdomain.User, error) {
	inviteCode = invitedomain.NormalizeCode(inviteCode)
	if userID <= 0 {
		return userdomain.User{}, xerr.New(xerr.InvalidArgument, "user_id is required")
	}
	if !invitedomain.ValidCode(inviteCode) {
		return userdomain.User{}, xerr.New(xerr.InvalidInviteCode, "invalid invite code")
	}
	if s.userRepository == nil {
		return userdomain.User{}, xerr.New(xerr.Unavailable, "user repository is not configured")
	}

	return s.userRepository.BindInviteReferrer(ctx, userdomain.BindInviteReferrerCommand{
		AppCode:       appcode.FromContext(ctx),
		InvitedUserID: userID,
		InviteCode:    inviteCode,
		RequestID:     strings.TrimSpace(requestID),
		BoundAtMs:     s.now().UnixMilli(),
	})
}

func validateInviteReferrerPair(invited userdomain.User, inviter userdomain.User) error {
	if invited.UserID <= 0 || inviter.UserID <= 0 {
		return xerr.New(xerr.NotFound, "inviter not found")
	}
	if invited.UserID == inviter.UserID {
		// 自邀不进入邀请码解析，避免把当前用户自己的邀请码可用性暴露出去。
		return xerr.New(xerr.InvalidInviteCode, "invalid invite code")
	}
	if !inviter.ProfileCompleted || !inviter.CanLogin() {
		return xerr.New(xerr.NotFound, "inviter not found")
	}
	if invited.Country == "" || inviter.Country == "" || invited.Country != inviter.Country {
		// 产品要求只能搜索和绑定本国家邀请人；跨国家统一返回 not found，避免泄漏目标用户是否存在。
		return xerr.New(xerr.NotFound, "inviter not found")
	}
	return nil
}
