namespace KArtSell.Modules.ModelOperations.Domain;

public sealed class ScheduleOccurrencePlanner
{
    public static DateTimeOffset GetNextDueAt(
        DateTimeOffset scheduledFor,
        string cadence,
        string catchUpPolicy,
        int maxCatchUp,
        DateTimeOffset now)
    {
        if (maxCatchUp is < 0 or > 31) throw new ArgumentOutOfRangeException(nameof(maxCatchUp));
        var next = Advance(scheduledFor, cadence);
        if (catchUpPolicy.Equals("ALL_WITH_LIMIT", StringComparison.OrdinalIgnoreCase))
            return next;

        if (!catchUpPolicy.Equals("LATEST_ONLY", StringComparison.OrdinalIgnoreCase)
            && !catchUpPolicy.Equals("SKIP_MISSED", StringComparison.OrdinalIgnoreCase))
            throw new InvalidOperationException($"Unsupported catch-up policy '{catchUpPolicy}'.");

        var guard = 0;
        while (next <= now)
        {
            next = Advance(next, cadence);
            if (++guard > 5000) throw new InvalidOperationException("Schedule catch-up exceeded safety guard.");
        }
        return next;
    }

    private static DateTimeOffset Advance(DateTimeOffset value, string cadence) => cadence.ToUpperInvariant() switch
    {
        "DAILY" => value.AddDays(1),
        "WEEKLY" => value.AddDays(7),
        "MONTHLY" => value.AddMonths(1),
        "QUARTERLY" => value.AddMonths(3),
        "EVENT_DRIVEN" => value.AddYears(100),
        _ => throw new InvalidOperationException($"Unsupported cadence '{cadence}'.")
    };
}
