namespace WxAgent.Core; public sealed record UiAccountIdentity(string? WechatId, string? Nickname); public sealed record DatabaseAccountIdentity(string AccountId, string? WechatId, string? Nickname); public sealed record AccountMatch(string? AccountId, string Strategy, bool IsUnique) { public bool IsMatched => AccountId is not null && IsUnique; } public static class AccountBindingMatcher { public static AccountMatch Match(UiAccountIdentity ui, IReadOnlyList accounts) { ArgumentNullException.ThrowIfNull(ui); ArgumentNullException.ThrowIfNull(accounts); var wechatId = Normalize(ui.WechatId); if (wechatId is not null) { var matches = accounts.Where(a => string.Equals(Normalize(a.WechatId), wechatId, StringComparison.OrdinalIgnoreCase)).ToArray(); if (matches.Length == 1) return new AccountMatch(matches[0].AccountId, "wechatId", true); if (matches.Length > 1) return new AccountMatch(null, "wechatId", false); } var nickname = Normalize(ui.Nickname); if (nickname is null) return new AccountMatch(null, "none", false); var nicknameMatches = accounts.Where(a => string.Equals(Normalize(a.Nickname), nickname, StringComparison.Ordinal)).ToArray(); return nicknameMatches.Length == 1 ? new AccountMatch(nicknameMatches[0].AccountId, "nickname", true) : new AccountMatch(null, nicknameMatches.Length == 0 ? "none" : "nickname", false); } private static string? Normalize(string? value) => string.IsNullOrWhiteSpace(value) ? null : value.Trim(); }