BCards/src/BCards.Web/Services/PlanConfigurationService.cs

239 lines
9.5 KiB
C#

using BCards.Web.Models;
namespace BCards.Web.Services;
public class PlanConfigurationService : IPlanConfigurationService
{
private readonly IConfiguration _configuration;
private readonly Dictionary<string, PlanConfiguration> _plans;
private readonly Dictionary<string, string> _priceIdToPlanName;
private readonly Dictionary<string, PlanType> _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<string, PlanConfiguration> LoadPlansFromConfiguration()
{
var plans = new Dictionary<string, PlanConfiguration>();
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<string, string> BuildPriceIdToPlanNameMap()
{
var map = new Dictionary<string, string>();
foreach (var kvp in _plans)
{
if (!string.IsNullOrEmpty(kvp.Value.PriceId))
{
map[kvp.Value.PriceId] = kvp.Key;
}
}
return map;
}
private Dictionary<string, PlanType> BuildPriceIdToPlanTypeMap()
{
var map = new Dictionary<string, PlanType>();
foreach (var kvp in _plans)
{
if (!string.IsNullOrEmpty(kvp.Value.PriceId))
{
map[kvp.Value.PriceId] = kvp.Value.BasePlanType;
}
}
return map;
}
private T GetConfigValue<T>(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;
}
}