using MiGu.Server.Auth;

namespace MiGu.Server.Dashboard;

/// <summary>
/// Dashboard 快捷入口 key 白名单。key 与前端 <c>quickEntries.ts</c> 对齐；
/// <see cref="PageKey"/> 用于 RBAC 校验（用户须有权访问对应页面）。
/// </summary>
public sealed record ShortcutDef(string Key, string PageKey, string Scope);

public static class DashboardShortcutCatalog
{
    /// <summary>旧版快捷 key（别名）→ 菜单 key。保存时归一化，避免与菜单项重复。</summary>
    private static readonly Dictionary<string, string> LegacyKeyAliases =
        new(StringComparer.OrdinalIgnoreCase)
        {
            ["platform-config"] = "admin-map-editor",
            ["mission"] = "admin-task-templates",
            ["cars"] = "admin-cars",
            ["auth"] = "admin-config-system-center",
            ["system"] = "admin-config-system-center",
            ["ops"] = "admin-config-ops-center",
            ["tasks"] = "admin-config-strategy",
        };

    private static readonly ShortcutDef[] PlatformShortcuts =
    [
        new("admin-dashboard", "admin-dashboard", PageCatalog.ScopePlatform),
        new("admin-map-monitor", "admin-map-monitor", PageCatalog.ScopePlatform),
        new("admin-maps", "admin-maps", PageCatalog.ScopePlatform),
        new("admin-map-editor", "admin-map-editor", PageCatalog.ScopePlatform),
        new("admin-project-properties", "admin-project-properties", PageCatalog.ScopePlatform),
        new("admin-tracks", "admin-tracks", PageCatalog.ScopePlatform),
        new("admin-cars", "admin-cars", PageCatalog.ScopePlatform),
        new("admin-processes", "admin-processes", PageCatalog.ScopePlatform),
        new("admin-scripts", "admin-scripts", PageCatalog.ScopePlatform),
        new("admin-task-templates", "admin-task-templates", PageCatalog.ScopePlatform),
        new("admin-simple-fields", "admin-simple-fields", PageCatalog.ScopePlatform),
        new("admin-config-strategy", "admin-config-strategy", PageCatalog.ScopePlatform),
        new("admin-vehicle-hub", "admin-vehicle-hub", PageCatalog.ScopePlatform),
        new("admin-config-facility", "admin-config-facility", PageCatalog.ScopePlatform),
        new("admin-config-business", "admin-config-business", PageCatalog.ScopePlatform),
        new("admin-config-ops-center", "admin-config-ops-center", PageCatalog.ScopePlatform),
        new("admin-config-system-center", "admin-config-system-center", PageCatalog.ScopePlatform),
    ];

    private static readonly ShortcutDef[] MonitorShortcuts =
    [
        new("monitor-dashboard", "monitor-dashboard", PageCatalog.ScopeMonitor),
        new("monitor-vehicle-hub", "monitor-vehicle-hub", PageCatalog.ScopeMonitor),
        new("monitor-map", "monitor-map", PageCatalog.ScopeMonitor),
        new("monitor-ops", "monitor-ops", PageCatalog.ScopeMonitor),
        new("monitor-notes", "monitor-notes", PageCatalog.ScopeMonitor),
    ];

    private static readonly Dictionary<string, ShortcutDef> ByKey =
        PlatformShortcuts.Concat(MonitorShortcuts)
            .ToDictionary(s => s.Key, s => s, StringComparer.OrdinalIgnoreCase);

    public static readonly int MaxKeysPerUser = 16;

    /// <summary>Platform 域固定保留、不可删除的快捷入口。</summary>
    public static readonly IReadOnlyList<string> MandatoryPlatformKeys =
    [
        "admin-maps",
        "admin-map-editor",
        "admin-cars",
        "admin-map-monitor",
        "admin-vehicle-hub",
        "admin-task-templates"
    ];

    public static readonly IReadOnlyList<string> DefaultPlatformKeys =
    [
        "admin-maps",
        "admin-map-editor",
        "admin-cars",
        "admin-map-monitor",
        "admin-vehicle-hub",
        "admin-task-templates",
        "admin-config-system-center",
        "admin-config-ops-center",
        "admin-config-strategy"
    ];

    public static readonly IReadOnlyList<string> DefaultMonitorKeys =
        ["monitor-vehicle-hub", "monitor-map", "monitor-ops"];

    private static readonly HashSet<string> ExcludedKeys =
        new(StringComparer.OrdinalIgnoreCase) { "admin-dashboard", "monitor-dashboard" };

    public static bool IsValidKey(string key) =>
        !ExcludedKeys.Contains(key) && ByKey.ContainsKey(key);

    public static ShortcutDef? TryGet(string key) =>
        ByKey.TryGetValue(key, out var def) ? def : null;

    public static IReadOnlyList<string> DefaultKeysForScope(string scope) =>
        string.Equals(scope, PageCatalog.ScopeMonitor, StringComparison.OrdinalIgnoreCase)
            ? DefaultMonitorKeys
            : DefaultPlatformKeys;

    public static bool KeyMatchesScope(string key, string scope)
    {
        var def = TryGet(key);
        return def != null && string.Equals(def.Scope, scope, StringComparison.OrdinalIgnoreCase);
    }

    public static string PageKeyFor(string key) => TryGet(NormalizeKey(key))?.PageKey ?? NormalizeKey(key);

    public static string NormalizeKey(string key) =>
        LegacyKeyAliases.TryGetValue(key.Trim(), out var canon) ? canon : key.Trim();

    public static bool IsMandatoryKey(string key, string scope) =>
        string.Equals(scope, PageCatalog.ScopePlatform, StringComparison.OrdinalIgnoreCase)
        && MandatoryPlatformKeys.Contains(NormalizeKey(key), StringComparer.OrdinalIgnoreCase);
}
