namespace ZB.MOM.WW.ScadaBridge.KpiHistory;

/// <summary>
/// Configuration for the KPI History component. Bound from the
/// <c>ScadaBridge:KpiHistory</c> section of <c>appsettings.json</c>. Defaults
/// reflect the design: a 60-second sampling cadence for the point-in-time
/// Notification Outbox / Site Call Audit KPI snapshots, a 90-day central
/// retention window with a daily purge sweep, and a 200-point default ceiling
/// on the series returned to the Central UI trend charts.
/// </summary>
public sealed class KpiHistoryOptions
{
    /// <summary>
    /// How often the recorder captures a KPI sample row (default 60 s). Must be
    /// strictly positive.
    /// </summary>
    public TimeSpan SampleInterval { get; set; } = TimeSpan.FromSeconds(60);

    /// <summary>
    /// Central retention window in days for recorded KPI samples (default 90,
    /// range <c>[1, 3650]</c>). Rows older than this are dropped by the purge
    /// sweep.
    /// </summary>
    public int RetentionDays { get; set; } = 90;

    /// <summary>
    /// How often the purge sweep drops expired sample rows (default 1 day). Must
    /// be strictly positive.
    /// </summary>
    public TimeSpan PurgeInterval { get; set; } = TimeSpan.FromDays(1);

    /// <summary>
    /// Default ceiling on the number of points returned in a single trend series
    /// query when the caller does not specify one (default 200, range
    /// <c>[2, 5000]</c>). At least two points are required to draw a line.
    /// </summary>
    public int DefaultMaxSeriesPoints { get; set; } = 200;

    /// <summary>
    /// How often the recorder folds the trailing raw <c>KpiSample</c> rows into the
    /// hourly <c>KpiRollupHourly</c> table (default 1 hour). Must be strictly
    /// positive. Each tick re-folds the trailing
    /// <see cref="RollupLookbackHours"/> hours via an idempotent upsert, so a tick
    /// missed during a singleton-failover handover self-heals on the next fold.
    /// </summary>
    public TimeSpan RollupInterval { get; set; } = TimeSpan.FromHours(1);

    /// <summary>
    /// How many trailing whole hours each rollup fold re-processes (default 3,
    /// range <c>[1, 168]</c>). Folding a lookback window rather than just the last
    /// hour lets an idempotent re-fold recover the one or more complete hours a
    /// missed/failover tick skipped. Never includes the in-progress hour (the fold's
    /// upper bound is the current hour start, exclusive).
    /// </summary>
    public int RollupLookbackHours { get; set; } = 3;

    /// <summary>
    /// Central retention window in days for the hourly rollup rows (default 365,
    /// range <c>[1, 3650]</c>). Rollups outlive raw samples so long-range trend
    /// charts have data after raw <c>KpiSample</c> rows are purged; the validator
    /// therefore requires <c>RollupRetentionDays &gt;= <see cref="RetentionDays"/></c>
    /// so a window never falls into a hole where raw is purged but no rollup was
    /// written. Dropped by the rollup purge sweep.
    /// </summary>
    public int RollupRetentionDays { get; set; } = 365;

    /// <summary>
    /// Query-routing boundary in hours (default 168 = 7 days, minimum 24). Trend
    /// queries whose window is <c>&lt;=</c> this width read raw <c>KpiSample</c> rows
    /// (preserving intra-minute detail); wider windows read the pre-aggregated
    /// hourly rollups. Consumed by the Central UI query service's range routing.
    /// </summary>
    public int RollupThresholdHours { get; set; } = 168;
}
