#nullable enable
using Baya.Application.Contracts.Common;

namespace Baya.Application.Features.Geography;

/// <summary>
/// Cache-key scheme for the read-heavy geo lookups. Every data key is namespaced by a generation token;
/// an admin write bumps the token, which orphans all prior geo entries in one move (they lapse by TTL).
/// This makes cascade invalidation trivial and correct — deactivating a province instantly hides its
/// cities/districts without having to enumerate and evict each child key.
/// </summary>
internal static class GeoCache
{
    private const string VersionKey = "geo:version";

    // Reference data changes rarely; a modest TTL bounds staleness even if a bump is ever missed.
    public static readonly TimeSpan Ttl = TimeSpan.FromHours(1);

    public static ValueTask<string> VersionAsync(ICacheService cache, CancellationToken cancellationToken)
        => cache.GetOrCreateAsync(VersionKey, _ => ValueTask.FromResult(NewToken()), null, cancellationToken);

    public static ValueTask InvalidateAsync(ICacheService cache, CancellationToken cancellationToken)
        => cache.SetAsync(VersionKey, NewToken(), null, cancellationToken);

    public static string ProvincesKey(string version) => $"geo:{version}:provinces";
    public static string CitiesKey(string version, long provinceId) => $"geo:{version}:cities:{provinceId}";
    public static string DistrictsKey(string version, long cityId) => $"geo:{version}:districts:{cityId}";
    public static string TreeKey(string version) => $"geo:{version}:tree";

    private static string NewToken() => Guid.NewGuid().ToString("N");
}
