
// 








namespace SafeCampus.System;

/// <summary>
/// 通知事件总线
/// </summary>
public class NoticeEventSubscriber : IEventSubscriber, ISingleton
{
    private readonly ISimpleCacheService _simpleCacheService;

    private readonly IServiceScopeFactory _scopeFactory;
    private readonly SqlSugarScope _db;

    public NoticeEventSubscriber(ISimpleCacheService simpleCacheService, IServiceScopeFactory scopeFactory)
    {
        _db = DbContext.DB;
        _simpleCacheService = simpleCacheService;
        _scopeFactory = scopeFactory;
    }

    /// <summary>
    /// 通知用户下线事件
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    [EventSubscribe(EventSubscriberConst.USER_LOGIN_OUT)]
    public async Task UserLoginOut(EventHandlerExecutingContext context)
    {
        var loginEvent = (UserLoginOutEvent)context.Source.Payload;//获取参数
        //客户端ID列表
        var clientIds = new List<string>();
        //遍历token列表获取客户端ID列表
        loginEvent.TokenInfos.ForEach(it =>
        {
            clientIds.AddRange(it.ClientIds);
        });
    }

    /// <summary>
    /// 有新的消息
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    [EventSubscribe(EventSubscriberConst.NEW_MESSAGE)]
    public async Task NewMessage(EventHandlerExecutingContext context)
    {
        var newMessageEvent = (NewMessageEvent)context.Source.Payload;//获取参数

        var clientIds = new List<string>();
        //获取用户token列表
        var tokenInfos = _simpleCacheService.HashGet<List<TokenInfo>>(CacheConst.CACHE_USER_TOKEN, newMessageEvent.UserIds.ToArray());
        tokenInfos.ForEach(it =>
        {
            if (it != null)
            {
                it = it.Where(it => it.TokenTimeout > DateTime.Now).ToList();//去掉登录超时的
                //遍历token
                it.ForEach(it =>
                {
                    clientIds.AddRange(it.ClientIds);//添加到客户端ID列表
                });
            }
        });
    }

    /// <summary>
    /// 获取服务
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    private T GetService<T>() where T : class, new()
    {
        // 创建新的作用域
        using var scope = _scopeFactory.CreateScope();
        return scope.ServiceProvider.GetRequiredService<T>();
    }
}
