using Baya.Domain.Entities.Configuration;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace Baya.Infrastructure.Persistence.Configuration.ConfigurationConfig;

internal sealed class PlatformConfigConfig : IEntityTypeConfiguration<PlatformConfig>
{
    public void Configure(EntityTypeBuilder<PlatformConfig> builder)
    {
        builder.ToTable("PlatformConfigs", "ops");

        builder.Property(c => c.Key).HasMaxLength(100).IsRequired();
        builder.Property(c => c.Value).IsRequired();
        builder.Property(c => c.DataType).HasMaxLength(20).IsRequired();
        builder.Property(c => c.Description).HasMaxLength(500);

        builder.HasIndex(c => c.Key).IsUnique();

        builder.HasData(SeedData());
    }

    // Seeded via HasData so the values land with the baseline migration on a fresh DB. Defaults for keys
    // the product docs don't pin down (fee/BNPL/cancellation) are decisions recorded in product doc 12.
    private static object[] SeedData()
    {
        var ts = SeedConstants.Timestamp;

        (long Id, string Key, string Value, string DataType, string Description)[] rows =
        [
            (1, "platform_fee_rate", "0.15", ConfigDataType.Decimal, "Balinyaar commission rate on the booking gross (fraction)."),
            (2, "vat_rate", "0.10", ConfigDataType.Decimal, "VAT rate applied to the commission line only (fraction)."),
            (3, "dispute_window_hours", "72", ConfigDataType.Int, "Hours after check-out a booking can be disputed."),
            (4, "booking_payment_deadline_minutes", "30", ConfigDataType.Int, "Minutes a family has to pay before a pending booking expires."),
            (5, "nurse_response_deadline_hours", "24", ConfigDataType.Int, "Hours a nurse has to accept/decline a booking request."),
            (6, "nurse_payout_interval_days", "7", ConfigDataType.Int, "Weekly payout cadence in days."),
            (7, "evv_location_tolerance_meters", "200", ConfigDataType.Int, "Allowed EVV check-in distance from the care address."),
            (8, "min_rating_for_support_alert", "2", ConfigDataType.Decimal, "A review at or below this rating raises a support alert."),
            (9, "bnpl_merchant_of_record", "platform", ConfigDataType.String, "Who is merchant of record for BNPL orders (platform|nurse)."),
            (10, "bnpl_provider_commission_rate", "0.07", ConfigDataType.Decimal, "BNPL provider commission rate (fraction)."),
            (11, "bnpl_settlement_timing", "immediate", ConfigDataType.String, "When BNPL settles funds to the platform (immediate|deferred)."),
            (12, "cancellation_tiers", "[{\"min_hours_before\":48,\"refund_percent\":100},{\"min_hours_before\":24,\"refund_percent\":50},{\"min_hours_before\":0,\"refund_percent\":0}]", ConfigDataType.Json, "Tiered cancellation refund policy: refund_percent by hours before the visit."),
            (13, "auth_otp_resend_seconds", "120", ConfigDataType.Int, "Seconds a phone must wait before another OTP can be requested."),
            (14, "auth_otp_max_attempts", "5", ConfigDataType.Int, "Wrong-code attempts allowed before OTP verification is refused until a fresh code."),
            (15, "auth_session_ttl_days", "30", ConfigDataType.Int, "Refresh-token session lifetime in days."),
            (16, "verification_expiry_scan_cadence_hours", "24", ConfigDataType.Int, "Hours between credential-expiry scans (the scheduled cron is deferred; the scan is admin-triggered today)."),
            (17, "no_show_threshold_minutes", "60", ConfigDataType.Int, "Minutes after a session's scheduled start with no EVV check-in before it is flagged a no-show."),
            (18, "no_show_scan_cadence_hours", "1", ConfigDataType.Int, "Hours between no-show sweeps (the scheduled cron is deferred; the sweep is admin-triggered today)."),
            // (19) refund_ticket_required — retired in refinement-phase-6. b15 unconditionally auto-opens a refund
            //      ticket, so the config-gated rule had no consumer left; the seed row is deleted by that migration.
            (20, "bnpl_refund_eta_business_days", "10", ConfigDataType.Int, "Business days shown as the customer BNPL refund ETA (b11)."),
            (21, "refund_assume_nurse_paid", "false", ConfigDataType.Bool, "Ops/testing override that forces the post-payout clawback path for refunds (b11); b13 replaces the derivation."),
            (22, "payout_satna_threshold_irr", "1000000000", ConfigDataType.Decimal, "IRR net-amount threshold above which a payout is routed via SATNA (real-time) instead of PAYA (batch) (b13)."),
            (23, "require_bnpl_settlement_for_payout", "false", ConfigDataType.Bool, "When on, a BNPL-paid booking is payout-eligible only after its provider settlement is received (b13; default off — the DEFERRED settled_at guard)."),
            // refinement-phase-9 §9.4: two-tier audit-log retention. Financial/verification rows keep a long legal
            // window; everyday rows a shorter one; the retention sweep runs on the cadence key.
            (24, "audit_retention_general_days", "730", ConfigDataType.Int, "Retention (days) for everyday audit rows before the retention sweep deletes them (~2 years)."),
            (25, "audit_retention_financial_days", "2555", ConfigDataType.Int, "Retention (days) for financial/verification audit rows (refunds/clawbacks/payouts/verification/config/partner-center) — the long legal window (~7 years)."),
            (26, "audit_retention_scan_cadence_hours", "24", ConfigDataType.Int, "Hours between audit-log retention sweeps."),
        ];

        return rows
            .Select(r => (object)new
            {
                r.Id,
                r.Key,
                r.Value,
                r.DataType,
                r.Description,
                CreatedAt = ts
            })
            .ToArray();
    }
}
