using BoardApp.Config; namespace BoardApp.Services; public sealed class ScenarioService { private readonly BoardConfigLoader _cfg; public ScenarioService(BoardConfigLoader cfg) { _cfg = cfg; } public sealed record HomeScenario(string Id, string Name, string Image); public sealed record HomeCategory(string Id, string Name, List Scenarios); public enum ScenarioSource { System, User } public static string ToScenarioKey(ScenarioSource source, string scenarioId) => (source == ScenarioSource.System ? "s:" : "u:") + scenarioId; public sealed record ScenarioKeyParts(ScenarioSource Source, string ScenarioId); public static ScenarioKeyParts ParseScenarioKey(string input) { var raw = (input ?? "").Trim(); if (raw.StartsWith("s:")) return new ScenarioKeyParts(ScenarioSource.System, raw[2..]); if (raw.StartsWith("u:")) return new ScenarioKeyParts(ScenarioSource.User, raw[2..]); return new ScenarioKeyParts(ScenarioSource.System, raw); } private Dictionary PageMap() { var cfg = _cfg.LoadPagesConfig(); var map = new Dictionary(StringComparer.Ordinal); foreach (var p in cfg.Pages) { map[p.Id] = p; } return map; } public List LoadHomeCatalogForUser(string username) { var pagesById = PageMap(); var sys = _cfg.LoadSystemScenariosConfig(); var users = _cfg.LoadUserScenariosConfig(); users.Users.TryGetValue(username, out var u); var userScenarios = u?.Scenarios ?? new List(); var sysCats = sys.Categories.Select(c => new HomeCategory( c.Id, c.Name, (c.Scenarios ?? new List()) .Select(s => new HomeScenario(ToScenarioKey(ScenarioSource.System, s.Id), s.Name, s.Image)) .ToList() )).ToList(); var my = new HomeCategory( "my", "ζˆ‘ηš„εœΊζ™―", userScenarios.Select(s => { var img = s.Image; if (string.IsNullOrWhiteSpace(img)) { var first = s.Pages.FirstOrDefault(); if (first is not null && pagesById.TryGetValue(first.PageId, out var pd)) { img = pd.Image; } } return new HomeScenario(ToScenarioKey(ScenarioSource.User, s.Id), s.Name, img ?? ""); }).ToList() ); return my.Scenarios.Count > 0 ? new List { my }.Concat(sysCats).ToList() : sysCats; } public Dictionary BuildScenarioImageMapForUser(string username) { var map = new Dictionary(StringComparer.Ordinal); var cats = LoadHomeCatalogForUser(username); foreach (var c in cats) { foreach (var s in c.Scenarios) { map[s.Id] = s.Image; } } return map; } public sealed record ScenarioPage(string Id, string Title, string BoardUrl, int Staytime); public sealed record Scenario(string Id, string Name, string Image, List Pages); public sealed record ResolvedScenario(ScenarioSource Source, Scenario Scenario); private static List ExpandPages(IEnumerable refs, Dictionary pagesById) { var list = new List(); foreach (var r in refs) { if (r is null) continue; if (!pagesById.TryGetValue(r.PageId, out var def)) continue; list.Add(new ScenarioPage(def.Id, def.Title, def.BoardUrl, r.Staytime)); } return list; } public ResolvedScenario? ResolveScenarioForUser(string username, string scenarioKey) { var pagesById = PageMap(); var key = ParseScenarioKey(scenarioKey); if (key.Source == ScenarioSource.System) { var sys = _cfg.LoadSystemScenariosConfig(); foreach (var cat in sys.Categories) { foreach (var sc in cat.Scenarios) { if (!string.Equals(sc.Id, key.ScenarioId, StringComparison.Ordinal)) continue; var pages = ExpandPages(sc.Pages, pagesById); return new ResolvedScenario( ScenarioSource.System, new Scenario(ToScenarioKey(ScenarioSource.System, sc.Id), sc.Name, sc.Image, pages) ); } } return null; } var users = _cfg.LoadUserScenariosConfig(); if (!users.Users.TryGetValue(username, out var u)) return null; var mine = u.Scenarios ?? new List(); var usc = mine.FirstOrDefault(x => string.Equals(x.Id, key.ScenarioId, StringComparison.Ordinal)); if (usc is null) return null; var upages = ExpandPages(usc.Pages, pagesById); return new ResolvedScenario( ScenarioSource.User, new Scenario(ToScenarioKey(ScenarioSource.User, usc.Id), usc.Name, usc.Image, upages) ); } }