using BCards.Web.Models; namespace BCards.Web.Services; public class PlanConfigurationService : IPlanConfigurationService { private readonly IConfiguration _configuration; private readonly Dictionary _plans; private readonly Dictionary _priceIdToPlanName; private readonly Dictionary _priceIdToPlanType; public PlanConfigurationService(IConfiguration configuration) { _configuration = configuration; _plans = LoadPlansFromConfiguration(); _priceIdToPlanName = BuildPriceIdToPlanNameMap(); _priceIdToPlanType = BuildPriceIdToPlanTypeMap(); } public PlanType GetPlanTypeFromPriceId(string priceId) { if (string.IsNullOrEmpty(priceId)) return PlanType.Trial; return _priceIdToPlanType.TryGetValue(priceId, out var planType) ? planType : PlanType.Trial; } public string GetPlanNameFromPriceId(string priceId) { if (string.IsNullOrEmpty(priceId)) return "Trial"; return _priceIdToPlanName.TryGetValue(priceId, out var planName) ? planName : "Trial"; } public PlanLimitations GetPlanLimitations(PlanType planType) { return planType switch { PlanType.Trial => new PlanLimitations { MaxLinks = 3, AllowCustomThemes = false, AllowAnalytics = false, AllowCustomDomain = false, AllowMultipleDomains = false, PrioritySupport = false, AllowProductLinks = false, MaxProductLinks = 0, PlanType = "trial", AllowDocumentUpload = false, MaxDocuments = 0 }, PlanType.Basic => new PlanLimitations { MaxLinks = GetConfigValue(PlanType.Basic, "MaxLinks", 8), AllowCustomThemes = GetConfigValue(PlanType.Basic, "AllowPremiumThemes", false), AllowAnalytics = GetConfigValue(PlanType.Basic, "AllowAnalytics", true), AllowCustomDomain = true, AllowMultipleDomains = false, PrioritySupport = false, AllowProductLinks = GetConfigValue(PlanType.Basic, "AllowProductLinks", false), MaxProductLinks = 0, PlanType = "basic", AllowDocumentUpload = GetConfigValue(PlanType.Basic, "AllowDocumentUpload", false), MaxDocuments = GetConfigValue(PlanType.Basic, "MaxDocuments", 0) }, PlanType.Professional => new PlanLimitations { MaxLinks = GetConfigValue(PlanType.Professional, "MaxLinks", 20), AllowCustomThemes = GetConfigValue(PlanType.Professional, "AllowPremiumThemes", false), AllowAnalytics = GetConfigValue(PlanType.Professional, "AllowAnalytics", true), AllowCustomDomain = true, AllowMultipleDomains = false, PrioritySupport = false, AllowProductLinks = GetConfigValue(PlanType.Professional, "AllowProductLinks", false), MaxProductLinks = 0, PlanType = "professional", AllowDocumentUpload = GetConfigValue(PlanType.Professional, "AllowDocumentUpload", false), MaxDocuments = GetConfigValue(PlanType.Professional, "MaxDocuments", 0) }, PlanType.Premium => new PlanLimitations { MaxLinks = GetConfigValue(PlanType.Premium, "MaxLinks", -1), AllowCustomThemes = GetConfigValue(PlanType.Premium, "AllowPremiumThemes", true), AllowAnalytics = GetConfigValue(PlanType.Premium, "AllowAnalytics", true), AllowCustomDomain = true, AllowMultipleDomains = true, PrioritySupport = true, AllowProductLinks = GetConfigValue(PlanType.Premium, "AllowProductLinks", false), MaxProductLinks = 0, PlanType = "premium", AllowDocumentUpload = GetConfigValue(PlanType.Premium, "AllowDocumentUpload", true), MaxDocuments = GetConfigValue(PlanType.Premium, "MaxDocuments", 5) }, PlanType.PremiumAffiliate => new PlanLimitations { MaxLinks = GetConfigValue(PlanType.PremiumAffiliate, "MaxLinks", -1), AllowCustomThemes = GetConfigValue(PlanType.PremiumAffiliate, "AllowPremiumThemes", true), AllowAnalytics = GetConfigValue(PlanType.PremiumAffiliate, "AllowAnalytics", true), AllowCustomDomain = true, AllowMultipleDomains = true, PrioritySupport = true, AllowProductLinks = GetConfigValue(PlanType.PremiumAffiliate, "AllowProductLinks", true), MaxProductLinks = 10, PlanType = "premiumaffiliate", AllowDocumentUpload = GetConfigValue(PlanType.PremiumAffiliate, "AllowDocumentUpload", true), MaxDocuments = GetConfigValue(PlanType.PremiumAffiliate, "MaxDocuments", 10) }, _ => new PlanLimitations { PlanType = "trial", AllowDocumentUpload = false, MaxDocuments = 0 } }; } public string GetPriceId(PlanType planType, bool yearly = false) { var planName = planType switch { PlanType.Basic => yearly ? "BasicYearly" : "Basic", PlanType.Professional => yearly ? "ProfessionalYearly" : "Professional", PlanType.Premium => yearly ? "PremiumYearly" : "Premium", PlanType.PremiumAffiliate => yearly ? "PremiumAffiliateYearly" : "PremiumAffiliate", _ => "Trial" }; return _plans.TryGetValue(planName, out var config) ? config.PriceId : string.Empty; } public decimal GetPlanPrice(PlanType planType, bool yearly = false) { var planName = planType switch { PlanType.Basic => yearly ? "BasicYearly" : "Basic", PlanType.Professional => yearly ? "ProfessionalYearly" : "Professional", PlanType.Premium => yearly ? "PremiumYearly" : "Premium", PlanType.PremiumAffiliate => yearly ? "PremiumAffiliateYearly" : "PremiumAffiliate", _ => "Trial" }; return _plans.TryGetValue(planName, out var config) ? config.Price : 0; } public bool IsYearlyPlan(string priceId) { if (string.IsNullOrEmpty(priceId) || !_priceIdToPlanName.TryGetValue(priceId, out var planName)) return false; return _plans.TryGetValue(planName, out var config) && config.Interval == "year"; } public PlanConfiguration? GetPlanConfiguration(string planSectionName) { return _plans.TryGetValue(planSectionName, out var config) ? config : null; } private Dictionary LoadPlansFromConfiguration() { var plans = new Dictionary(); var plansSection = _configuration.GetSection("Plans"); foreach (var planSection in plansSection.GetChildren()) { var config = new PlanConfiguration(); planSection.Bind(config); // Mapear o nome da seção para PlanType base config.BasePlanType = planSection.Key switch { "Basic" or "BasicYearly" => PlanType.Basic, "Professional" or "ProfessionalYearly" => PlanType.Professional, "Premium" or "PremiumYearly" => PlanType.Premium, "PremiumAffiliate" or "PremiumAffiliateYearly" => PlanType.PremiumAffiliate, _ => PlanType.Trial }; plans[planSection.Key] = config; } return plans; } private Dictionary BuildPriceIdToPlanNameMap() { var map = new Dictionary(); foreach (var kvp in _plans) { if (!string.IsNullOrEmpty(kvp.Value.PriceId)) { map[kvp.Value.PriceId] = kvp.Key; } } return map; } private Dictionary BuildPriceIdToPlanTypeMap() { var map = new Dictionary(); foreach (var kvp in _plans) { if (!string.IsNullOrEmpty(kvp.Value.PriceId)) { map[kvp.Value.PriceId] = kvp.Value.BasePlanType; } } return map; } private T GetConfigValue(PlanType planType, string propertyName, T defaultValue) { // Buscar primeira nas configurações mensais, depois anuais var monthlyPlan = planType switch { PlanType.Basic => "Basic", PlanType.Professional => "Professional", PlanType.Premium => "Premium", PlanType.PremiumAffiliate => "PremiumAffiliate", _ => null }; if (monthlyPlan != null && _plans.TryGetValue(monthlyPlan, out var config)) { var property = typeof(PlanConfiguration).GetProperty(propertyName); if (property != null) { var value = property.GetValue(config); if (value != null && value is T typedValue) { return typedValue; } } } return defaultValue; } }