/*
* File: D:\shadowed-realms-mobile\ShadowedRealmsMobile\src\server\ShadowedRealms.API\Services\PurchaseService.cs
* Created: 2025-10-19
* Last Modified: 2025-10-19
* Description: Concrete implementation of IPurchaseService providing comprehensive purchase and monetization business logic operations including anti-pay-to-win monitoring, ethical VIP progression, spending balance validation, and skill-based alternative systems with player protection
* Last Edit Notes: Initial creation with complete business logic implementation focusing on ethical monetization
*/
using Microsoft.Extensions.Logging;
using ShadowedRealms.Core.Interfaces;
using ShadowedRealms.Core.Interfaces.Repositories;
using ShadowedRealms.Core.Interfaces.Services;
using ShadowedRealms.Core.Models;
using ShadowedRealms.Core.Models.Player;
namespace ShadowedRealms.API.Services
{
///
/// Concrete implementation of purchase service providing ethical monetization and anti-pay-to-win business logic
///
public class PurchaseService : IPurchaseService
{
private readonly IUnitOfWork _unitOfWork;
private readonly IPurchaseLogRepository _purchaseLogRepository;
private readonly IPlayerRepository _playerRepository;
private readonly IAllianceRepository _allianceRepository;
private readonly IKingdomRepository _kingdomRepository;
private readonly ICombatLogRepository _combatLogRepository;
private readonly ILogger _logger;
// Anti-pay-to-win constants for balance
private const double MAX_SPENDING_VICTORY_INFLUENCE = 0.3; // Max 30% victory influence from spending
private const double MIN_FREE_PLAYER_EFFECTIVENESS = 0.7; // Min 70% effectiveness for skilled free players
private const double CHARGEBACK_RISK_THRESHOLD = 0.15; // 15% chargeback risk threshold
private const int VIP_SECRET_TIER_THRESHOLD = 16; // VIP tiers 16+ are secret
private const decimal HEALTHY_SPENDING_DAILY_LIMIT = 100m; // Daily spending limit for player protection
private const int FRAUD_DETECTION_LOOKBACK_DAYS = 30; // Days to analyze for fraud patterns
public PurchaseService(
IUnitOfWork unitOfWork,
IPurchaseLogRepository purchaseLogRepository,
IPlayerRepository playerRepository,
IAllianceRepository allianceRepository,
IKingdomRepository kingdomRepository,
ICombatLogRepository combatLogRepository,
ILogger logger)
{
_unitOfWork = unitOfWork ?? throw new ArgumentNullException(nameof(unitOfWork));
_purchaseLogRepository = purchaseLogRepository ?? throw new ArgumentNullException(nameof(purchaseLogRepository));
_playerRepository = playerRepository ?? throw new ArgumentNullException(nameof(playerRepository));
_allianceRepository = allianceRepository ?? throw new ArgumentNullException(nameof(allianceRepository));
_kingdomRepository = kingdomRepository ?? throw new ArgumentNullException(nameof(kingdomRepository));
_combatLogRepository = combatLogRepository ?? throw new ArgumentNullException(nameof(combatLogRepository));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
#region Purchase Processing & Validation
public async Task<(bool Success, string TransactionId, Dictionary AppliedBenefits,
Dictionary BalanceValidation)>
ProcessPurchaseAsync(int playerId, int kingdomId, Dictionary purchaseDetails,
Dictionary paymentMethod)
{
_logger.LogInformation("Processing purchase: Player {PlayerId}, Amount: {Amount}, Items: {ItemCount}",
playerId, purchaseDetails.GetValueOrDefault("Amount", 0),
((List