using Application.Abstractions.Cache;
using Application.Abstractions.Chat;
using Application.Abstractions.Data;
using Microsoft.EntityFrameworkCore;
namespace Application.Helpers;
///
/// ChatRoomConfig 로더 — Redis 캐시(60초 TTL) → MSSQL 폴백.
/// 오픈 판정: main 은 row 없어도 기본 오픈, 종목방은 row 존재 + IsActive 필요(단계 오픈 — d0 §5-④),
/// 레거시 channel:{sid} 룸은 항상 통과(기존 채널 채팅 동작 유지).
///
public static class ChatRoomConfigLoader
{
public sealed record RoomConfig(bool Exists, bool IsActive, short SlowModeSeconds, string? Notice);
private static readonly TimeSpan CacheTtl = TimeSpan.FromSeconds(60);
public static async Task GetAsync(ICacheService cache, IAppDbContext db, string roomKey, CancellationToken ct)
{
var cacheKey = CacheKeys.ChatRoomConfig(roomKey);
var cached = await cache.GetAsync(cacheKey);
if (cached is not null)
{
return cached;
}
var row = await db.ChatRoomConfig.AsNoTracking().Where(c => c.RoomKey == roomKey).Select(c => new { c.IsActive, c.SlowModeSeconds, c.Notice }).FirstOrDefaultAsync(ct);
var config = row is null
? new RoomConfig(false, false, 0, null)
: new RoomConfig(true, row.IsActive, row.SlowModeSeconds, row.Notice);
await cache.SetAsync(cacheKey, config, CacheTtl);
return config;
}
public static bool IsRoomOpen(string roomKey, RoomConfig config)
{
if (roomKey == ChatRoomKeys.Main)
{
return !config.Exists || config.IsActive;
}
if (ChatRoomKeys.IsStockRoom(roomKey))
{
return config.Exists && config.IsActive;
}
return true;
}
}