namespace Tiku.Application.Security;

public enum FeatureAccessOperation
{
    Read,
    Write
}

public sealed record FeatureAccessDecision(
    bool Allowed,
    string? DenialCode,
    string FeatureCode,
    FeatureAccessOperation Operation);

public sealed record FeatureQuotaSnapshot(
    string MetricCode,
    long UsedValue,
    long LimitValue,
    int UsedPercent,
    bool Warning,
    bool Exceeded,
    DateTimeOffset PeriodStart,
    DateTimeOffset PeriodEnd);

public interface IFeatureAccessService
{
    Task<FeatureAccessDecision> EvaluateAsync(
        Guid tenantId,
        string featureCode,
        FeatureAccessOperation operation,
        CancellationToken cancellationToken = default);

    Task<IReadOnlySet<string>> GetEnabledFeaturesAsync(
        Guid tenantId,
        FeatureAccessOperation operation = FeatureAccessOperation.Read,
        CancellationToken cancellationToken = default);

    Task<IReadOnlySet<string>> FilterPermissionCodesAsync(
        Guid tenantId,
        IEnumerable<string> permissionCodes,
        FeatureAccessOperation operation = FeatureAccessOperation.Read,
        CancellationToken cancellationToken = default);

    Task<IReadOnlyCollection<FeatureQuotaSnapshot>> GetQuotaSummaryAsync(
        Guid tenantId,
        CancellationToken cancellationToken = default);

    Task<bool> TryConsumeQuotaAsync(
        Guid tenantId,
        string metricCode,
        long amount,
        CancellationToken cancellationToken = default);

    Task ReleaseQuotaAsync(
        Guid tenantId,
        string metricCode,
        long amount,
        CancellationToken cancellationToken = default);
}

public sealed class FeatureAccessException(string message, string code) : Exception(message)
{
    public string Code { get; } = code;
}
