using System.Globalization; using System.Text.RegularExpressions; using line_gestao_api.Data; using line_gestao_api.Models; using Microsoft.EntityFrameworkCore; namespace line_gestao_api.Services; public static class AutoFillRules { private static readonly Regex FranquiaRegex = new( @"(?\d+(?:[.,]\d+)?)\s*(?GB|MB)", RegexOptions.IgnoreCase | RegexOptions.Compiled); public sealed record PlanSuggestion(decimal? FranquiaGb, decimal? ValorPlano); public static async Task ResolvePlanSuggestionAsync(AppDbContext db, string? planoContrato) { var plan = (planoContrato ?? string.Empty).Trim(); if (string.IsNullOrWhiteSpace(plan)) return null; ResumoPlanoContratoResumo? resumoPlano = await db.ResumoPlanoContratoResumos .AsNoTracking() .Where(x => x.PlanoContrato != null && EF.Functions.ILike(x.PlanoContrato, plan)) .OrderByDescending(x => x.UpdatedAt) .FirstOrDefaultAsync(); ResumoMacrophonyPlan? macroPlan = null; if (resumoPlano == null) { macroPlan = await db.ResumoMacrophonyPlans .AsNoTracking() .Where(x => x.PlanoContrato != null && EF.Functions.ILike(x.PlanoContrato, plan)) .OrderByDescending(x => x.UpdatedAt) .FirstOrDefaultAsync(); } decimal? franquia = resumoPlano?.FranquiaGb ?? resumoPlano?.Gb; decimal? valor = resumoPlano?.ValorIndividualComSvas; if (macroPlan != null) { franquia ??= macroPlan.FranquiaGb ?? macroPlan.Gb; valor ??= macroPlan.ValorIndividualComSvas; } franquia ??= ParseFranquiaGbFromPlano(plan); return new PlanSuggestion(franquia, valor); } public static decimal? ParseFranquiaGbFromPlano(string? planoContrato) { if (string.IsNullOrWhiteSpace(planoContrato)) return null; var match = FranquiaRegex.Match(planoContrato); if (!match.Success) return null; var raw = match.Groups["val"].Value.Replace(",", "."); if (!decimal.TryParse(raw, NumberStyles.Any, CultureInfo.InvariantCulture, out var value)) { return null; } var unit = match.Groups["unit"].Value.ToUpperInvariant(); if (unit == "MB") { return Math.Round(value / 1000m, 4); } return value; } }