using System.Text.Json;
using ImGuiNET;

namespace Shoko;

[MediaType("application/json")]
class JsonMediaHandler : MediaHandler
{
    JsonDocument document;
    MediaHandler fallback;
    public JsonMediaHandler(ProtoHandler content)
    {
        Content = content;
    }

    public override async Task Load()
    {
        Title = Content.URL.AbsolutePath;
        try
        {
            document = await Task.Run(()=>JsonDocument.Parse(Content.Content));
        }
        catch
        {
            Content.Content.Position = 0;
            Content.MediaType = "text/plain";
            fallback = GetHandler(Content);
            await fallback.Load();
        }
        OnLoaded();
    }

    public override void Render()
    {
        if(fallback is not null)
            fallback.Render();
        else
        {
            Gui.Table("json", 3, ()=>{
                ImGui.TableSetupColumn("Key");
                ImGui.TableSetupColumn("Type");
                ImGui.TableSetupColumn("Value");
                ImGui.TableHeadersRow();
                RenderNode("root", document.RootElement);
            });
        }
    }

    public override void MenuBar()
    {
        if(fallback is not null)
            fallback.MenuBar();
    }

    public void RenderNode(string name, JsonElement element)
    {
        ImGui.TableNextRow();
        ImGui.TableNextColumn();
        switch(element.ValueKind)
        {
            case JsonValueKind.Object: {
                var node = ImGui.TreeNode(name);
                ImGui.TableNextColumn();
                ImGui.TextUnformatted("Object");
                ImGui.TableNextColumn();
                ImGui.TextDisabled("--");
                if(node)
                {
                    foreach (var item in element.EnumerateObject())
                    {
                        RenderNode(item.Name, item.Value);
                    }
                    ImGui.TreePop();
                }
            } break;
            case JsonValueKind.Array: {
                var node = ImGui.TreeNode(name);
                ImGui.TableNextColumn();
                ImGui.TextUnformatted("Array");
                ImGui.TableNextColumn();
                ImGui.TextDisabled($"length: {element.GetArrayLength()}");
                if(node)
                {
                    var i = 0;
                    foreach (var item in element.EnumerateArray())
                    {
                        RenderNode($"[{i++}]", item);
                    }
                    ImGui.TreePop();
                }
            } break;
            case JsonValueKind.String: {
                ImGui.TextUnformatted(name);
                ImGui.TableNextColumn();
                ImGui.TextUnformatted("String");
                ImGui.TableNextColumn();
                ImGui.TextUnformatted(element.GetString());
            } break;
            case JsonValueKind.Number: {
                ImGui.TextUnformatted(name);
                ImGui.TableNextColumn();
                ImGui.TextUnformatted("Number");
                ImGui.TableNextColumn();
                ImGui.TextUnformatted(element.GetString());
            } break;
            case JsonValueKind.True: {
                ImGui.TextUnformatted(name);
                ImGui.TableNextColumn();
                ImGui.TextUnformatted("Boolean");
                ImGui.TableNextColumn();
                ImGui.TextUnformatted("true");
            } break;
            case JsonValueKind.False: {
                ImGui.TextUnformatted(name);
                ImGui.TableNextColumn();
                ImGui.TextUnformatted("Boolean");
                ImGui.TableNextColumn();
                ImGui.TextUnformatted("false");
            } break;
            case JsonValueKind.Null: {
                ImGui.TextUnformatted(name);
                ImGui.TableNextColumn();
                ImGui.TextUnformatted("Null");
                ImGui.TableNextColumn();
                ImGui.TextUnformatted("null");
            } break;
            case JsonValueKind.Undefined: {
                ImGui.TextUnformatted(name);
                ImGui.TableNextColumn();
                ImGui.TextUnformatted("Undefined");
                ImGui.TableNextColumn();
                ImGui.TextDisabled("undefined");
            } break;
        }
    }
}