using NexusShell.Models;

namespace NexusShell.Services;

public static class NexusFileAssociations
{
    private static readonly IReadOnlyList<NexusDefaultAppCategory> Categories =
    [
        new()
        {
            Id = "images",
            Label = "Billeder",
            ExtensionsLabel = ".jpg, .jpeg, .png, .webp, .gif, .bmp",
            Extensions = [".jpg", ".jpeg", ".png", ".webp", ".gif", ".bmp"],
            DefaultApp = NexusDefaultAppId.Photos,
        },
        new()
        {
            Id = "video",
            Label = "Video",
            ExtensionsLabel = ".mp4, .mkv, .avi, .webm, .mov",
            Extensions = [".mp4", ".mkv", ".avi", ".webm", ".mov"],
            DefaultApp = NexusDefaultAppId.Media,
        },
        new()
        {
            Id = "audio",
            Label = "Musik",
            ExtensionsLabel = ".mp3, .wav, .flac, .aac, .ogg",
            Extensions = [".mp3", ".wav", ".flac", ".aac", ".ogg"],
            DefaultApp = NexusDefaultAppId.Media,
        },
        new()
        {
            Id = "documents",
            Label = "Dokumenter",
            ExtensionsLabel = ".pdf",
            Extensions = [".pdf"],
            DefaultApp = NexusDefaultAppId.FilesPreview,
        },
        new()
        {
            Id = "text",
            Label = "Tekst",
            ExtensionsLabel = ".txt, .md, .log, .csv",
            Extensions = [".txt", ".md", ".log", ".csv"],
            DefaultApp = NexusDefaultAppId.FilesPreview,
        },
    ];

    public static IReadOnlyList<NexusDefaultAppCategory> GetCategories() => Categories;

    public static IReadOnlyList<NexusDefaultAppOption> GetAvailableApps() =>
    [
        new() { AppId = NexusDefaultAppId.Photos, Label = "Nexus Photos", Description = "Billedfremviser" },
        new() { AppId = NexusDefaultAppId.Media, Label = "Nexus Media", Description = "Musik og video" },
        new() { AppId = NexusDefaultAppId.FilesPreview, Label = "Nexus Files", Description = "Forhåndsvisning i Files" },
        new() { AppId = NexusDefaultAppId.Browser, Label = "Nexus Browser", Description = "Webbrowser" },
    ];

    public static IReadOnlyList<NexusOpenWithChoice> GetOpenWithChoices() =>
    [
        new()
        {
            AppId = NexusDefaultAppId.Photos,
            Label = "Nexus Photos",
            Description = "Åbn som billede",
            IconPath = NexusLucideIcons.Image,
        },
        new()
        {
            AppId = NexusDefaultAppId.Media,
            Label = "Nexus Media",
            Description = "Afspil musik eller video",
            IconPath = NexusLucideIcons.Play,
        },
        new()
        {
            AppId = NexusDefaultAppId.FilesPreview,
            Label = "Nexus Files",
            Description = "Vis i Files-forhåndsvisning",
            IconPath = NexusLucideIcons.File,
        },
        new()
        {
            AppId = NexusDefaultAppId.Browser,
            Label = "Nexus Browser",
            Description = "Åbn i browser",
            IconPath = NexusLucideIcons.Globe,
        },
    ];

    public static NexusDefaultAppId GetBuiltInHandler(string extension)
    {
        var normalized = NormalizeExtension(extension);
        foreach (var category in Categories)
        {
            if (category.Extensions.Contains(normalized, StringComparer.OrdinalIgnoreCase))
            {
                return category.DefaultApp;
            }
        }

        return NexusDefaultAppId.FilesPreview;
    }

    public static string? GetCategoryIdForExtension(string extension)
    {
        var normalized = NormalizeExtension(extension);
        return Categories.FirstOrDefault(c =>
            c.Extensions.Contains(normalized, StringComparer.OrdinalIgnoreCase))?.Id;
    }

    public static string GetAppLabel(NexusDefaultAppId appId) => appId switch
    {
        NexusDefaultAppId.Photos => "Nexus Photos",
        NexusDefaultAppId.Media => "Nexus Media",
        NexusDefaultAppId.FilesPreview => "Nexus Files",
        NexusDefaultAppId.Browser => "Nexus Browser",
        _ => appId.ToString(),
    };

    private static string NormalizeExtension(string extension)
    {
        if (string.IsNullOrWhiteSpace(extension))
        {
            return string.Empty;
        }

        return extension.StartsWith('.') ? extension.ToLowerInvariant() : $".{extension.ToLowerInvariant()}";
    }
}
