using Grpc.Core;
using Microsoft.JSInterop;

namespace FrontOffice.Main.Utilities;

public static class CreditChargeNavigation
{
    public const long MinChargeAmount = 10_000;
    public const string ReturnUrlStorageKey = "credit_charge_return_url";
    private const string InsufficientBalanceMarker = "موجودی کیف پول کافی نیست";

    public static long NormalizeChargeAmount(long shortfall) =>
        Math.Max(shortfall, MinChargeAmount);

    public static string BuildChargeUrl(long amount, string? returnUrl)
    {
        var url = $"{RouteConstants.Profile.ChargeCreditWallet}?amount={amount}";
        if (IsValidReturnUrl(returnUrl))
            url += $"&returnUrl={Uri.EscapeDataString(returnUrl!)}";
        return url;
    }

    public static bool IsValidReturnUrl(string? url) =>
        !string.IsNullOrWhiteSpace(url)
        && url.StartsWith('/')
        && !url.StartsWith("//", StringComparison.Ordinal);

    public static bool IsInsufficientWalletBalanceMessage(string? message) =>
        message?.Contains(InsufficientBalanceMarker, StringComparison.Ordinal) == true;

    public static bool IsInsufficientWalletBalance(Exception ex) =>
        ex switch
        {
            RpcException rpc => IsInsufficientWalletBalanceMessage(rpc.Status.Detail)
                || IsInsufficientWalletBalanceMessage(rpc.Message),
            _ => IsInsufficientWalletBalanceMessage(ex.Message)
        };

    public static async Task SaveReturnUrlAsync(IJSRuntime js, string returnUrl)
    {
        if (!IsValidReturnUrl(returnUrl)) return;
        await js.InvokeVoidAsync("sessionStorage.setItem", ReturnUrlStorageKey, returnUrl);
    }

    public static async Task<string?> GetReturnUrlAsync(IJSRuntime js) =>
        await js.InvokeAsync<string?>("sessionStorage.getItem", ReturnUrlStorageKey);

    public static async Task ClearReturnUrlAsync(IJSRuntime js) =>
        await js.InvokeVoidAsync("sessionStorage.removeItem", ReturnUrlStorageKey);
}
