using System.Reflection;
using System.Text.RegularExpressions;
using ImGuiNET;

namespace Shoko;

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
class MediaTypeAttribute : Attribute
{
    public string MediaType;
    public MediaTypeAttribute(string type)
    {
        MediaType = type;
    }
}

class MediaHandler
{
    public ProtoHandler Content;
    public string Title;
    public MediaHandler()
    {

    }
    public MediaHandler(ProtoHandler content)
    {
        Content = content;
    }
    public virtual void Load()
    {
    }
    public virtual void Render()
    {
        Title = "Error";
        ImGui.Text("unknown media type: " + Content.MediaType);
    }
    public virtual void MenuBar()
    {
    }

    /// <summary>
    /// Get the appropriate media handler for the URL
    /// </summary>
    /// <param name="url"></param>
    /// <returns></returns>
    public static MediaHandler GetHandler(ProtoHandler content)
    {
        var types = Assembly.GetAssembly(typeof(MediaHandler)).GetTypes()
                        .Where(t => t.IsClass && !t.IsAbstract && t.IsSubclassOf(typeof(MediaHandler)));
        Type type;
        try
        {
            type = types.Where(t=>t.GetCustomAttributes<MediaTypeAttribute>().Any(x => x.MediaType == content.MediaType))
                    .Single();
        }
        catch
        {
            var rgx = new Regex("/.*");
            var mediatype = rgx.Replace(content.MediaType, "/*");
            type = types.Where(t=>t.GetCustomAttributes<MediaTypeAttribute>().Any(x => x.MediaType == mediatype))
                    .SingleOrDefault(typeof(MediaHandler));
        }
        return (MediaHandler)Activator.CreateInstance(type, content);
    }

    public static string[] SupportedMedia
    {
        get
        {
            return Assembly.GetAssembly(typeof(MediaHandler)).GetTypes()
                .Where(t => t.IsClass && !t.IsAbstract && t.IsSubclassOf(typeof(MediaHandler)))
                .SelectMany(t => t.GetCustomAttributes<MediaTypeAttribute>().Select(x => x.MediaType))
                .ToArray();
        }
    }
}