/*
 * File: D:\shadowed-realms-mobile\ShadowedRealmsMobile\src\server\ShadowedRealms.API\Services\PlayerService.cs
 * Created: 2025-10-19
 * Last Modified: 2025-10-26
 * Description: Concrete implementation of IPlayerService providing comprehensive player-related business logic operations including castle progression, VIP management, teleportation mechanics, and cross-system coordination
 * Last Edit Notes: Fixed all compilation errors - aligned with actual Player model properties, fixed UnitOfWork delegates, implemented missing helper methods, resolved Alliance namespace conflicts
 */

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
{
    /// <summary>
    /// Concrete implementation of player service providing business logic coordination for all player-related operations
    /// </summary>
    public class PlayerService : IPlayerService
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly IPlayerRepository _playerRepository;
        private readonly IAllianceRepository _allianceRepository;
        private readonly IKingdomRepository _kingdomRepository;
        private readonly ICombatLogRepository _combatLogRepository;
        private readonly IPurchaseLogRepository _purchaseLogRepository;
        private readonly ILogger<PlayerService> _logger;

        public PlayerService(
            IUnitOfWork unitOfWork,
            IPlayerRepository playerRepository,
            IAllianceRepository allianceRepository,
            IKingdomRepository kingdomRepository,
            ICombatLogRepository combatLogRepository,
            IPurchaseLogRepository purchaseLogRepository,
            ILogger<PlayerService> logger)
        {
            _unitOfWork = unitOfWork ?? throw new ArgumentNullException(nameof(unitOfWork));
            _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));
            _purchaseLogRepository = purchaseLogRepository ?? throw new ArgumentNullException(nameof(purchaseLogRepository));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        }

        #region Castle Management

        public async Task<(bool Success, int NewCastleLevel, Dictionary<string, object> BenefitsGranted)> UpgradeCastleAsync(
            int playerId, int kingdomId, bool useSpeedups = false)
        {
            _logger.LogInformation("Processing castle upgrade for Player {PlayerId} in Kingdom {KingdomId}",
                playerId, kingdomId);

            return await _unitOfWork.ExecuteInTransactionAsync(async (uow) =>
            {
                var player = await _playerRepository.GetByIdAsync(playerId, kingdomId);
                if (player == null)
                    throw new ArgumentException($"Player {playerId} not found in kingdom {kingdomId}");

                var currentLevel = player.CastleLevel;
                var targetLevel = currentLevel + 1;

                // Validate upgrade requirements
                var requirements = await GetCastleUpgradeRequirementsAsync(playerId, kingdomId);
                var canUpgrade = (bool)requirements["CanUpgrade"];
                if (!canUpgrade)
                {
                    return (false, currentLevel, new Dictionary<string, object>
                    {
                        ["Error"] = requirements["BlockingReasons"]
                    });
                }

                var resourceCosts = (Dictionary<string, long>)requirements["ResourceCosts"];
                var timeCost = (TimeSpan)requirements["UpgradeTime"];

                // Apply VIP benefits
                var vipTimeReduction = CalculateVipTimeReduction(player.VipLevel, timeCost);
                var finalUpgradeTime = useSpeedups ? TimeSpan.Zero : timeCost - vipTimeReduction;

                // Apply alliance research bonuses
                Dictionary<string, object> allianceBonuses = new();
                if (player.AllianceId.HasValue)
                {
                    var alliance = await _allianceRepository.GetByIdAsync(player.AllianceId.Value, kingdomId);
                    if (alliance != null)
                    {
                        allianceBonuses = CalculateAllianceConstructionBonuses(alliance);
                        // Apply alliance resource reduction
                        foreach (var resource in resourceCosts.Keys.ToList())
                        {
                            var reduction = (double)(allianceBonuses[$"{resource}Reduction"] ?? 0.0);
                            resourceCosts[resource] = (long)(resourceCosts[resource] * (1.0 - reduction));
                        }
                    }
                }

                // Spend resources
                var spendResult = await SpendResourcesAsync(playerId, kingdomId, resourceCosts,
                    $"Castle upgrade to level {targetLevel}");
                if (!spendResult.Success)
                {
                    return (false, currentLevel, new Dictionary<string, object>
                    {
                        ["Error"] = spendResult.ValidationMessage
                    });
                }

                // Update castle level and apply benefits
                var upgradeSuccess = await UpdateCastleLevelAsync(playerId, kingdomId, targetLevel);
                if (!upgradeSuccess)
                    throw new InvalidOperationException("Failed to update castle level");

                // Calculate and apply upgrade benefits
                var benefitsGranted = CalculateCastleLevelBenefits(targetLevel);

                // Update player power
                var (newPower, powerBreakdown) = await RecalculatePlayerPowerAsync(playerId, kingdomId);
                benefitsGranted["PowerIncrease"] = newPower - player.Power;
                benefitsGranted["NewPowerTotal"] = newPower;

                // Update experience (simulate experience system)
                var experienceGain = targetLevel * 1000;
                var playerLevel = CalculatePlayerLevelFromCastle(targetLevel);
                var (levelUp, newLevel, levelRewards) = await ProcessExperienceGainAsync(
                    playerId, kingdomId, experienceGain, "Castle Upgrade");

                if (levelUp)
                {
                    benefitsGranted["LevelUp"] = true;
                    benefitsGranted["NewPlayerLevel"] = newLevel;
                    benefitsGranted["LevelRewards"] = levelRewards;
                }

                // Process achievements
                await ProcessAchievementProgressAsync(playerId, kingdomId, "CastleUpgrade", targetLevel);

                _logger.LogInformation("Castle upgrade completed for Player {PlayerId}: Level {OldLevel} → {NewLevel}",
                    playerId, currentLevel, targetLevel);

                return (true, targetLevel, benefitsGranted);
            });
        }

        public async Task<Dictionary<string, object>> GetCastleUpgradeRequirementsAsync(int playerId, int kingdomId)
        {
            var player = await _playerRepository.GetByIdAsync(playerId, kingdomId);
            if (player == null)
                throw new ArgumentException($"Player {playerId} not found");

            var currentLevel = player.CastleLevel;
            var targetLevel = currentLevel + 1;
            var blockingReasons = new List<string>();

            // Check maximum level cap (Phase 1: Level 30)
            if (targetLevel > 30)
            {
                blockingReasons.Add("Maximum castle level reached (Level 30 cap during Phase 1)");
            }

            // Calculate resource requirements with exponential scaling
            var resourceCosts = new Dictionary<string, long>
            {
                ["Wood"] = (long)(1000 * Math.Pow(1.5, targetLevel - 1)),
                ["Iron"] = (long)(600 * Math.Pow(1.5, targetLevel - 1)),
                ["Food"] = (long)(1200 * Math.Pow(1.5, targetLevel - 1)),
                ["Silver"] = (long)(400 * Math.Pow(1.5, targetLevel - 1)),
                ["Mithril"] = (long)(100 * Math.Pow(1.5, targetLevel - 1))
            };

            // Check resource availability
            var hasResources = true;
            var missingResources = new Dictionary<string, long>();
            foreach (var cost in resourceCosts)
            {
                var playerResource = GetPlayerResourceAmount(player, cost.Key);
                if (playerResource < cost.Value)
                {
                    hasResources = false;
                    missingResources[cost.Key] = cost.Value - playerResource;
                }
            }

            if (!hasResources)
            {
                blockingReasons.Add($"Insufficient resources: {string.Join(", ", missingResources.Select(r => $"{r.Key}: {r.Value:N0}"))}");
            }

            // Calculate upgrade time with level scaling
            var baseUpgradeTime = TimeSpan.FromMinutes(30 * Math.Pow(1.3, targetLevel - 1));

            // Check prerequisite buildings for higher levels
            if (targetLevel > 10)
            {
                var requiredBuildings = GetRequiredBuildingsForLevel(targetLevel);
                // Building level validation would go here when building system is implemented
            }

            var canUpgrade = blockingReasons.Count == 0;

            return new Dictionary<string, object>
            {
                ["CanUpgrade"] = canUpgrade,
                ["TargetLevel"] = targetLevel,
                ["ResourceCosts"] = resourceCosts,
                ["UpgradeTime"] = baseUpgradeTime,
                ["BlockingReasons"] = blockingReasons,
                ["HasSufficientResources"] = hasResources,
                ["MissingResources"] = missingResources
            };
        }

        public async Task<(bool Success, DateTime CompletionTime, Dictionary<string, object> ResourcesConsumed)> StartConstructionAsync(
            int playerId, int kingdomId, string buildingType, bool useSpeedups = false)
        {
            _logger.LogInformation("Starting construction for Player {PlayerId}: {BuildingType}",
                playerId, buildingType);

            return await _unitOfWork.ExecuteInTransactionAsync(async (uow) =>
            {
                var player = await _playerRepository.GetByIdAsync(playerId, kingdomId);
                if (player == null)
                    throw new ArgumentException($"Player {playerId} not found");

                // Calculate construction requirements
                var buildingCosts = GetBuildingConstructionCosts(buildingType, 1);
                var constructionTime = GetBuildingConstructionTime(buildingType, 1);

                // Apply VIP and alliance bonuses
                var vipTimeReduction = CalculateVipTimeReduction(player.VipLevel, constructionTime);
                var finalConstructionTime = useSpeedups ? TimeSpan.Zero : constructionTime - vipTimeReduction;
                var completionTime = DateTime.UtcNow.Add(finalConstructionTime);

                // Spend resources
                var spendResult = await SpendResourcesAsync(playerId, kingdomId, buildingCosts,
                    $"{buildingType} construction");
                if (!spendResult.Success)
                {
                    return (false, DateTime.UtcNow, new Dictionary<string, object>
                    {
                        ["Error"] = spendResult.ValidationMessage
                    });
                }

                _logger.LogInformation("Construction started for Player {PlayerId}: {BuildingType}, Completion: {CompletionTime}",
                    playerId, buildingType, completionTime);

                return (true, completionTime, buildingCosts.ToDictionary(kvp => kvp.Key, kvp => (object)kvp.Value));
            });
        }

        #endregion

        #region VIP Management

        public async Task<(bool TierChanged, int NewTier, bool IsSecretTier, Dictionary<string, object> NewBenefits, bool ChargebackRisk)>
            ProcessVipAdvancementAsync(int playerId, int kingdomId, decimal purchaseAmount)
        {
            _logger.LogInformation("Processing VIP advancement for Player {PlayerId}: Purchase amount {Amount}",
                playerId, purchaseAmount);

            return await _unitOfWork.ExecuteInTransactionAsync(async (uow) =>
            {
                var player = await _playerRepository.GetByIdAsync(playerId, kingdomId);
                if (player == null)
                    throw new ArgumentException($"Player {playerId} not found");

                var oldTier = player.VipLevel;

                // Update VIP tier through repository
                var (tierUpdated, newTier, chargebackRisk) = await UpdateVipTierAsync(
                    playerId, kingdomId, purchaseAmount);

                var isSecretTier = newTier >= 16; // Secret tiers start at 16
                var newBenefits = new Dictionary<string, object>();

                if (tierUpdated)
                {
                    // Calculate new VIP benefits
                    newBenefits = await GrantVipBenefitsAsync(playerId, kingdomId, newTier);

                    // Notify alliance of VIP advancement (if in alliance)
                    if (player.AllianceId.HasValue)
                    {
                        await NotifyAllianceOfVipAdvancement(player.AllianceId.Value, kingdomId,
                            playerId, oldTier, newTier, isSecretTier);
                    }

                    // Process achievements for VIP advancement
                    await ProcessAchievementProgressAsync(playerId, kingdomId, "VipAdvancement", newTier);

                    _logger.LogInformation("VIP tier advanced for Player {PlayerId}: Tier {OldTier} → {NewTier} (Secret: {IsSecret})",
                        playerId, oldTier, newTier, isSecretTier);
                }

                return (tierUpdated, newTier, isSecretTier, newBenefits, chargebackRisk);
            });
        }

        public async Task<Dictionary<string, object>> GrantVipBenefitsAsync(int playerId, int kingdomId, int vipTier)
        {
            var benefits = new Dictionary<string, object>();

            // Calculate VIP benefits based on tier
            benefits["ConstructionSpeedBonus"] = Math.Min(vipTier * 2, 50); // Max 50% at VIP 25
            benefits["ResearchSpeedBonus"] = Math.Min(vipTier * 2, 50);
            benefits["TrainingSpeedBonus"] = Math.Min(vipTier * 1.5, 40);
            benefits["ResourceProductionBonus"] = Math.Min(vipTier * 1, 30);

            // March speed increases
            benefits["MarchSpeedBonus"] = Math.Min(vipTier * 1, 25);

            // Queue slots
            benefits["BuildingQueueSlots"] = Math.Min(1 + (vipTier / 5), 4);
            benefits["ResearchQueueSlots"] = Math.Min(1 + (vipTier / 8), 3);

            // Teleportation benefits
            if (vipTier >= 6)
                benefits["FreeTeleportsPerDay"] = Math.Min((vipTier - 5) / 2, 5);

            // Advanced benefits for higher tiers
            if (vipTier >= 10)
            {
                benefits["AutoResourceCollection"] = true;
                benefits["AdvancedIntelligence"] = true;
            }

            if (vipTier >= 15)
            {
                benefits["ExclusiveEquipment"] = true;
                benefits["PremiumDragonSkills"] = true;
            }

            // Secret tier benefits (16+)
            if (vipTier >= 16)
            {
                benefits["SecretTierStatus"] = true;
                benefits["ExclusiveTerritoryAccess"] = true;
                benefits["AdvancedCombatBonus"] = (vipTier - 15) * 2;

                // Hidden from other players
                benefits["HideVipTierFromOthers"] = true;
            }

            _logger.LogInformation("VIP benefits granted for Player {PlayerId}: Tier {VipTier}",
                playerId, vipTier);

            return benefits;
        }

        public async Task<(bool CanUse, string Reason, Dictionary<string, object> PrivilegeDetails)> ValidateVipPrivilegeAsync(
            int playerId, int kingdomId, string privilegeType)
        {
            var player = await _playerRepository.GetByIdAsync(playerId, kingdomId);
            if (player == null)
                return (false, "Player not found", new Dictionary<string, object>());

            var details = new Dictionary<string, object>();

            return privilegeType.ToLower() switch
            {
                "free_teleport" => await ValidateFreeTeleportPrivilege(player, details),
                "auto_collection" => ValidateAutoCollectionPrivilege(player, details),
                "advanced_intelligence" => ValidateAdvancedIntelligencePrivilege(player, details),
                "exclusive_equipment" => ValidateExclusiveEquipmentPrivilege(player, details),
                _ => (false, "Unknown privilege type", details)
            };
        }

        #endregion

        #region Teleportation System

        public async Task<(bool Success, int NewX, int NewY, Dictionary<string, object> CostsApplied, DateTime NextTeleportAvailable)>
            ExecuteTeleportationAsync(int playerId, int kingdomId, int targetX, int targetY, string teleportType)
        {
            _logger.LogInformation("Processing teleportation for Player {PlayerId}: ({TargetX}, {TargetY}) Type: {TeleportType}",
                playerId, targetX, targetY, teleportType);

            return await _unitOfWork.ExecuteInTransactionAsync(async (uow) =>
            {
                // Validate teleportation
                var (canTeleport, reason, costs, restrictions) = await ValidateTeleportationAsync(
                    playerId, kingdomId, targetX, targetY);
                if (!canTeleport)
                {
                    return (false, 0, 0, new Dictionary<string, object> { ["Error"] = reason }, DateTime.UtcNow);
                }

                // Check for blocks
                var (isBlocked, blockReason, nearbyPlayers) = await CheckTeleportationBlocksAsync(
                    playerId, kingdomId, targetX, targetY);
                if (isBlocked)
                {
                    return (false, 0, 0, new Dictionary<string, object> { ["Error"] = blockReason }, DateTime.UtcNow);
                }

                var player = await _playerRepository.GetByIdAsync(playerId, kingdomId);
                if (player == null)
                    throw new ArgumentException($"Player {playerId} not found");

                var costsApplied = new Dictionary<string, object>();

                // Apply costs based on teleport type
                switch (teleportType.ToLower())
                {
                    case "free":
                        // Check VIP free teleport allowance
                        var vipBenefits = await GrantVipBenefitsAsync(playerId, kingdomId, player.VipLevel);
                        var freeTeleports = (int)(vipBenefits.GetValueOrDefault("FreeTeleportsPerDay", 0));
                        if (freeTeleports <= 0)
                        {
                            return (false, 0, 0, new Dictionary<string, object>
                            {
                                ["Error"] = "No free teleports remaining"
                            }, DateTime.UtcNow);
                        }
                        costsApplied["FreeTeleportUsed"] = true;
                        break;

                    case "paid":
                        var goldCost = (long)costs["GoldCost"];
                        var spendResult = await SpendResourcesAsync(playerId, kingdomId,
                            new Dictionary<string, long> { ["Gold"] = goldCost }, "Teleportation");
                        if (!spendResult.Success)
                        {
                            return (false, 0, 0, new Dictionary<string, object>
                            {
                                ["Error"] = spendResult.ValidationMessage
                            }, DateTime.UtcNow);
                        }
                        costsApplied["GoldSpent"] = goldCost;
                        break;

                    case "alliance":
                        if (!player.AllianceId.HasValue)
                        {
                            return (false, 0, 0, new Dictionary<string, object>
                            {
                                ["Error"] = "Must be in alliance for alliance teleports"
                            }, DateTime.UtcNow);
                        }
                        costsApplied["AllianceTeleportUsed"] = true;
                        break;
                }

                // Update player coordinates
                var teleportSuccess = await UpdateCoordinatesAsync(playerId, kingdomId, targetX, targetY);
                if (!teleportSuccess)
                    throw new InvalidOperationException("Failed to update player coordinates");

                // Set cooldown
                var nextTeleportTime = DateTime.UtcNow.AddHours(GetTeleportCooldownHours(teleportType));
                await UpdateLastTeleportTimeAsync(playerId, kingdomId, DateTime.UtcNow);

                _logger.LogInformation("Teleportation completed for Player {PlayerId}: New position ({NewX}, {NewY})",
                    playerId, targetX, targetY);

                return (true, targetX, targetY, costsApplied, nextTeleportTime);
            });
        }

        public async Task<(bool CanTeleport, string Reason, Dictionary<string, object> Costs, List<string> Restrictions)>
            ValidateTeleportationAsync(int playerId, int kingdomId, int targetX, int targetY)
        {
            var player = await _playerRepository.GetByIdAsync(playerId, kingdomId);
            if (player == null)
                return (false, "Player not found", new Dictionary<string, object>(), new List<string>());

            var restrictions = new List<string>();
            var costs = new Dictionary<string, object>();

            // Check cooldown (simulate LastTeleportTime)
            var lastTeleportTime = GetLastTeleportTime(player);
            if (lastTeleportTime.HasValue)
            {
                var cooldownRemaining = GetRemainingTeleportCooldown(lastTeleportTime.Value);
                if (cooldownRemaining > TimeSpan.Zero)
                {
                    return (false, $"Teleport on cooldown for {cooldownRemaining.TotalMinutes:F0} minutes",
                           costs, restrictions);
                }
            }

            // Calculate distance and costs
            var distance = CalculateDistance(player.CoordinateX, player.CoordinateY, targetX, targetY);
            var baseCost = Math.Max(100, (long)(distance * 10));

            // Apply VIP discount
            var vipDiscount = Math.Min(player.VipLevel * 2, 50) / 100.0;
            var finalCost = (long)(baseCost * (1.0 - vipDiscount));

            costs["GoldCost"] = finalCost;
            costs["Distance"] = distance;
            costs["VipDiscount"] = $"{vipDiscount * 100}%";

            // Check for map boundaries
            if (targetX < 0 || targetX > 1000 || targetY < 0 || targetY > 1000)
            {
                return (false, "Target coordinates outside map boundaries", costs, restrictions);
            }

            // Check for march restrictions
            var hasActiveMarch = await CheckForActiveMarch(playerId, kingdomId);
            if (hasActiveMarch)
            {
                restrictions.Add("Cannot teleport while troops are marching");
            }

            // Check for combat restrictions
            var recentCombat = await CheckRecentCombatActivity(playerId, kingdomId, TimeSpan.FromMinutes(30));
            if (recentCombat)
            {
                restrictions.Add("Cannot teleport within 30 minutes of combat");
            }

            var canTeleport = restrictions.Count == 0;
            var reason = canTeleport ? "Teleportation allowed" : string.Join("; ", restrictions);

            return (canTeleport, reason, costs, restrictions);
        }

        public async Task<(bool IsBlocked, string BlockReason, List<(int BlockingPlayerId, string PlayerName, double Distance)> NearbyPlayers)>
            CheckTeleportationBlocksAsync(int playerId, int kingdomId, int targetX, int targetY)
        {
            const double MIN_TELEPORT_DISTANCE = 50.0; // Minimum distance from other players

            // Get nearby players within blocking range
            var nearbyPlayers = await GetPlayersNearCoordinatesAsync(
                kingdomId, targetX, targetY, MIN_TELEPORT_DISTANCE);

            var blockingPlayers = new List<(int PlayerId, string PlayerName, double Distance)>();

            foreach (var nearbyPlayer in nearbyPlayers)
            {
                if (nearbyPlayer.Id == playerId) continue; // Skip self

                var distance = CalculateDistance(targetX, targetY,
                    nearbyPlayer.CoordinateX, nearbyPlayer.CoordinateY);

                if (distance < MIN_TELEPORT_DISTANCE)
                {
                    blockingPlayers.Add((nearbyPlayer.Id, nearbyPlayer.Name, distance));
                }
            }

            var isBlocked = blockingPlayers.Count > 0;
            var blockReason = isBlocked ?
                $"Too close to other players (minimum distance: {MIN_TELEPORT_DISTANCE:F0})" :
                "No blocking players detected";

            return (isBlocked, blockReason, blockingPlayers);
        }

        #endregion

        #region Resource Management

        public async Task<Dictionary<string, object>> CollectResourcesAsync(int playerId, int kingdomId)
        {
            _logger.LogInformation("Collecting resources for Player {PlayerId}", playerId);

            return await _unitOfWork.ExecuteInTransactionAsync(async (uow) =>
            {
                var player = await _playerRepository.GetByIdAsync(playerId, kingdomId);
                if (player == null)
                    throw new ArgumentException($"Player {playerId} not found");

                // Calculate production since last collection
                var productionRates = await CalculateResourceProductionAsync(playerId, kingdomId);
                var lastCollectionTime = GetLastResourceCollectionTime(player);
                var timeSinceLastCollection = DateTime.UtcNow - lastCollectionTime;
                var hoursOfProduction = Math.Min(timeSinceLastCollection.TotalHours, 8.0); // Max 8 hours stored

                var resourcesGained = new Dictionary<string, long>();
                var newResourceTotals = new Dictionary<string, long>();

                foreach (var resource in new[] { "Wood", "Iron", "Food", "Silver", "Mithril" })
                {
                    var productionPerHour = (long)productionRates[$"{resource}PerHour"];
                    var gained = (long)(productionPerHour * hoursOfProduction);

                    var currentAmount = GetPlayerResourceAmount(player, resource);
                    var newAmount = currentAmount + gained;

                    resourcesGained[resource] = gained;
                    newResourceTotals[resource] = newAmount;
                }

                // Update player resources and collection time
                await UpdateResourcesAsync(playerId, kingdomId, newResourceTotals, "Resource Collection");
                await UpdateLastResourceCollectionTimeAsync(playerId, kingdomId, DateTime.UtcNow);

                _logger.LogInformation("Resources collected for Player {PlayerId}: {ResourcesGained}",
                    playerId, string.Join(", ", resourcesGained.Select(r => $"{r.Key}: {r.Value:N0}")));

                return new Dictionary<string, object>
                {
                    ["ResourcesGained"] = resourcesGained,
                    ["NewResourceTotals"] = newResourceTotals,
                    ["ProductionRates"] = productionRates,
                    ["HoursCollected"] = hoursOfProduction
                };
            });
        }

        public async Task<(bool Success, Dictionary<string, long> NewResourceTotals, string ValidationMessage)>
            SpendResourcesAsync(int playerId, int kingdomId, Dictionary<string, long> resourceCosts, string purpose)
        {
            var player = await _playerRepository.GetByIdAsync(playerId, kingdomId);
            if (player == null)
                return (false, new Dictionary<string, long>(), $"Player {playerId} not found");

            var newTotals = new Dictionary<string, long>();
            var validationErrors = new List<string>();

            // Validate each resource requirement
            foreach (var cost in resourceCosts)
            {
                var currentAmount = GetPlayerResourceAmount(player, cost.Key);
                if (currentAmount < cost.Value)
                {
                    validationErrors.Add($"Insufficient {cost.Key}: Need {cost.Value:N0}, Have {currentAmount:N0}");
                }
                else
                {
                    newTotals[cost.Key] = currentAmount - cost.Value;
                }
            }

            if (validationErrors.Count > 0)
            {
                return (false, new Dictionary<string, long>(), string.Join("; ", validationErrors));
            }

            // Apply resource spending
            var updateSuccess = await UpdateResourcesAsync(playerId, kingdomId, newTotals, purpose);
            if (!updateSuccess)
                return (false, new Dictionary<string, long>(), "Failed to update player resources");

            _logger.LogInformation("Resources spent for Player {PlayerId} ({Purpose}): {ResourceCosts}",
                playerId, purpose, string.Join(", ", resourceCosts.Select(r => $"{r.Key}: {r.Value:N0}")));

            return (true, newTotals, "Resources spent successfully");
        }

        public async Task<Dictionary<string, object>> CalculateResourceProductionAsync(int playerId, int kingdomId)
        {
            var player = await _playerRepository.GetByIdAsync(playerId, kingdomId);
            if (player == null)
                throw new ArgumentException($"Player {playerId} not found");

            var baseProduction = GetBaseResourceProduction(player.CastleLevel);
            var production = new Dictionary<string, object>();

            foreach (var resource in new[] { "Wood", "Iron", "Food", "Silver", "Mithril" })
            {
                var baseAmount = baseProduction[resource];
                var totalProduction = baseAmount;

                // Apply building bonuses (would come from building system)
                var buildingBonus = CalculateBuildingProductionBonus(resource, player.CastleLevel);
                totalProduction += buildingBonus;

                // Apply VIP bonuses
                var vipBenefits = await GrantVipBenefitsAsync(playerId, kingdomId, player.VipLevel);
                var vipBonus = (int)vipBenefits.GetValueOrDefault("ResourceProductionBonus", 0);
                totalProduction = (long)(totalProduction * (1.0 + vipBonus / 100.0));

                // Apply alliance research bonuses
                if (player.AllianceId.HasValue)
                {
                    var alliance = await _allianceRepository.GetByIdAsync(player.AllianceId.Value, kingdomId);
                    if (alliance != null)
                    {
                        var allianceBonus = GetAllianceResourceBonus(alliance, resource);
                        totalProduction = (long)(totalProduction * (1.0 + allianceBonus / 100.0));
                    }
                }

                production[$"{resource}PerHour"] = totalProduction;
                production[$"{resource}BaseProduction"] = baseAmount;
                production[$"{resource}BuildingBonus"] = buildingBonus;
                production[$"{resource}VipBonus"] = $"{vipBonus}%";
            }

            return production;
        }

        #endregion

        #region Player Progression

        public async Task<(bool LevelUp, int NewLevel, Dictionary<string, object> LevelRewards)>
            ProcessExperienceGainAsync(int playerId, int kingdomId, long experienceGained, string source)
        {
            _logger.LogInformation("Processing experience gain for Player {PlayerId}: {Experience} from {Source}",
                playerId, experienceGained, source);

            return await _unitOfWork.ExecuteInTransactionAsync(async (uow) =>
            {
                var player = await _playerRepository.GetByIdAsync(playerId, kingdomId);
                if (player == null)
                    throw new ArgumentException($"Player {playerId} not found");

                var oldLevel = CalculatePlayerLevelFromCastle(player.CastleLevel);
                var oldExperience = CalculateExperienceFromLevel(oldLevel);
                var newExperience = oldExperience + experienceGained;

                // Calculate new level
                var newLevel = CalculateLevelFromExperience(newExperience);
                var levelUp = newLevel > oldLevel;
                var levelRewards = new Dictionary<string, object>();

                // Update experience and level (simulated via castle level for now)
                await UpdateExperienceAsync(playerId, kingdomId, newExperience, newLevel);

                if (levelUp)
                {
                    // Calculate level up rewards
                    for (int level = oldLevel + 1; level <= newLevel; level++)
                    {
                        var rewards = GetLevelUpRewards(level);
                        foreach (var reward in rewards)
                        {
                            if (levelRewards.ContainsKey(reward.Key))
                            {
                                levelRewards[reward.Key] = (long)levelRewards[reward.Key] + (long)reward.Value;
                            }
                            else
                            {
                                levelRewards[reward.Key] = reward.Value;
                            }
                        }
                    }

                    // Apply level up rewards (simulated - ActionPoints would be in player model)
                    if (levelRewards.ContainsKey("ActionPoints"))
                    {
                        await UpdateActionPointsAsync(playerId, kingdomId,
                            GetPlayerActionPoints(player) + (long)levelRewards["ActionPoints"]);
                    }

                    _logger.LogInformation("Player level up: Player {PlayerId} Level {OldLevel} → {NewLevel}",
                        playerId, oldLevel, newLevel);
                }

                return (levelUp, newLevel, levelRewards);
            });
        }

        public async Task<(long NewPower, Dictionary<string, long> PowerBreakdown)> RecalculatePlayerPowerAsync(int playerId, int kingdomId)
        {
            var player = await _playerRepository.GetByIdAsync(playerId, kingdomId);
            if (player == null)
                throw new ArgumentException($"Player {playerId} not found");

            var powerBreakdown = new Dictionary<string, long>();

            // Castle power
            var castlePower = CalculateCastlePower(player.CastleLevel);
            powerBreakdown["Castle"] = castlePower;

            // Troop power
            var troopPower = CalculateTroopPower(player);
            powerBreakdown["Troops"] = troopPower;

            // Research power (placeholder)
            var researchPower = CalculateResearchPower(player);
            powerBreakdown["Research"] = researchPower;

            // Equipment power (placeholder)
            var equipmentPower = CalculateEquipmentPower(player);
            powerBreakdown["Equipment"] = equipmentPower;

            // Dragon power (placeholder)
            var dragonPower = CalculateDragonPower(player);
            powerBreakdown["Dragon"] = dragonPower;

            var totalPower = powerBreakdown.Values.Sum();

            // Update player power
            await UpdatePowerAsync(playerId, kingdomId, totalPower);

            _logger.LogInformation("Power recalculated for Player {PlayerId}: {OldPower} → {NewPower}",
                playerId, player.Power, totalPower);

            return (totalPower, powerBreakdown);
        }

        public async Task<(bool NewAchievement, List<string> UnlockedAchievements, Dictionary<string, object> Rewards)>
            ProcessAchievementProgressAsync(int playerId, int kingdomId, string achievementType, long progressValue)
        {
            _logger.LogInformation("Processing achievement progress for Player {PlayerId}: {Type} = {Value}",
                playerId, achievementType, progressValue);

            var unlockedAchievements = new List<string>();
            var rewards = new Dictionary<string, object>();

            // Get achievement definitions for the type
            var achievements = GetAchievementsForType(achievementType);

            foreach (var achievement in achievements)
            {
                if (progressValue >= achievement.RequiredValue)
                {
                    // Check if already unlocked
                    var hasAchievement = await HasAchievementAsync(playerId, kingdomId, achievement.Id);
                    if (!hasAchievement)
                    {
                        await GrantAchievementAsync(playerId, kingdomId, achievement.Id);
                        unlockedAchievements.Add(achievement.Name);

                        // Add achievement rewards
                        foreach (var reward in achievement.Rewards)
                        {
                            if (rewards.ContainsKey(reward.Key))
                            {
                                rewards[reward.Key] = (long)rewards[reward.Key] + (long)reward.Value;
                            }
                            else
                            {
                                rewards[reward.Key] = reward.Value;
                            }
                        }
                    }
                }
            }

            var hasNewAchievements = unlockedAchievements.Count > 0;

            if (hasNewAchievements)
            {
                _logger.LogInformation("Achievements unlocked for Player {PlayerId}: {Achievements}",
                    playerId, string.Join(", ", unlockedAchievements));
            }

            return (hasNewAchievements, unlockedAchievements, rewards);
        }

        #endregion

        #region Combat Integration

        public async Task<(bool CanMarch, Dictionary<string, object> MarchDetails, DateTime EstimatedArrival, List<string> Warnings)>
            PrepareCombatMarchAsync(int playerId, int kingdomId, Dictionary<string, int> troopComposition, string marchType)
        {
            _logger.LogInformation("Preparing combat march for Player {PlayerId}: Type {MarchType}",
                playerId, marchType);

            var player = await _playerRepository.GetByIdAsync(playerId, kingdomId);
            if (player == null)
                return (false, new Dictionary<string, object>(), DateTime.UtcNow,
                       new List<string> { "Player not found" });

            var warnings = new List<string>();
            var marchDetails = new Dictionary<string, object>();

            // Validate troop availability
            var troopValidation = ValidateTroopAvailability(player, troopComposition);
            if (!troopValidation.IsValid)
            {
                return (false, marchDetails, DateTime.UtcNow, troopValidation.Errors);
            }

            // Calculate march speed based on troops
            var marchSpeed = CalculateMarchSpeed(troopComposition, player.VipLevel);
            marchDetails["MarchSpeed"] = marchSpeed;
            marchDetails["TroopComposition"] = troopComposition;
            marchDetails["MarchType"] = marchType;

            // Apply VIP march speed bonuses
            var vipBenefits = await GrantVipBenefitsAsync(playerId, kingdomId, player.VipLevel);
            var speedBonus = (int)vipBenefits.GetValueOrDefault("MarchSpeedBonus", 0);
            var finalSpeed = marchSpeed * (1.0 + speedBonus / 100.0);
            marchDetails["FinalMarchSpeed"] = finalSpeed;
            marchDetails["VipSpeedBonus"] = $"{speedBonus}%";

            // Estimated arrival (placeholder - would need target coordinates)
            var estimatedArrival = DateTime.UtcNow.AddMinutes(30); // Default 30 minutes

            // Check for warnings
            var actionPoints = GetPlayerActionPoints(player);
            if (marchType == "Attack" && actionPoints < 1)
            {
                warnings.Add("Low action points - march may be less effective");
            }

            if (player.AllianceId == null && marchType == "Defense")
            {
                warnings.Add("Not in alliance - limited defensive coordination available");
            }

            return (true, marchDetails, estimatedArrival, warnings);
        }

        public async Task<Dictionary<string, object>> ProcessCombatResultsAsync(int playerId, int kingdomId, Dictionary<string, object> combatResult)
        {
            _logger.LogInformation("Processing combat results for Player {PlayerId}", playerId);

            return await _unitOfWork.ExecuteInTransactionAsync(async (uow) =>
            {
                var player = await _playerRepository.GetByIdAsync(playerId, kingdomId);
                if (player == null)
                    throw new ArgumentException($"Player {playerId} not found");

                var updates = new Dictionary<string, object>();

                // Process troop losses
                if (combatResult.ContainsKey("TroopLosses"))
                {
                    var losses = (Dictionary<string, int>)combatResult["TroopLosses"];
                    updates["TroopLossesProcessed"] = losses;
                }

                // Process power changes
                if (combatResult.ContainsKey("PowerLost"))
                {
                    var powerLost = (long)combatResult["PowerLost"];
                    var newPower = Math.Max(0, player.Power - powerLost);
                    await UpdatePowerAsync(playerId, kingdomId, newPower);
                    updates["PowerLost"] = powerLost;
                    updates["NewPower"] = newPower;
                }

                // Process experience gains
                if (combatResult.ContainsKey("ExperienceGained"))
                {
                    var experience = (long)combatResult["ExperienceGained"];
                    var (levelUp, newLevel, levelRewards) = await ProcessExperienceGainAsync(
                        playerId, kingdomId, experience, "Combat");

                    updates["ExperienceGained"] = experience;
                    if (levelUp)
                    {
                        updates["LevelUp"] = true;
                        updates["NewLevel"] = newLevel;
                        updates["LevelRewards"] = levelRewards;
                    }
                }

                // Process achievements
                if (combatResult.ContainsKey("Victory") && (bool)combatResult["Victory"])
                {
                    await ProcessAchievementProgressAsync(playerId, kingdomId, "CombatVictory", 1);
                    updates["VictoryAchievementProcessed"] = true;
                }

                _logger.LogInformation("Combat results processed for Player {PlayerId}: {Updates}",
                    playerId, string.Join(", ", updates.Keys));

                return updates;
            });
        }

        #endregion

        #region Social Integration

        public async Task<(bool Success, Dictionary<string, object> AllianceDetails, List<string> NewPrivileges)>
            ProcessAllianceJoinAsync(int playerId, int kingdomId, int allianceId, bool isInvitation)
        {
            _logger.LogInformation("Processing alliance join for Player {PlayerId}: Alliance {AllianceId} (Invitation: {IsInvitation})",
                playerId, allianceId, isInvitation);

            return await _unitOfWork.ExecuteInTransactionAsync(async (uow) =>
            {
                var player = await _playerRepository.GetByIdAsync(playerId, kingdomId);
                if (player == null)
                    return (false, new Dictionary<string, object>(), new List<string> { "Player not found" });

                var alliance = await _allianceRepository.GetByIdAsync(allianceId, kingdomId);
                if (alliance == null)
                    return (false, new Dictionary<string, object>(), new List<string> { "Alliance not found" });

                if (player.AllianceId.HasValue)
                    return (false, new Dictionary<string, object>(), new List<string> { "Player already in alliance" });

                // Update player's alliance
                var joinSuccess = await UpdateAllianceAsync(playerId, kingdomId, allianceId);
                if (!joinSuccess)
                    return (false, new Dictionary<string, object>(), new List<string> { "Failed to join alliance" });

                // Get alliance details and privileges
                var allianceDetails = new Dictionary<string, object>
                {
                    ["Name"] = alliance.Name,
                    ["Tag"] = alliance.Tag,
                    ["Level"] = alliance.Level,
                    ["MemberCount"] = alliance.MemberCount + 1,
                    ["Power"] = alliance.Power
                };

                var privileges = new List<string>
                {
                    "Alliance Chat",
                    "Alliance Help",
                    "Alliance Research Benefits",
                    "Alliance Territory Access"
                };

                // Grant alliance research benefits immediately
                await RecalculatePlayerPowerAsync(playerId, kingdomId);

                _logger.LogInformation("Player {PlayerId} joined Alliance {AllianceId} successfully",
                    playerId, allianceId);

                return (true, allianceDetails, privileges);
            });
        }

        public async Task<(bool Success, Dictionary<string, object> BenefitsLost, bool TerritoryEviction)>
            ProcessAllianceLeaveAsync(int playerId, int kingdomId, string reason)
        {
            _logger.LogInformation("Processing alliance leave for Player {PlayerId}: Reason {Reason}",
                playerId, reason);

            return await _unitOfWork.ExecuteInTransactionAsync(async (uow) =>
            {
                var player = await _playerRepository.GetByIdAsync(playerId, kingdomId);
                if (player == null)
                    return (false, new Dictionary<string, object>(), false);

                if (!player.AllianceId.HasValue)
                    return (false, new Dictionary<string, object> { ["Error"] = "Player not in alliance" }, false);

                var alliance = await _allianceRepository.GetByIdAsync(player.AllianceId.Value, kingdomId);
                var benefitsLost = new Dictionary<string, object>();

                // Calculate lost benefits
                if (alliance != null)
                {
                    benefitsLost["ResearchBonuses"] = GetAllianceResearchBonuses(alliance);
                    benefitsLost["TerritoryAccess"] = "All alliance territory access revoked";
                }

                // Remove player from alliance
                var leaveSuccess = await UpdateAllianceAsync(playerId, kingdomId, null);
                if (!leaveSuccess)
                    return (false, new Dictionary<string, object>(), false);

                // Check for territory eviction
                var territoryEviction = await CheckTerritoryEviction(playerId, kingdomId);

                // Recalculate power without alliance bonuses
                await RecalculatePlayerPowerAsync(playerId, kingdomId);

                _logger.LogInformation("Player {PlayerId} left alliance: Reason {Reason}, Territory eviction: {Eviction}",
                    playerId, reason, territoryEviction);

                return (true, benefitsLost, territoryEviction);
            });
        }

        #endregion

        #region Anti-Exploitation

        public async Task<(bool IsValid, List<string> Warnings, Dictionary<string, object> RiskFactors)>
            ValidatePlayerActionAsync(int playerId, int kingdomId, string actionType, Dictionary<string, object> actionDetails)
        {
            var warnings = new List<string>();
            var riskFactors = new Dictionary<string, object>();

            var player = await _playerRepository.GetByIdAsync(playerId, kingdomId);
            if (player == null)
                return (false, new List<string> { "Player not found" }, riskFactors);

            // Rate limiting checks
            var actionFrequency = await CheckActionFrequency(playerId, kingdomId, actionType);
            if (actionFrequency.IsExcessive)
            {
                warnings.Add($"High frequency {actionType} actions detected");
                riskFactors["ActionFrequency"] = actionFrequency.ActionsPerHour;
            }

            // Resource manipulation checks
            if (actionType.Contains("Resource"))
            {
                var resourceRisk = await ValidateResourceManipulation(playerId, kingdomId, actionDetails);
                if (resourceRisk.IsSuspicious)
                {
                    warnings.Add("Unusual resource patterns detected");
                    riskFactors["ResourceManipulation"] = resourceRisk.Details;
                }
            }

            // Progression speed checks
            if (actionType.Contains("Upgrade") || actionType.Contains("Build"))
            {
                var progressionRisk = await ValidateProgressionSpeed(playerId, kingdomId);
                if (progressionRisk.TooFast)
                {
                    warnings.Add("Unusually fast progression detected");
                    riskFactors["ProgressionSpeed"] = progressionRisk.SpeedMultiplier;
                }
            }

            var isValid = warnings.Count == 0;

            if (!isValid)
            {
                _logger.LogWarning("Action validation failed for Player {PlayerId}: {ActionType} - {Warnings}",
                    playerId, actionType, string.Join("; ", warnings));
            }

            return (isValid, warnings, riskFactors);
        }

        public async Task<(bool SuspiciousActivity, List<string> Flags, Dictionary<string, object> ProgressionMetrics)>
            MonitorProgressionPatternsAsync(int playerId, int kingdomId)
        {
            var player = await _playerRepository.GetByIdAsync(playerId, kingdomId);
            if (player == null)
                return (false, new List<string>(), new Dictionary<string, object>());

            var flags = new List<string>();
            var metrics = new Dictionary<string, object>();

            // Calculate progression metrics
            var accountAge = DateTime.UtcNow - player.CreatedAt;
            var playerLevel = CalculatePlayerLevelFromCastle(player.CastleLevel);
            var levelProgression = playerLevel / Math.Max(1, accountAge.TotalDays);
            var powerProgression = player.Power / Math.Max(1, accountAge.TotalDays);

            metrics["AccountAgeDays"] = accountAge.TotalDays;
            metrics["LevelProgressionPerDay"] = levelProgression;
            metrics["PowerProgressionPerDay"] = powerProgression;

            // Flag suspicious patterns
            if (levelProgression > 5.0) // More than 5 levels per day average
            {
                flags.Add("Extremely fast level progression");
            }

            if (powerProgression > 50000) // More than 50k power per day average
            {
                flags.Add("Extremely fast power progression");
            }

            // Check for bot-like activity patterns
            var activityPattern = await AnalyzeActivityPattern(playerId, kingdomId);
            if (activityPattern.IsBotLike)
            {
                flags.Add("Bot-like activity patterns detected");
                metrics["ActivityPattern"] = activityPattern.Details;
            }

            var hasSuspiciousActivity = flags.Count > 0;

            if (hasSuspiciousActivity)
            {
                _logger.LogWarning("Suspicious progression patterns detected for Player {PlayerId}: {Flags}",
                    playerId, string.Join("; ", flags));
            }

            return (hasSuspiciousActivity, flags, metrics);
        }

        #endregion

        #region Player Information

        public async Task<Dictionary<string, object>> GetPlayerProfileAsync(int playerId, int kingdomId, bool includePrivateData = false)
        {
            var player = await _playerRepository.GetByIdAsync(playerId, kingdomId);
            if (player == null)
                return new Dictionary<string, object>();

            var profile = new Dictionary<string, object>
            {
                ["PlayerId"] = player.Id,
                ["PlayerName"] = player.Name,
                ["Level"] = CalculatePlayerLevelFromCastle(player.CastleLevel),
                ["Power"] = player.Power,
                ["CastleLevel"] = player.CastleLevel,
                ["KingdomId"] = player.KingdomId
            };

            // Add alliance information
            if (player.AllianceId.HasValue)
            {
                var alliance = await _allianceRepository.GetByIdAsync(player.AllianceId.Value, kingdomId);
                if (alliance != null)
                {
                    profile["Alliance"] = new Dictionary<string, object>
                    {
                        ["Name"] = alliance.Name,
                        ["Tag"] = alliance.Tag,
                        ["Level"] = alliance.Level
                    };
                }
            }

            // Add VIP information (hide secret tiers from others)
            if (includePrivateData || player.VipLevel < 16)
            {
                profile["VipTier"] = player.VipLevel;
            }
            else
            {
                profile["VipTier"] = Math.Min(player.VipLevel, 15); // Hide secret tiers
            }

            // Private data only for own profile
            if (includePrivateData)
            {
                profile["Resources"] = new Dictionary<string, long>
                {
                    ["Wood"] = player.Wood,
                    ["Iron"] = player.Iron,
                    ["Food"] = player.Food,
                    ["Silver"] = player.Silver,
                    ["Mithril"] = player.Mithril,
                    ["Gold"] = player.Gold
                };

                profile["Experience"] = CalculateExperienceFromLevel(CalculatePlayerLevelFromCastle(player.CastleLevel));
                profile["ActionPoints"] = GetPlayerActionPoints(player);
                profile["Coordinates"] = new { X = player.CoordinateX, Y = player.CoordinateY };
                profile["CreatedAt"] = player.CreatedAt;
                profile["LastLogin"] = GetLastLogin(player);
            }

            return profile;
        }

        public async Task<Dictionary<string, object>> GetPlayerStatusAsync(int playerId, int kingdomId)
        {
            var player = await _playerRepository.GetByIdAsync(playerId, kingdomId);
            if (player == null)
                return new Dictionary<string, object>();

            var status = new Dictionary<string, object>();

            // Online status
            var lastLogin = GetLastLogin(player);
            var isOnline = lastLogin.HasValue &&
                          (DateTime.UtcNow - lastLogin.Value).TotalMinutes < 5;
            status["IsOnline"] = isOnline;
            status["LastSeen"] = lastLogin;

            // March status
            var hasActiveMarch = await CheckForActiveMarch(playerId, kingdomId);
            status["HasActiveMarch"] = hasActiveMarch;

            // Combat status
            var inCombat = await CheckRecentCombatActivity(playerId, kingdomId, TimeSpan.FromMinutes(10));
            status["InCombat"] = inCombat;

            // Shield status (would come from shield system)
            status["HasShield"] = false; // Placeholder
            status["ShieldExpiry"] = null;

            // Active buffs (would come from buff system)
            status["ActiveBuffs"] = new List<object>(); // Placeholder

            return status;
        }

        public async Task<Dictionary<string, object>> GetPlayerRankingsAsync(int playerId, int kingdomId)
        {
            var rankings = new Dictionary<string, object>();

            // Get kingdom rankings
            var powerRank = await GetPlayerPowerRankAsync(playerId, kingdomId);
            var levelRank = await GetPlayerLevelRankAsync(playerId, kingdomId);

            rankings["PowerRank"] = powerRank;
            rankings["LevelRank"] = levelRank;

            // Get kill rankings from combat logs
            var killRank = await GetPlayerKillRankAsync(playerId, kingdomId);
            rankings["KillRank"] = killRank;

            // Alliance rankings
            var player = await _playerRepository.GetByIdAsync(playerId, kingdomId);
            if (player?.AllianceId.HasValue == true)
            {
                var allianceRank = await GetAlliancePowerRankAsync(player.AllianceId.Value, kingdomId);
                rankings["AllianceRank"] = allianceRank;
            }

            return rankings;
        }

        #endregion

        #region Private Helper Methods

        private TimeSpan CalculateVipTimeReduction(int vipLevel, TimeSpan baseTime)
        {
            var reductionPercentage = Math.Min(vipLevel * 2, 50) / 100.0; // Max 50% reduction
            return TimeSpan.FromTicks((long)(baseTime.Ticks * reductionPercentage));
        }

        private Dictionary<string, object> CalculateAllianceConstructionBonuses(Core.Models.Alliance.Alliance alliance)
        {
            var bonuses = new Dictionary<string, object>();

            // Get construction research level (simplified - would use actual research system)
            var constructionLevel = alliance.TechnologyConstructionResearch;

            bonuses["WoodReduction"] = Math.Min(constructionLevel * 1.5, 25) / 100.0;
            bonuses["IronReduction"] = Math.Min(constructionLevel * 1.5, 25) / 100.0;
            bonuses["FoodReduction"] = Math.Min(constructionLevel * 1.5, 25) / 100.0;
            bonuses["TimeReduction"] = Math.Min(constructionLevel * 2, 30) / 100.0;

            return bonuses;
        }

        private Dictionary<string, object> CalculateCastleLevelBenefits(int castleLevel)
        {
            return new Dictionary<string, object>
            {
                ["TroopCapacityIncrease"] = castleLevel * 1000,
                ["ResourceCapacityIncrease"] = castleLevel * 10000,
                ["WallDefenseIncrease"] = castleLevel * 50,
                ["NewBuildingSlots"] = castleLevel / 5,
                ["HospitalCapacityIncrease"] = castleLevel * 100
            };
        }

        private long GetPlayerResourceAmount(Player player, string resourceType)
        {
            return resourceType.ToLower() switch
            {
                "wood" => player.Wood,
                "iron" => player.Iron,
                "food" => player.Food,
                "silver" => player.Silver,
                "mithril" => player.Mithril,
                "gold" => player.Gold,
                _ => 0
            };
        }

        private Dictionary<string, long> GetBaseResourceProduction(int castleLevel)
        {
            var baseProduction = 1000 + (castleLevel * 100);
            return new Dictionary<string, long>
            {
                ["Wood"] = baseProduction,
                ["Iron"] = baseProduction,
                ["Food"] = baseProduction,
                ["Silver"] = baseProduction / 2,
                ["Mithril"] = baseProduction / 10
            };
        }

        private long CalculateBuildingProductionBonus(string resource, int castleLevel)
        {
            // Placeholder for building bonus calculation
            return castleLevel * 50;
        }

        private double GetAllianceResourceBonus(Core.Models.Alliance.Alliance alliance, string resource)
        {
            var economyLevel = alliance.EconomicProductionResearch;
            return Math.Min(economyLevel * 2, 30); // Max 30% bonus
        }

        private double CalculateDistance(int x1, int y1, int x2, int y2)
        {
            return Math.Sqrt(Math.Pow(x2 - x1, 2) + Math.Pow(y2 - y1, 2));
        }

        private int GetTeleportCooldownHours(string teleportType)
        {
            return teleportType.ToLower() switch
            {
                "free" => 8,
                "paid" => 1,
                "alliance" => 4,
                _ => 8
            };
        }

        private TimeSpan GetRemainingTeleportCooldown(DateTime lastTeleportTime)
        {
            var cooldownDuration = TimeSpan.FromHours(8); // Default cooldown
            var elapsed = DateTime.UtcNow - lastTeleportTime;
            return cooldownDuration - elapsed;
        }

        private async Task<bool> CheckForActiveMarch(int playerId, int kingdomId)
        {
            // Placeholder - would check march system
            return false;
        }

        private async Task<bool> CheckRecentCombatActivity(int playerId, int kingdomId, TimeSpan timeframe)
        {
            // Placeholder - would check combat logs
            return false;
        }

        // Additional placeholder helper methods to resolve compilation errors

        private List<string> GetRequiredBuildingsForLevel(int targetLevel)
        {
            // Placeholder for building requirement validation
            return new List<string>();
        }

        private async Task<(bool CanUse, string Reason, Dictionary<string, object> PrivilegeDetails)> ValidateFreeTeleportPrivilege(
            Player player, Dictionary<string, object> details)
        {
            var canUse = player.VipLevel >= 6;
            var reason = canUse ? "VIP privilege available" : "Requires VIP level 6 or higher";
            return (canUse, reason, details);
        }

        private (bool CanUse, string Reason, Dictionary<string, object> PrivilegeDetails) ValidateAutoCollectionPrivilege(
            Player player, Dictionary<string, object> details)
        {
            var canUse = player.VipLevel >= 10;
            var reason = canUse ? "Auto collection available" : "Requires VIP level 10 or higher";
            return (canUse, reason, details);
        }

        private (bool CanUse, string Reason, Dictionary<string, object> PrivilegeDetails) ValidateAdvancedIntelligencePrivilege(
            Player player, Dictionary<string, object> details)
        {
            var canUse = player.VipLevel >= 10;
            var reason = canUse ? "Advanced intelligence available" : "Requires VIP level 10 or higher";
            return (canUse, reason, details);
        }

        private (bool CanUse, string Reason, Dictionary<string, object> PrivilegeDetails) ValidateExclusiveEquipmentPrivilege(
            Player player, Dictionary<string, object> details)
        {
            var canUse = player.VipLevel >= 15;
            var reason = canUse ? "Exclusive equipment available" : "Requires VIP level 15 or higher";
            return (canUse, reason, details);
        }

        private Dictionary<string, long> GetBuildingConstructionCosts(string buildingType, int level)
        {
            var baseCost = level * 1000;
            return new Dictionary<string, long>
            {
                ["Wood"] = baseCost * 2,
                ["Iron"] = baseCost,
                ["Food"] = baseCost,
                ["Silver"] = baseCost / 2
            };
        }

        private TimeSpan GetBuildingConstructionTime(string buildingType, int level)
        {
            return TimeSpan.FromMinutes(level * 30);
        }

        private async Task<(bool Success, int NewTier, bool ChargebackRisk)> UpdateVipTierAsync(
            int playerId, int kingdomId, decimal purchaseAmount)
        {
            // Simulate VIP tier calculation
            var player = await _playerRepository.GetByIdAsync(playerId, kingdomId);
            if (player == null) return (false, 0, false);

            // Simple progression: $10 per VIP level
            var newTier = Math.Min(20, (int)(purchaseAmount / 10) + player.VipLevel);
            var tierChanged = newTier > player.VipLevel;
            var chargebackRisk = purchaseAmount > 1000; // High purchases flagged for chargeback risk

            return (tierChanged, newTier, chargebackRisk);
        }

        private async Task NotifyAllianceOfVipAdvancement(int allianceId, int kingdomId, int playerId,
            int oldTier, int newTier, bool isSecretTier)
        {
            // Placeholder for alliance notification system
            _logger.LogInformation("Alliance {AllianceId} notified of Player {PlayerId} VIP advancement: {OldTier} → {NewTier}",
                allianceId, playerId, oldTier, newTier);
        }

        private async Task<bool> UpdateCastleLevelAsync(int playerId, int kingdomId, int targetLevel)
        {
            try
            {
                var player = await _playerRepository.GetByIdAsync(playerId, kingdomId);
                if (player == null) return false;

                player.CastleLevel = targetLevel;
                await _playerRepository.UpdateAsync(player, kingdomId);
                return true;
            }
            catch
            {
                return false;
            }
        }

        private int CalculatePlayerLevelFromCastle(int castleLevel)
        {
            // Simple mapping: castle level roughly equals player level
            return castleLevel;
        }

        private int CalculateLevelFromExperience(long experience)
        {
            // Simple level calculation: 1000 XP per level
            return Math.Max(1, (int)(experience / 1000));
        }

        private long CalculateExperienceFromLevel(int level)
        {
            return level * 1000L;
        }

        private Dictionary<string, object> GetLevelUpRewards(int level)
        {
            return new Dictionary<string, object>
            {
                ["Gold"] = level * 10,
                ["ActionPoints"] = 1,
                ["Resources"] = level * 1000
            };
        }

        private async Task<bool> UpdateExperienceAsync(int playerId, int kingdomId, long newExperience, int newLevel)
        {
            // Placeholder - would update experience tracking
            return true;
        }

        private async Task<bool> UpdateActionPointsAsync(int playerId, int kingdomId, long actionPoints)
        {
            // Placeholder - would update action points
            return true;
        }

        private long GetPlayerActionPoints(Player player)
        {
            // Placeholder - would get from player model or calculate
            return player.CastleLevel; // Simple simulation
        }

        private long CalculateCastlePower(int castleLevel)
        {
            return castleLevel * castleLevel * 1000L;
        }

        private long CalculateTroopPower(Player player)
        {
            return player.TotalTroops * 10;
        }

        private long CalculateResearchPower(Player player)
        {
            // Placeholder - would calculate from research levels
            return player.CastleLevel * 500;
        }

        private long CalculateEquipmentPower(Player player)
        {
            // Placeholder - would calculate from equipment
            return player.CastleLevel * 200;
        }

        private long CalculateDragonPower(Player player)
        {
            return player.HasActiveDragon ? player.CastleLevel * 300 : 0;
        }

        private async Task<bool> UpdatePowerAsync(int playerId, int kingdomId, long newPower)
        {
            try
            {
                var player = await _playerRepository.GetByIdAsync(playerId, kingdomId);
                if (player == null) return false;

                player.Power = newPower;
                await _playerRepository.UpdateAsync(player, kingdomId);
                return true;
            }
            catch
            {
                return false;
            }
        }

        private List<Achievement> GetAchievementsForType(string achievementType)
        {
            // Placeholder achievement system
            return achievementType.ToLower() switch
            {
                "castleupgrade" => new List<Achievement>
                {
                    new Achievement { Id = "castle_5", Name = "Castle Builder I", RequiredValue = 5, Rewards = new Dictionary<string, object> { ["Gold"] = 100 } },
                    new Achievement { Id = "castle_10", Name = "Castle Builder II", RequiredValue = 10, Rewards = new Dictionary<string, object> { ["Gold"] = 500 } }
                },
                "vipadvancement" => new List<Achievement>
                {
                    new Achievement { Id = "vip_5", Name = "VIP Member", RequiredValue = 5, Rewards = new Dictionary<string, object> { ["Gold"] = 200 } }
                },
                "combatvictory" => new List<Achievement>
                {
                    new Achievement { Id = "first_victory", Name = "First Victory", RequiredValue = 1, Rewards = new Dictionary<string, object> { ["Gold"] = 50 } }
                },
                _ => new List<Achievement>()
            };
        }

        private async Task<bool> HasAchievementAsync(int playerId, int kingdomId, string achievementId)
        {
            // Placeholder - would check achievement database
            return false;
        }

        private async Task GrantAchievementAsync(int playerId, int kingdomId, string achievementId)
        {
            // Placeholder - would grant achievement
            _logger.LogInformation("Achievement granted to Player {PlayerId}: {AchievementId}", playerId, achievementId);
        }

        private (bool IsValid, List<string> Errors) ValidateTroopAvailability(Player player, Dictionary<string, int> troopComposition)
        {
            var errors = new List<string>();

            foreach (var troop in troopComposition)
            {
                var available = GetTroopCount(player, troop.Key);
                if (available < troop.Value)
                {
                    errors.Add($"Insufficient {troop.Key}: Need {troop.Value}, Have {available}");
                }
            }

            return (errors.Count == 0, errors);
        }

        private int GetTroopCount(Player player, string troopType)
        {
            return troopType.ToLower() switch
            {
                "infantryt1" => (int)player.InfantryT1,
                "cavalryt1" => (int)player.CavalryT1,
                "bowment1" => (int)player.BowmenT1,
                "sieget1" => (int)player.SiegeT1,
                _ => 0
            };
        }

        private double CalculateMarchSpeed(Dictionary<string, int> troopComposition, int vipLevel)
        {
            // Base speed modified by slowest troop type and VIP bonuses
            var baseSpeed = 100.0; // Base march speed
            var vipBonus = vipLevel * 2; // 2% per VIP level
            return baseSpeed * (1.0 + vipBonus / 100.0);
        }

        private DateTime? GetLastTeleportTime(Player player)
        {
            // Placeholder - would get from player teleportation history
            return player.CreatedAt.AddDays(1); // Simulate last teleport
        }

        private DateTime GetLastResourceCollectionTime(Player player)
        {
            // Placeholder - would get from player resource collection tracking
            return player.LastActiveAt;
        }

        private async Task<bool> UpdateResourcesAsync(int playerId, int kingdomId, Dictionary<string, long> newResourceTotals, string reason)
        {
            try
            {
                var player = await _playerRepository.GetByIdAsync(playerId, kingdomId);
                if (player == null) return false;

                foreach (var resource in newResourceTotals)
                {
                    switch (resource.Key.ToLower())
                    {
                        case "wood":
                            player.Wood = resource.Value;
                            break;
                        case "iron":
                            player.Iron = resource.Value;
                            break;
                        case "food":
                            player.Food = resource.Value;
                            break;
                        case "silver":
                            player.Silver = resource.Value;
                            break;
                        case "mithril":
                            player.Mithril = resource.Value;
                            break;
                        case "gold":
                            player.Gold = (int)Math.Min(int.MaxValue, resource.Value);
                            break;
                    }
                }

                await _playerRepository.UpdateAsync(player, kingdomId);
                return true;
            }
            catch
            {
                return false;
            }
        }

        private async Task<bool> UpdateLastResourceCollectionTimeAsync(int playerId, int kingdomId, DateTime collectionTime)
        {
            // Placeholder - would update last collection time
            return true;
        }

        private async Task<bool> UpdateCoordinatesAsync(int playerId, int kingdomId, int x, int y)
        {
            try
            {
                var player = await _playerRepository.GetByIdAsync(playerId, kingdomId);
                if (player == null) return false;

                player.CoordinateX = x;
                player.CoordinateY = y;
                await _playerRepository.UpdateAsync(player, kingdomId);
                return true;
            }
            catch
            {
                return false;
            }
        }

        private async Task<bool> UpdateLastTeleportTimeAsync(int playerId, int kingdomId, DateTime teleportTime)
        {
            // Placeholder - would update last teleport time
            return true;
        }

        private async Task<IEnumerable<Player>> GetPlayersNearCoordinatesAsync(int kingdomId, int x, int y, double radius)
        {
            // Placeholder - would query players within radius
            var allPlayers = await _playerRepository.GetAllAsync(kingdomId);
            return allPlayers.Where(p => CalculateDistance(p.CoordinateX, p.CoordinateY, x, y) <= radius);
        }

        private async Task<bool> UpdateAllianceAsync(int playerId, int kingdomId, int? allianceId)
        {
            try
            {
                var player = await _playerRepository.GetByIdAsync(playerId, kingdomId);
                if (player == null) return false;

                player.AllianceId = allianceId;
                await _playerRepository.UpdateAsync(player, kingdomId);
                return true;
            }
            catch
            {
                return false;
            }
        }

        private Dictionary<string, object> GetAllianceResearchBonuses(Core.Models.Alliance.Alliance alliance)
        {
            return new Dictionary<string, object>
            {
                ["Military"] = alliance.MilitaryAttackResearch + alliance.MilitaryDefenseResearch,
                ["Economic"] = alliance.EconomicProductionResearch + alliance.EconomicGatheringResearch,
                ["Technology"] = alliance.TechnologyConstructionResearch + alliance.TechnologyUpgradeResearch
            };
        }

        private async Task<bool> CheckTerritoryEviction(int playerId, int kingdomId)
        {
            // Placeholder - would check if player is in alliance territory without alliance membership
            return false;
        }

        private async Task<(bool IsExcessive, double ActionsPerHour)> CheckActionFrequency(int playerId, int kingdomId, string actionType)
        {
            // Placeholder anti-exploitation check
            return (false, 1.0);
        }

        private async Task<(bool IsSuspicious, Dictionary<string, object> Details)> ValidateResourceManipulation(
            int playerId, int kingdomId, Dictionary<string, object> actionDetails)
        {
            // Placeholder resource manipulation check
            return (false, new Dictionary<string, object>());
        }

        private async Task<(bool TooFast, double SpeedMultiplier)> ValidateProgressionSpeed(int playerId, int kingdomId)
        {
            // Placeholder progression speed check
            return (false, 1.0);
        }

        private async Task<(bool IsBotLike, Dictionary<string, object> Details)> AnalyzeActivityPattern(int playerId, int kingdomId)
        {
            // Placeholder bot detection
            return (false, new Dictionary<string, object>());
        }

        private DateTime? GetLastLogin(Player player)
        {
            // Use LastActiveAt as LastLogin equivalent
            return player.LastActiveAt;
        }

        private async Task<int> GetPlayerPowerRankAsync(int playerId, int kingdomId)
        {
            // Placeholder ranking calculation
            var allPlayers = await _playerRepository.GetAllAsync(kingdomId);
            var sortedByPower = allPlayers.OrderByDescending(p => p.Power).ToList();
            return sortedByPower.FindIndex(p => p.Id == playerId) + 1;
        }

        private async Task<int> GetPlayerLevelRankAsync(int playerId, int kingdomId)
        {
            // Placeholder level ranking
            var allPlayers = await _playerRepository.GetAllAsync(kingdomId);
            var sortedByLevel = allPlayers.OrderByDescending(p => p.CastleLevel).ToList();
            return sortedByLevel.FindIndex(p => p.Id == playerId) + 1;
        }

        private async Task<int> GetPlayerKillRankAsync(int playerId, int kingdomId)
        {
            // Placeholder kill ranking
            var allPlayers = await _playerRepository.GetAllAsync(kingdomId);
            var sortedByKills = allPlayers.OrderByDescending(p => p.TroopsKilled).ToList();
            return sortedByKills.FindIndex(p => p.Id == playerId) + 1;
        }

        private async Task<int> GetAlliancePowerRankAsync(int allianceId, int kingdomId)
        {
            // Placeholder alliance ranking
            return 1;
        }

        #endregion

        // Supporting classes
        private class Achievement
        {
            public string Id { get; set; } = string.Empty;
            public string Name { get; set; } = string.Empty;
            public long RequiredValue { get; set; }
            public Dictionary<string, object> Rewards { get; set; } = new();
        }
    }
}