using System.Collections.Concurrent;
using CMSMicroservice.Protobuf.Protos.ImageResolver;

namespace FrontOffice.Main.Utilities;

/// <summary>
/// سرویس مرکزی resolve تصاویر — تمام تصاویر دینامیک FrontOffice از این سرویس عبور می‌کنند.
/// مسیرهای نسبی از طریق gRPC به CMS ارسال شده و base64 data-URI دریافت می‌شود.
/// نتایج در حافظه کش می‌شوند تا از فراخوانی مجدد جلوگیری شود.
/// </summary>
public class ImageCacheService
{
    private readonly ImageResolverContract.ImageResolverContractClient _client;
    private readonly ConcurrentDictionary<string, string> _cache = new();

    public ImageCacheService(ImageResolverContract.ImageResolverContractClient client)
    {
        _client = client;
    }

    /// <summary>
    /// تبدیل یک مسیر تصویر به base64 data-URI.
    /// اگر مسیر خالی باشد → رشته خالی.
    /// اگر قبلاً data-URI باشد → بدون تغییر.
    /// اگر در کش باشد → از کش.
    /// در غیر این صورت → فراخوانی gRPC.
    /// </summary>
    public async Task<string> ResolveAsync(string? path)
    {
        if (string.IsNullOrWhiteSpace(path))
            return string.Empty;

        // اگر قبلاً base64 هست (مثلاً از interceptor آمده)
        if (path.StartsWith("data:", StringComparison.Ordinal))
            return path;

        // مسیرهای استاتیک (wwwroot) یا لینک‌های خارجی نیاز به resolve ندارند
        if (path.StartsWith('/') || path.StartsWith("http://", StringComparison.Ordinal)
                                 || path.StartsWith("https://", StringComparison.Ordinal))
            return path;

        // جستجو در کش
        if (_cache.TryGetValue(path, out var cached))
            return cached;

        try
        {
            var response = await _client.ResolveImagesAsync(
                new ResolveImagesRequest { Paths = { path } });

            var result = response?.Images?.FirstOrDefault()?.DataUri ?? string.Empty;
            _cache.TryAdd(path, result);
            return result;
        }
        catch
        {
            // در صورت خطا، رشته خالی برگردان تا UI خراب نشود
            return string.Empty;
        }
    }

    /// <summary>
    /// تبدیل دسته‌ای مسیرهای تصویر به base64 data-URI.
    /// مسیرهای کش‌شده و data-URI‌ها بدون فراخوانی gRPC برگردانده می‌شوند.
    /// </summary>
    public async Task<Dictionary<string, string>> ResolveBatchAsync(IEnumerable<string?> paths)
    {
        var result = new Dictionary<string, string>();
        var toResolve = new List<string>();

        foreach (var path in paths)
        {
            if (string.IsNullOrWhiteSpace(path))
                continue;

            if (path.StartsWith("data:", StringComparison.Ordinal)
                || path.StartsWith('/')
                || path.StartsWith("http://", StringComparison.Ordinal)
                || path.StartsWith("https://", StringComparison.Ordinal))
            {
                result[path] = path;
            }
            else if (_cache.TryGetValue(path, out var cached))
            {
                result[path] = cached;
            }
            else
            {
                toResolve.Add(path);
            }
        }

        if (toResolve.Count == 0)
            return result;

        try
        {
            var response = await _client.ResolveImagesAsync(
                new ResolveImagesRequest { Paths = { toResolve } });

            if (response?.Images != null)
            {
                foreach (var img in response.Images)
                {
                    _cache.TryAdd(img.OriginalPath, img.DataUri);
                    result[img.OriginalPath] = img.DataUri;
                }
            }
        }
        catch
        {
            // در صورت خطا، مسیرهای resolve نشده خالی بمانند
        }

        return result;
    }

    /// <summary>
    /// پاکسازی تمام کش (مثلاً هنگام logout)
    /// </summary>
    public void ClearCache() => _cache.Clear();
}
