using ERPCore.Domain.Entities;
using ERPCore.Domain.Enums;
using Microsoft.EntityFrameworkCore;

namespace ERPCore.Infra.Persistence;

/// <summary>
/// Idempotent startup seeding of configurable reference data (docs/10 §B.8.3).
/// Reason codes are seeded at runtime (not via <c>HasData</c>) so the identity
/// sequence advances normally and later admin <c>POST /reason-codes</c> calls
/// cannot collide with seeded ids.
/// </summary>
public static class DataSeeder
{
    private static readonly (string Code, string Description, ReasonContext Context)[] StandardReasonCodes =
    [
        ("DMG", "Damage", ReasonContext.Adjustment),
        ("THEFT", "Theft/Loss", ReasonContext.Adjustment),
        ("VAR", "Count Variance", ReasonContext.Adjustment),
        ("EXP", "Expiry Write-off", ReasonContext.Adjustment),
        ("SYS", "System Correction", ReasonContext.Adjustment),
        ("DEF", "Defective", ReasonContext.Return),
        ("WRONG", "Wrong Item", ReasonContext.Return),
        ("OVER", "Over-supply", ReasonContext.Return),
        ("QREJ", "Quality Reject", ReasonContext.Return),
    ];

    public static async Task SeedAsync(ErpDbContext db, CancellationToken ct = default)
    {
        var existing = await db.ReasonCodes
            .Select(r => new { r.Context, r.Code })
            .ToListAsync(ct);
        var have = existing.Select(x => (x.Context, x.Code)).ToHashSet();

        var toAdd = StandardReasonCodes
            .Where(r => !have.Contains((r.Context, r.Code)))
            .Select(r => new ReasonCode { Code = r.Code, Description = r.Description, Context = r.Context })
            .ToList();

        if (toAdd.Count == 0) return;

        db.ReasonCodes.AddRange(toAdd);
        await db.SaveChangesAsync(ct);
    }
}
