#nullable enable
using System;
using System.Threading;
using System.Threading.Tasks;

namespace Baya.Infrastructure.Persistence.Services.Scheduling;

/// <summary>
/// One recurring background job driven by <see cref="RecurringJobSchedulerHostedService"/>. Each
/// implementation re-homes a previously admin-manual (or hardcoded-interval) sweep behind the same seam so
/// the platform runs itself: the scheduler owns the loop, the per-tick DI scope, the distributed lock, and
/// the error handling, while the job only says <em>how often</em> it runs and <em>what</em> one idempotent
/// run does. Every run must be idempotent — a scheduler retry (or a second instance once the lock is
/// Redis-backed) must never double-pay or double-post; the DB uniques/state-machines are the backstop.
/// </summary>
internal interface IRecurringJob
{
    /// <summary>Stable identifier — used for the distributed-lock key (<c>scheduler:{Name}</c>) and log scope.</summary>
    string Name { get; }

    /// <summary>
    /// Resolves this job's run interval, read fresh each tick (usually from a <c>platform_configs</c> cadence
    /// key via <see cref="Baya.Application.Contracts.Configuration.IPlatformConfig"/>) so an admin cadence
    /// change takes effect without a restart. <paramref name="services"/> is the per-tick scoped provider.
    /// </summary>
    ValueTask<TimeSpan> GetIntervalAsync(IServiceProvider services, CancellationToken cancellationToken);

    /// <summary>Executes one idempotent run within the provided per-tick DI scope.</summary>
    ValueTask RunAsync(IServiceProvider services, CancellationToken cancellationToken);
}
