using System.Collections.Immutable;
using Penumbra.Api.Enums;

namespace LightlessSync.Services.TextureCompression;

internal static class TextureCompressionCapabilities
{
    private static readonly ImmutableDictionary<TextureCompressionTarget, TextureType> TexTargets =
        new Dictionary<TextureCompressionTarget, TextureType>
        {
            [TextureCompressionTarget.BC1] = TextureType.Bc1Tex,
            [TextureCompressionTarget.BC3] = TextureType.Bc3Tex,
            [TextureCompressionTarget.BC4] = TextureType.Bc4Tex,
            [TextureCompressionTarget.BC5] = TextureType.Bc5Tex,
            [TextureCompressionTarget.BC7] = TextureType.Bc7Tex,
        }.ToImmutableDictionary();

    private static readonly ImmutableDictionary<TextureCompressionTarget, TextureType> DdsTargets =
        new Dictionary<TextureCompressionTarget, TextureType>
        {
            [TextureCompressionTarget.BC1] = TextureType.Bc1Dds,
            [TextureCompressionTarget.BC3] = TextureType.Bc3Dds,
            [TextureCompressionTarget.BC4] = TextureType.Bc4Dds,
            [TextureCompressionTarget.BC5] = TextureType.Bc5Dds,
            [TextureCompressionTarget.BC7] = TextureType.Bc7Dds,
        }.ToImmutableDictionary();

    private static readonly TextureCompressionTarget[] SelectableTargetsCache = TexTargets
        .Select(kvp => kvp.Key)
        .OrderBy(t => t)
        .ToArray();

    private static readonly HashSet<TextureCompressionTarget> SelectableTargetSet = SelectableTargetsCache.ToHashSet();

    public static IReadOnlyList<TextureCompressionTarget> SelectableTargets => SelectableTargetsCache;

    public static TextureCompressionTarget DefaultTarget => TextureCompressionTarget.BC7;

    public static bool IsSelectable(TextureCompressionTarget target) => SelectableTargetSet.Contains(target);

    public static TextureCompressionTarget Normalize(TextureCompressionTarget? desired)
    {
        if (desired.HasValue && IsSelectable(desired.Value))
        {
            return desired.Value;
        }

        return DefaultTarget;
    }

    public static bool TryGetPenumbraTarget(TextureCompressionTarget target, string? outputPath, out TextureType textureType)
    {
        if (!string.IsNullOrWhiteSpace(outputPath) &&
            string.Equals(Path.GetExtension(outputPath), ".dds", StringComparison.OrdinalIgnoreCase))
        {
            return DdsTargets.TryGetValue(target, out textureType);
        }

        return TexTargets.TryGetValue(target, out textureType);
    }
}
