using Dalamud.Bindings.ImGui;
using Dalamud.Interface;
using Dalamud.Interface.Windowing;
using LightlessSync.UI;
using LightlessSync.WebAPI.SignalR.Utils;
using System.Numerics;

namespace LightlessSync.Utils;

public sealed class WindowBuilder
{
    private readonly Window _window;
    private readonly List<Window.TitleBarButton> _titleButtons = new();

    private WindowBuilder(Window window)
    {
        _window = window ?? throw new ArgumentNullException(nameof(window));
    }

    public static WindowBuilder For(Window window) => new(window);

    public WindowBuilder AllowPinning(bool allow = true)
    {
        _window.AllowPinning = allow;
        return this;
    }

    public WindowBuilder AllowClickthrough(bool allow = true)
    {
        _window.AllowClickthrough = allow;
        return this;
    }

    public WindowBuilder SetFixedSize(Vector2 size) => SetSizeConstraints(size, size);

    public WindowBuilder SetSizeConstraints(Vector2 min, Vector2 max)
    {
        _window.SizeConstraints = new Window.WindowSizeConstraints
        {
            MinimumSize = min,
            MaximumSize = max,
        };
        return this;
    }

    public WindowBuilder AddFlags(ImGuiWindowFlags flags)
    {
        _window.Flags |= flags;
        return this;
    }

    public WindowBuilder AddTitleBarButton(FontAwesomeIcon icon, string tooltip, Action onClick, Vector2? iconOffset = null)
    {
        _titleButtons.Add(new Window.TitleBarButton
        {
            Icon = icon,
            IconOffset = iconOffset ?? new Vector2(2, 1),
            Click = _ => onClick(),
            ShowTooltip = () => UiSharedService.AttachToolTip(tooltip),
        });
        return this;
    }

    public Window Apply()
    {
        if (_titleButtons.Count > 0)
            _window.TitleBarButtons = _titleButtons;
        return _window;
    }
}

public static class WindowUtils
{
    public static Vector4 GetUidColor(this ServerState state)
    {
        return state switch
        {
            ServerState.Connecting => UIColors.Get("LightlessYellow"),
            ServerState.Reconnecting => UIColors.Get("DimRed"),
            ServerState.Connected => UIColors.Get("LightlessPurple"),
            ServerState.Disconnected => UIColors.Get("LightlessYellow"),
            ServerState.Disconnecting => UIColors.Get("LightlessYellow"),
            ServerState.Unauthorized => UIColors.Get("DimRed"),
            ServerState.VersionMisMatch => UIColors.Get("DimRed"),
            ServerState.Offline => UIColors.Get("DimRed"),
            ServerState.RateLimited => UIColors.Get("LightlessYellow"),
            ServerState.NoSecretKey => UIColors.Get("LightlessYellow"),
            ServerState.MultiChara => UIColors.Get("LightlessYellow"),
            ServerState.OAuthMisconfigured => UIColors.Get("DimRed"),
            ServerState.OAuthLoginTokenStale => UIColors.Get("DimRed"),
            ServerState.NoAutoLogon => UIColors.Get("LightlessYellow"),
            _ => UIColors.Get("DimRed"),
        };
    }

    public static string GetUidText(this ServerState state, string displayName)
    {
        return state switch
        {
            ServerState.Reconnecting => "Reconnecting",
            ServerState.Connecting => "Connecting",
            ServerState.Disconnected => "Disconnected",
            ServerState.Disconnecting => "Disconnecting",
            ServerState.Unauthorized => "Unauthorized",
            ServerState.VersionMisMatch => "Version mismatch",
            ServerState.Offline => "Unavailable",
            ServerState.RateLimited => "Rate Limited",
            ServerState.NoSecretKey => "No Secret Key",
            ServerState.MultiChara => "Duplicate Characters",
            ServerState.OAuthMisconfigured => "Misconfigured OAuth2",
            ServerState.OAuthLoginTokenStale => "Stale OAuth2",
            ServerState.NoAutoLogon => "Auto Login disabled",
            ServerState.Connected => displayName,
            _ => string.Empty,
        };
    }

    public static string GetServerError(this ServerState state, string authFailureMessage)
    {
        return state switch
        {
            ServerState.Connecting => "Attempting to connect to the server.",
            ServerState.Reconnecting => "Connection to server interrupted, attempting to reconnect to the server.",
            ServerState.Disconnected => "You are currently disconnected from the Lightless Sync server.",
            ServerState.Disconnecting => "Disconnecting from the server",
            ServerState.Unauthorized => "Server Response: " + authFailureMessage,
            ServerState.Offline => "Your selected Lightless Sync server is currently offline.",
            ServerState.VersionMisMatch =>
                "Your plugin or the server you are connecting to is out of date. Please update your plugin now. If you already did so, contact the server provider to update their server to the latest version.",
            ServerState.RateLimited => "You are rate limited for (re)connecting too often. Disconnect, wait 10 minutes and try again.",
            ServerState.NoSecretKey => "You have no secret key set for this current character. Open Settings -> Service Settings and set a secret key for the current character. You can reuse the same secret key for multiple characters.",
            ServerState.MultiChara => "Your Character Configuration has multiple characters configured with same name and world. You will not be able to connect until you fix this issue. Remove the duplicates from the configuration in Settings -> Service Settings -> Character Management and reconnect manually after.",
            ServerState.OAuthMisconfigured => "OAuth2 is enabled but not fully configured, verify in the Settings -> Service Settings that you have OAuth2 connected and, importantly, a UID assigned to your current character.",
            ServerState.OAuthLoginTokenStale => "Your OAuth2 login token is stale and cannot be used to renew. Go to the Settings -> Service Settings and unlink then relink your OAuth2 configuration.",
            ServerState.NoAutoLogon => "This character has automatic login into Lightless disabled. Press the connect button to connect to Lightless.",
            _ => string.Empty,
        };
    }
}
