using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Kpi;

namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Configurations;

/// <summary>
/// Maps the <see cref="KpiSample"/> POCO to the central <c>KpiSample</c> table —
/// the tall / EAV row written by the recorder
/// singleton. Operational history, NOT audit, so the table is non-partitioned,
/// standard <c>[PRIMARY]</c> filegroup, no DB-role restriction.
/// </summary>
/// <remarks>
/// Two named indexes back the access paths: <c>IX_KpiSample_Series</c> covers the
/// bucketed series query (filter by Source/Metric/Scope/ScopeKey, ordered by
/// capture time) and <c>IX_KpiSample_Captured</c> backs the retention purge
/// (delete by <see cref="KpiSample.CapturedAtUtc"/>).
/// </remarks>
public class KpiSampleEntityTypeConfiguration : IEntityTypeConfiguration<KpiSample>
{
    /// <summary>
    /// Configures the EF Core entity type mapping for <see cref="KpiSample"/>.
    /// </summary>
    /// <param name="builder">The entity type builder to configure.</param>
    public void Configure(EntityTypeBuilder<KpiSample> builder)
    {
        builder.ToTable("KpiSample");

        // Surrogate long identity assigned by the store.
        builder.HasKey(s => s.Id);

        // Catalog-bounded ASCII columns — values come from the KpiSources /
        // KpiScopes catalogs and per-source metric names.
        builder.Property(s => s.Source).HasMaxLength(64).IsUnicode(false).IsRequired();
        builder.Property(s => s.Metric).HasMaxLength(64).IsUnicode(false).IsRequired();
        builder.Property(s => s.Scope).HasMaxLength(16).IsUnicode(false).IsRequired();

        // Scope qualifier — null for the Global scope.
        builder.Property(s => s.ScopeKey).HasMaxLength(64).IsUnicode(false);

        // Measured value — double / float column.
        builder.Property(s => s.Value);

        builder.Property(s => s.CapturedAtUtc).IsRequired();

        // Series index — backs the bucketed query path (filter one series, scan in
        // capture order). Names locked for migration discoverability.
        // Global-scope rows (ScopeKey IS NULL) are included in the index and are
        // seeked via the IS NULL predicate, so the index covers all scope levels.
        builder.HasIndex(s => new { s.Source, s.Metric, s.Scope, s.ScopeKey, s.CapturedAtUtc })
            .HasDatabaseName("IX_KpiSample_Series");

        // Captured index — backs the retention purge (delete by capture time).
        builder.HasIndex(s => s.CapturedAtUtc)
            .HasDatabaseName("IX_KpiSample_Captured");
    }
}
