namespace ClawdDotNet.Core.Accounting;

/// <summary>Verbrauch eines abgeschlossenen Laufs.</summary>
public sealed record RunUsage
{
    public long Id { get; init; }
    public string AgentId { get; init; } = "";
    public string Model { get; init; } = "";

    public int PromptTokens { get; init; }
    public int CompletionTokens { get; init; }

    /// <summary>Anteil der Eingabe-Tokens aus dem Prompt-Cache — in PromptTokens enthalten.</summary>
    public int CachedTokens { get; init; }

    public int TotalTokens => PromptTokens + CompletionTokens;

    public decimal CostUsd { get; init; }

    /// <summary>
    /// Ob für das Modell Preise vorlagen. Ohne diese Angabe wäre eine zu niedrige
    /// Summe von einer vollständigen nicht zu unterscheiden.
    /// </summary>
    public bool CostIsKnown { get; init; }

    public string Status { get; init; } = "";
    public int StepCount { get; init; }
    public long DurationMs { get; init; }

    public DateTime OccurredAt { get; init; }
}

/// <summary>Verbrauch eines Tages, aggregiert.</summary>
public sealed record DailyUsage(
    DateOnly Date,
    int PromptTokens,
    int CompletionTokens,
    decimal CostUsd,
    bool CostIsComplete,
    int RunCount)
{
    public int TotalTokens => PromptTokens + CompletionTokens;

    public static DailyUsage Empty(DateOnly date) => new(date, 0, 0, 0m, true, 0);
}

public interface IUsageRepository
{
    Task RecordAsync(RunUsage usage, CancellationToken ct);

    /// <summary>Tagesverbrauch eines Agenten. <paramref name="agentId"/> leer = ganze Instanz.</summary>
    Task<DailyUsage> GetDailyAsync(DateOnly date, string agentId, CancellationToken ct);

    Task<IReadOnlyList<RunUsage>> GetRecentAsync(int limit, CancellationToken ct);

    /// <summary>Entfernt Einträge älter als das angegebene Datum. Gibt die Anzahl zurück.</summary>
    Task<int> PurgeBeforeAsync(DateOnly date, CancellationToken ct);
}
