using System.Diagnostics.CodeAnalysis;

namespace NeonSprawl.Server.Game.Combat;

/// <summary>Adapter over <see cref="AbilityDefinitionCatalog"/> (NEO-79).</summary>
public sealed class AbilityDefinitionRegistry(AbilityDefinitionCatalog catalog) : IAbilityDefinitionRegistry
{
    private readonly IReadOnlyList<AbilityDefRow> _definitionsInIdOrder = BuildDefinitionsInIdOrder(catalog);

    /// <inheritdoc />
    public bool TryGetDefinition(string? abilityId, [NotNullWhen(true)] out AbilityDefRow? definition)
    {
        if (abilityId is null)
        {
            definition = null;
            return false;
        }

        return catalog.TryGetAbility(abilityId, out definition);
    }

    /// <inheritdoc />
    public bool TryNormalizeKnown(string? rawAbilityId, [NotNullWhen(true)] out string normalized)
    {
        if (rawAbilityId is null)
        {
            normalized = string.Empty;
            return false;
        }

        normalized = rawAbilityId.Trim().ToLowerInvariant();
        if (normalized.Length == 0)
        {
            normalized = string.Empty;
            return false;
        }

        return catalog.TryGetAbility(normalized, out _);
    }

    /// <inheritdoc />
    public IReadOnlyList<AbilityDefRow> GetDefinitionsInIdOrder() => _definitionsInIdOrder;

    private static IReadOnlyList<AbilityDefRow> BuildDefinitionsInIdOrder(AbilityDefinitionCatalog catalog)
    {
        var ids = catalog.ById.Keys.OrderBy(k => k, StringComparer.Ordinal).ToArray();
        var list = new List<AbilityDefRow>(ids.Length);
        foreach (var id in ids)
        {
            list.Add(catalog.ById[id]);
        }

        return list;
    }
}
