using System.Diagnostics;
using Avalonia.Controls;
using OF_DL.Helpers;
using Serilog;

namespace OF_DL.Gui.Helpers;

public static class WebLinkHelper
{
    private const string CopiedToClipboardMessage = "Copied to clipboard";

    public static async Task OpenOrCopyAsync(
        Window owner,
        string url,
        Control? toolTipTarget = null,
        Func<string, Task>? dockerFeedbackAsync = null)
    {
        try
        {
            if (EnvironmentHelper.IsRunningInDocker())
            {
                TopLevel? topLevel = TopLevel.GetTopLevel(owner);
                if (topLevel?.Clipboard != null)
                {
                    try
                    {
                        await topLevel.Clipboard.SetTextAsync(url);
                    }
                    catch
                    {
                        return;
                    }
                }

                if (dockerFeedbackAsync != null)
                {
                    await dockerFeedbackAsync(CopiedToClipboardMessage);
                    return;
                }

                if (toolTipTarget != null)
                {
                    await ShowTemporaryTooltipAsync(toolTipTarget, CopiedToClipboardMessage);
                }

                return;
            }
        }
        catch (Exception e)
        {
            Log.Error("Failed to copy URL to clipboard. {ErrorMessage}", e.Message);
        }

        try
        {
            OpenExternalUrl(url);
        }
        catch (Exception e)
        {
            Log.Error(e, "Failed to open external URL. {ErrorMessage}", e.Message);
        }
    }

    private static async Task ShowTemporaryTooltipAsync(
        Control target,
        string message,
        int durationMilliseconds = 1500)
    {
        object? originalTip = ToolTip.GetTip(target);

        ToolTip.SetTip(target, message);
        ToolTip.SetIsOpen(target, true);

        await Task.Delay(durationMilliseconds);

        ToolTip.SetIsOpen(target, false);
        ToolTip.SetTip(target, originalTip);
    }

    private static void OpenExternalUrl(string url)
    {
        try
        {
            ProcessStartInfo processStartInfo = new(url) { UseShellExecute = true };
            Process.Start(processStartInfo);
        }
        catch
        {
            // Ignore browser launch failures to preserve prior behavior.
        }
    }
}
