using JSMR.Domain.Enums;
using System.Diagnostics.CodeAnalysis;

namespace JSMR.Domain.ValueObjects;

public sealed record SupportedLanguage(string Code, Language Language)
{
    public static readonly SupportedLanguage Japanese = new("JPN", Language.Japanese);
    public static readonly SupportedLanguage English = new("ENG", Language.English);
    public static readonly SupportedLanguage ChineseSimplified = new("CHI_HANS", Language.ChineseSimplified);
    public static readonly SupportedLanguage ChineseTraditional = new("CHI_HANT", Language.ChineseTraditional);
    public static readonly SupportedLanguage Korean = new("KO_KR", Language.Korean);
    public static readonly SupportedLanguage Alingual = new("NM", Language.Unknown);

    public static IReadOnlyList<SupportedLanguage> All =>
    [
        Japanese,
        English,
        ChineseSimplified,
        ChineseTraditional,
        Korean,
        Alingual
    ];

    private static readonly Dictionary<string, SupportedLanguage> _byCode =
        All.ToDictionary(x => x.Code, StringComparer.OrdinalIgnoreCase);

    private static readonly Dictionary<Language, SupportedLanguage> _byLang =
        All.ToDictionary(x => x.Language);

    public static bool TryFromCode(string code, [MaybeNullWhen(false)] out SupportedLanguage supportedLanguage) =>
        _byCode.TryGetValue(code, out supportedLanguage);

    public static bool TryFromLanguage(Language language, [MaybeNullWhen(false)] out SupportedLanguage supportedLanguage) =>
        _byLang.TryGetValue(language, out supportedLanguage);

    public static SupportedLanguage FromLanguage(Language language) =>
        _byLang.TryGetValue(language, out SupportedLanguage? supportedLanguage)
            ? supportedLanguage
            : throw new ArgumentOutOfRangeException(nameof(language), $"Unsupported: {language}");
}