// bobcord_cs.cs — SDK BobCord (REST + builders)
// User + Bot + EmbedBuilder + ActionRow / Button / WebAction
// API: https://aml-s9xx-box.taildd440a.ts.net/api/v1.1
// .NET 6+ — HttpClient + System.Text.Json

using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;

public static class BobCordApi
{
    public const string DefaultBase = "https://aml-s9xx-box.taildd440a.ts.net/api/v1.1";
}

public class Builder
{
    protected readonly Dictionary<string, object?> Data = new();
    public Builder Set(string key, object? value) { Data[key] = value; return this; }
    public Dictionary<string, object?> Build() => new(Data);
}

public class EmbedBuilder : Builder
{
    public EmbedBuilder() { Data["fields"] = new List<object>(); }
    public EmbedBuilder Title(string t) { Data["title"] = t; return this; }
    public EmbedBuilder Description(string d) { Data["description"] = d; return this; }
    public EmbedBuilder Color(int c) { Data["color"] = c & 0xFFFFFF; return this; }
    public EmbedBuilder AddField(string name, string value, bool inline = false)
    {
        ((List<object>)Data["fields"]!).Add(new { name, value, inline });
        return this;
    }
    public EmbedBuilder Footer(string text) { Data["footer"] = new { text }; return this; }
}

public class WebAction : Builder
{
    public static WebAction Confirm(string title = "Confirmer", string body = "", object? then = null)
    {
        var wa = new WebAction();
        wa.Set("type", "confirm").Set("title", title).Set("body", body);
        if (then != null) wa.Set("then", then is Builder b ? b.Build() : then);
        return wa;
    }
    public static WebAction SendMessage(string content, string? channel = null, long? serverId = null, object? confirm = null)
    {
        var wa = new WebAction();
        wa.Set("type", "send_message").Set("content", content);
        if (channel != null) wa.Set("channel", channel);
        if (serverId != null) wa.Set("server_id", serverId);
        if (confirm != null) wa.Set("confirm", confirm);
        return wa;
    }
    public static WebAction React(string emoji = "👍", object messageId = null!, object? confirm = null)
    {
        var wa = new WebAction();
        wa.Set("type", "react").Set("emoji", emoji).Set("message_id", messageId ?? "self");
        if (confirm != null) wa.Set("confirm", confirm);
        return wa;
    }
}

public class Button : Builder
{
    public Button(string label, string style = "SECONDARY", string? customId = null, string? url = null, object? webAction = null, bool disabled = false)
    {
        style = style.ToUpperInvariant();
        Set("type", "BUTTON").Set("style", style).Set("label", label).Set("disabled", disabled);
        if (style == "LINK")
        {
            if (string.IsNullOrEmpty(url)) throw new ArgumentException("LINK requires url");
            Set("url", url);
        }
        else
        {
            if (string.IsNullOrEmpty(customId)) throw new ArgumentException("BUTTON requires custom_id");
            Set("custom_id", customId);
        }
        if (style == "WEB_ACTION")
        {
            if (webAction == null) throw new ArgumentException("WEB_ACTION requires web_action");
            Set("web_action", webAction is Builder b ? b.Build() : webAction);
        }
    }
}

public class ActionRow : Builder
{
    public ActionRow(params object[] components)
    {
        Set("type", "ACTION_ROW");
        var list = new List<object>();
        foreach (var c in components.Take(5))
            list.Add(c is Builder b ? b.Build() : c);
        Set("components", list);
    }
}

public class User
{
    public string Token { get; }
    public string BaseUrl { get; set; } = BobCordApi.DefaultBase;
    public JsonElement? Me { get; private set; }
    static readonly HttpClient Http = new();

    public User(string token) { Token = token.Trim(); }

    public async Task<JsonElement> RequestAsync(string method, string path, object? body = null)
    {
        var url = $"{BaseUrl.TrimEnd('/')}/{path.TrimStart('/')}";
        using var req = new HttpRequestMessage(new HttpMethod(method), url);
        req.Headers.Authorization = new AuthenticationHeaderValue("Bearer", Token);
        if (body != null)
            req.Content = new StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json");
        using var res = await Http.SendAsync(req);
        var text = await res.Content.ReadAsStringAsync();
        if ((int)res.StatusCode == 204) return default;
        using var doc = JsonDocument.Parse(string.IsNullOrWhiteSpace(text) ? "{}" : text);
        var data = doc.RootElement.Clone();
        if (!res.IsSuccessStatusCode)
            throw new Exception($"HTTP {(int)res.StatusCode}: {data}");
        return data;
    }

    public async Task<JsonElement> LoginAsync()
    {
        var data = await RequestAsync("GET", "/me");
        Me = data.TryGetProperty("user", out var u) ? u : data;
        return Me.Value;
    }

    public async Task<JsonElement> SendAsync(string content = "", string channel = "général",
        long serverId = 1, object? embeds = null, object? actionRows = null, object? attachments = null)
    {
        var body = new Dictionary<string, object?>
        {
            ["content"] = content, ["channel"] = channel, ["server_id"] = serverId
        };
        if (embeds != null) body["embeds"] = embeds;
        if (attachments != null) body["attachments"] = attachments;
        if (actionRows != null)
        {
            var rows = new List<object>();
            foreach (var r in (IEnumerable<object>)actionRows)
                rows.Add(r is Builder b ? b.Build() : r);
            body["action_rows"] = rows;
        }
        return await RequestAsync("POST", "/message", body);
    }
}

public class Bot : User
{
    public Bot(string token) : base(token) { }
}
