/*
 * File: ShadowedRealms.Data/Repositories/Kingdom/KingdomRepository.cs
 * Created: 2025-10-19
 * Last Modified: 2025-10-20
 * Description: Kingdom repository implementation providing kingdom-specific operations including population management,
 *              democratic systems, KvK events, merger mechanics, and tax distribution systems.
 * Last Edit Notes: Fixed method return types to match IKingdomRepository interface signatures exactly
 */

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using ShadowedRealms.Core.Interfaces;
using ShadowedRealms.Core.Interfaces.Repositories;
using ShadowedRealms.Core.Models;
using ShadowedRealms.Data.Contexts;
using System.Linq.Expressions;

// Use aliases to resolve namespace conflicts
using KingdomModel = ShadowedRealms.Core.Models.Kingdom.Kingdom;
using AllianceModel = ShadowedRealms.Core.Models.Alliance.Alliance;

namespace ShadowedRealms.Data.Repositories.Kingdom
{
    /// <summary>
    /// Kingdom repository implementation providing specialized kingdom operations.
    /// Handles population management, democratic systems, KvK events, and kingdom-level statistics.
    /// </summary>
    public class KingdomRepository : Repository<KingdomModel, int>, IKingdomRepository
    {
        public KingdomRepository(GameDbContext context, ILogger<KingdomRepository> logger)
            : base(context, logger)
        {
        }

        #region IKingdomRepository Implementation

        /// <summary>
        /// Creates a new kingdom with proper initialization
        /// </summary>
        public async Task<KingdomModel> CreateNewKingdomAsync(string name, string description = "", CancellationToken cancellationToken = default)
        {
            try
            {
                _logger.LogInformation("Creating new kingdom: {Name}", name);

                var kingdom = new KingdomModel
                {
                    Name = name,
                    Description = description,
                    IsActive = true,
                    CreatedAt = DateTime.UtcNow,
                    LastActivity = DateTime.UtcNow,
                    TotalTaxCollected = 0,
                    IsInKvK = false,
                    KvKHostAllianceId = null,
                    CurrentPowerRank = 0,
                    MaxPopulation = 1500,
                    CurrentPopulation = 0
                };

                var addedKingdom = await _context.Kingdoms.AddAsync(kingdom, cancellationToken);
                await _context.SaveChangesAsync(cancellationToken);

                _logger.LogInformation("Successfully created new kingdom {KingdomId}: {Name}",
                    addedKingdom.Entity.Id, name);

                return addedKingdom.Entity;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error creating new kingdom: {Name}", name);
                throw new InvalidOperationException($"Failed to create new kingdom: {name}", ex);
            }
        }

        /// <summary>
        /// Gets kingdoms available for new players
        /// </summary>
        public async Task<IEnumerable<KingdomModel>> GetAvailableKingdomsForNewPlayersAsync(CancellationToken cancellationToken = default)
        {
            try
            {
                _logger.LogDebug("Getting available kingdoms for new players");

                const int maxPopulation = 1500;

                var kingdomsWithCounts = await _context.Kingdoms
                    .Where(k => k.IsActive)
                    .Select(k => new
                    {
                        Kingdom = k,
                        PlayerCount = _context.Players.Count(p => p.KingdomId == k.Id && p.IsActive)
                    })
                    .Where(x => x.PlayerCount < maxPopulation)
                    .OrderBy(x => x.PlayerCount)
                    .ToListAsync(cancellationToken);

                var availableKingdoms = kingdomsWithCounts
                    .Select(x => x.Kingdom)
                    .ToList();

                _logger.LogDebug("Found {Count} available kingdoms for new players", availableKingdoms.Count);

                return availableKingdoms;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting available kingdoms");
                throw new InvalidOperationException("Failed to get available kingdoms", ex);
            }
        }

        /// <summary>
        /// Gets the newest available kingdom for player assignment
        /// </summary>
        public async Task<KingdomModel?> GetNewestAvailableKingdomAsync(string playerRegion, CancellationToken cancellationToken = default)
        {
            try
            {
                _logger.LogDebug("Getting newest available kingdom for region: {Region}", playerRegion);

                var kingdom = await _context.Kingdoms
                    .Where(k => k.IsActive && k.CurrentPopulation < k.MaxPopulation)
                    .OrderByDescending(k => k.CreatedAt)
                    .FirstOrDefaultAsync(cancellationToken);

                if (kingdom != null)
                {
                    _logger.LogDebug("Found newest kingdom: {KingdomId} created at {CreatedAt}",
                        kingdom.Id, kingdom.CreatedAt);
                }
                else
                {
                    _logger.LogWarning("No available kingdoms found for region: {Region}", playerRegion);
                }

                return kingdom;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting newest available kingdom");
                throw new InvalidOperationException("Failed to get newest available kingdom", ex);
            }
        }

        /// <summary>
        /// Archives a kingdom with reason
        /// </summary>
        public async Task<bool> ArchiveKingdomAsync(int kingdomId, string reason, CancellationToken cancellationToken = default)
        {
            try
            {
                _logger.LogInformation("Archiving kingdom {KingdomId} with reason: {Reason}", kingdomId, reason);

                var kingdom = await _context.Kingdoms
                    .FirstOrDefaultAsync(k => k.Id == kingdomId, cancellationToken);

                if (kingdom == null)
                {
                    _logger.LogWarning("Kingdom {KingdomId} not found for archiving", kingdomId);
                    return false;
                }

                kingdom.IsActive = false;
                kingdom.LastActivity = DateTime.UtcNow;
                kingdom.Description = $"{kingdom.Description} [ARCHIVED: {reason}]";

                await _context.SaveChangesAsync(cancellationToken);

                _logger.LogInformation("Successfully archived kingdom {KingdomId}", kingdomId);
                return true;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error archiving kingdom {KingdomId}", kingdomId);
                throw new InvalidOperationException($"Failed to archive kingdom {kingdomId}", ex);
            }
        }

        /// <summary>
        /// Gets kingdom population breakdown with active/inactive/total counts
        /// FIXED: Returns tuple matching interface signature exactly
        /// </summary>
        public async Task<(int ActivePlayers, int InactivePlayers, int TotalPlayers)> GetKingdomPopulationAsync(int kingdomId, bool includeInactive = false, CancellationToken cancellationToken = default)
        {
            try
            {
                _logger.LogDebug("Getting population breakdown for kingdom {KingdomId}", kingdomId);

                var activePlayers = await _context.Players
                    .CountAsync(p => p.KingdomId == kingdomId && p.IsActive, cancellationToken);

                var inactivePlayers = await _context.Players
                    .CountAsync(p => p.KingdomId == kingdomId && !p.IsActive, cancellationToken);

                var totalPlayers = activePlayers + inactivePlayers;

                _logger.LogDebug("Kingdom {KingdomId} population: {Active} active, {Inactive} inactive, {Total} total",
                    kingdomId, activePlayers, inactivePlayers, totalPlayers);

                return (activePlayers, inactivePlayers, totalPlayers);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting population breakdown for kingdom {KingdomId}", kingdomId);
                throw new InvalidOperationException($"Failed to get population breakdown for kingdom {kingdomId}", ex);
            }
        }

        /// <summary>
        /// Gets kingdoms eligible for merger with the specified kingdom
        /// </summary>
        public async Task<IEnumerable<KingdomModel>> GetKingdomsEligibleForMergerAsync(int kingdomId, CancellationToken cancellationToken = default)
        {
            try
            {
                _logger.LogDebug("Getting merger eligible kingdoms for {KingdomId}", kingdomId);

                var (activePlayers, _, _) = await GetKingdomPopulationAsync(kingdomId, false, cancellationToken);
                const int maxMergedPopulation = 1500;

                var candidates = new List<KingdomModel>();
                var otherKingdoms = await _context.Kingdoms
                    .Where(k => k.Id != kingdomId && k.IsActive && !k.IsInKvK)
                    .ToListAsync(cancellationToken);

                foreach (var kingdom in otherKingdoms)
                {
                    var (otherActive, _, _) = await GetKingdomPopulationAsync(kingdom.Id, false, cancellationToken);
                    if (activePlayers + otherActive <= maxMergedPopulation)
                    {
                        candidates.Add(kingdom);
                    }
                }

                _logger.LogDebug("Found {Count} merger candidates for kingdom {KingdomId}", candidates.Count, kingdomId);
                return candidates.OrderBy(k => k.CreatedAt);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting merger eligible kingdoms for {KingdomId}", kingdomId);
                throw new InvalidOperationException($"Failed to get merger eligible kingdoms for {kingdomId}", ex);
            }
        }

        /// <summary>
        /// Updates kingdom population count and returns updated kingdom entity
        /// FIXED: Returns Kingdom entity matching interface signature exactly
        /// </summary>
        public async Task<KingdomModel> UpdateKingdomPopulationAsync(int kingdomId, int newPopulation, CancellationToken cancellationToken = default)
        {
            try
            {
                _logger.LogDebug("Updating kingdom {KingdomId} population to {NewPopulation}", kingdomId, newPopulation);

                var kingdom = await _context.Kingdoms
                    .FirstOrDefaultAsync(k => k.Id == kingdomId, cancellationToken);

                if (kingdom == null)
                {
                    throw new InvalidOperationException($"Kingdom {kingdomId} not found");
                }

                kingdom.CurrentPopulation = newPopulation;
                kingdom.LastActivity = DateTime.UtcNow;

                await _context.SaveChangesAsync(cancellationToken);

                _logger.LogDebug("Successfully updated kingdom {KingdomId} population to {NewPopulation}", kingdomId, newPopulation);
                return kingdom;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error updating kingdom {KingdomId} population", kingdomId);
                throw new InvalidOperationException($"Failed to update kingdom {kingdomId} population", ex);
            }
        }

        /// <summary>
        /// Gets kingdoms eligible for KvK events with compatibility scores
        /// FIXED: Returns tuple with compatibility scores matching interface signature exactly
        /// </summary>
        public async Task<IEnumerable<(KingdomModel Kingdom, double CompatibilityScore)>> GetKvKEligibleKingdomsAsync(int kingdomId, string eventType, CancellationToken cancellationToken = default)
        {
            try
            {
                _logger.LogDebug("Getting KvK eligible kingdoms for {KingdomId}, event type: {EventType}", kingdomId, eventType);

                var eligibleKingdoms = await _context.Kingdoms
                    .Where(k => k.Id != kingdomId && k.IsActive && !k.IsInKvK)
                    .Where(k => k.CurrentPopulation >= 500) // Minimum population for KvK
                    .ToListAsync(cancellationToken);

                var results = new List<(KingdomModel Kingdom, double CompatibilityScore)>();

                foreach (var kingdom in eligibleKingdoms)
                {
                    var compatibilityScore = await CalculateKvKCompatibilityScore(kingdomId, kingdom.Id, cancellationToken);
                    results.Add((kingdom, compatibilityScore));
                }

                // Order by compatibility score (highest first)
                var orderedResults = results.OrderByDescending(r => r.CompatibilityScore);

                _logger.LogDebug("Found {Count} KvK eligible kingdoms with compatibility scores", results.Count);
                return orderedResults;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting KvK eligible kingdoms for {KingdomId}", kingdomId);
                throw new InvalidOperationException($"Failed to get KvK eligible kingdoms for {kingdomId}", ex);
            }
        }

        /// <summary>
        /// Creates a new KvK event
        /// </summary>
        public async Task<object> CreateKvKEventAsync(IEnumerable<int> participatingKingdoms, string eventType, DateTime startTime, TimeSpan duration, CancellationToken cancellationToken = default)
        {
            try
            {
                var kingdomIds = participatingKingdoms.ToList();
                _logger.LogInformation("Creating KvK event: {EventType} for kingdoms: {KingdomIds}", eventType, string.Join(", ", kingdomIds));

                var kingdoms = await _context.Kingdoms
                    .Where(k => kingdomIds.Contains(k.Id) && k.IsActive)
                    .ToListAsync(cancellationToken);

                if (kingdoms.Count != kingdomIds.Count)
                {
                    throw new InvalidOperationException("Not all specified kingdoms found or active");
                }

                foreach (var kingdom in kingdoms)
                {
                    kingdom.IsInKvK = true;
                    kingdom.LastActivity = DateTime.UtcNow;
                }

                await _context.SaveChangesAsync(cancellationToken);

                var kvkEvent = new
                {
                    EventId = Guid.NewGuid(),
                    EventType = eventType,
                    ParticipatingKingdoms = kingdomIds,
                    StartTime = startTime,
                    Duration = duration,
                    Status = "Created"
                };

                _logger.LogInformation("Successfully created KvK event for {Count} kingdoms", kingdoms.Count);
                return kvkEvent;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error creating KvK event");
                throw new InvalidOperationException("Failed to create KvK event", ex);
            }
        }

        /// <summary>
        /// Gets KvK events for a kingdom
        /// </summary>
        public async Task<IEnumerable<object>> GetKingdomKvKEventsAsync(int kingdomId, bool activeOnly = true, CancellationToken cancellationToken = default)
        {
            try
            {
                _logger.LogDebug("Getting KvK events for kingdom {KingdomId}, active only: {ActiveOnly}", kingdomId, activeOnly);

                var kingdom = await _context.Kingdoms
                    .FirstOrDefaultAsync(k => k.Id == kingdomId, cancellationToken);

                if (kingdom == null)
                {
                    return Enumerable.Empty<object>();
                }

                // In a full implementation, this would query a KvKEvents table
                // For now, return simulated data based on kingdom state
                var events = new List<object>();

                if (kingdom.IsInKvK || !activeOnly)
                {
                    events.Add(new
                    {
                        EventId = Guid.NewGuid(),
                        KingdomId = kingdomId,
                        EventType = "Kingdom War",
                        IsActive = kingdom.IsInKvK,
                        StartTime = DateTime.UtcNow.AddHours(-2),
                        Duration = TimeSpan.FromDays(3),
                        HostAllianceId = kingdom.KvKHostAllianceId
                    });
                }

                _logger.LogDebug("Found {Count} KvK events for kingdom {KingdomId}", events.Count, kingdomId);
                return events;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting KvK events for kingdom {KingdomId}", kingdomId);
                throw new InvalidOperationException($"Failed to get KvK events for kingdom {kingdomId}", ex);
            }
        }

        /// <summary>
        /// Updates KvK performance metrics for a kingdom and returns updated kingdom
        /// FIXED: Returns Kingdom entity matching interface signature exactly
        /// </summary>
        public async Task<KingdomModel> UpdateKvKPerformanceAsync(int kingdomId, object battleResults, object performanceMetrics, CancellationToken cancellationToken = default)
        {
            try
            {
                _logger.LogInformation("Updating KvK performance for kingdom {KingdomId}", kingdomId);

                var kingdom = await _context.Kingdoms
                    .FirstOrDefaultAsync(k => k.Id == kingdomId, cancellationToken);

                if (kingdom == null)
                {
                    throw new InvalidOperationException($"Kingdom {kingdomId} not found");
                }

                kingdom.LastActivity = DateTime.UtcNow;
                // In production, this would update actual KvK performance fields

                await _context.SaveChangesAsync(cancellationToken);

                _logger.LogInformation("Successfully updated KvK performance for kingdom {KingdomId}", kingdomId);
                return kingdom;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error updating KvK performance for kingdom {KingdomId}", kingdomId);
                throw new InvalidOperationException($"Failed to update KvK performance for kingdom {kingdomId}", ex);
            }
        }

        /// <summary>
        /// Proposes a merger between two kingdoms
        /// </summary>
        public async Task<object> ProposeMergerAsync(int sourceKingdomId, int targetKingdomId, string reason, CancellationToken cancellationToken = default)
        {
            try
            {
                _logger.LogInformation("Proposing merger: {SourceKingdom} -> {TargetKingdom}, reason: {Reason}",
                    sourceKingdomId, targetKingdomId, reason);

                // Validate merger eligibility
                var eligibleKingdoms = await GetKingdomsEligibleForMergerAsync(sourceKingdomId, cancellationToken);
                if (!eligibleKingdoms.Any(k => k.Id == targetKingdomId))
                {
                    throw new InvalidOperationException("Kingdoms are not eligible for merger");
                }

                var proposal = new
                {
                    ProposalId = Guid.NewGuid(),
                    SourceKingdomId = sourceKingdomId,
                    TargetKingdomId = targetKingdomId,
                    Reason = reason,
                    ProposedAt = DateTime.UtcNow,
                    Status = "Proposed",
                    RequiresVoting = true
                };

                _logger.LogInformation("Successfully created merger proposal: {ProposalId}", proposal.ProposalId);
                return proposal;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error proposing merger between {SourceKingdom} and {TargetKingdom}",
                    sourceKingdomId, targetKingdomId);
                throw new InvalidOperationException($"Failed to propose merger between {sourceKingdomId} and {targetKingdomId}", ex);
            }
        }

        /// <summary>
        /// Gets kingdoms compatible for merger with compatibility scores and benefits
        /// FIXED: Returns tuple with compatibility scores and benefits matching interface signature exactly
        /// </summary>
        public async Task<IEnumerable<(KingdomModel Kingdom, double CompatibilityScore, string[] Benefits)>> GetMergerCompatibleKingdomsAsync(int kingdomId, CancellationToken cancellationToken = default)
        {
            try
            {
                _logger.LogDebug("Getting merger compatible kingdoms for {KingdomId}", kingdomId);

                var (currentActive, _, currentTotal) = await GetKingdomPopulationAsync(kingdomId, false, cancellationToken);
                const int maxMergedPopulation = 1500;

                var candidates = new List<(KingdomModel Kingdom, double CompatibilityScore, string[] Benefits)>();
                var otherKingdoms = await _context.Kingdoms
                    .Where(k => k.Id != kingdomId && k.IsActive && !k.IsInKvK)
                    .ToListAsync(cancellationToken);

                var currentKingdom = await _context.Kingdoms.FirstOrDefaultAsync(k => k.Id == kingdomId);
                if (currentKingdom == null)
                {
                    throw new InvalidOperationException($"Kingdom {kingdomId} not found");
                }

                foreach (var kingdom in otherKingdoms)
                {
                    var (otherActive, _, otherTotal) = await GetKingdomPopulationAsync(kingdom.Id, false, cancellationToken);

                    if (currentActive + otherActive <= maxMergedPopulation)
                    {
                        var compatibilityScore = CalculateMergerCompatibilityScore(currentTotal, otherTotal, currentKingdom, kingdom);
                        var benefits = CalculateMergerBenefits(currentKingdom, currentTotal, otherTotal);

                        candidates.Add((kingdom, compatibilityScore, benefits));
                    }
                }

                var orderedCandidates = candidates.OrderByDescending(c => c.CompatibilityScore);

                _logger.LogDebug("Found {Count} merger compatible kingdoms for kingdom {KingdomId}", candidates.Count, kingdomId);
                return orderedCandidates;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting merger compatible kingdoms for {KingdomId}", kingdomId);
                throw new InvalidOperationException($"Failed to get merger compatible kingdoms for {kingdomId}", ex);
            }
        }

        /// <summary>
        /// Executes a kingdom merger and returns the updated target kingdom
        /// FIXED: Returns Kingdom entity matching interface signature exactly
        /// </summary>
        public async Task<KingdomModel> ExecuteMergerAsync(int sourceKingdomId, int targetKingdomId, object mergerConfiguration, CancellationToken cancellationToken = default)
        {
            try
            {
                _logger.LogInformation("Executing merger: {SourceKingdom} -> {TargetKingdom}",
                    sourceKingdomId, targetKingdomId);

                using var transaction = await _context.Database.BeginTransactionAsync(cancellationToken);
                try
                {
                    // Move all players from source to target kingdom
                    var playersToMove = await _context.Players
                        .Where(p => p.KingdomId == sourceKingdomId)
                        .ToListAsync(cancellationToken);

                    foreach (var player in playersToMove)
                    {
                        player.KingdomId = targetKingdomId;
                    }

                    // Move all alliances from source to target kingdom
                    var alliancesToMove = await _context.Alliances
                        .Where(a => a.KingdomId == sourceKingdomId)
                        .ToListAsync(cancellationToken);

                    foreach (var alliance in alliancesToMove)
                    {
                        alliance.KingdomId = targetKingdomId;
                    }

                    // Archive source kingdom
                    await ArchiveKingdomAsync(sourceKingdomId, "Merged into another kingdom", cancellationToken);

                    // Get updated target kingdom and update population
                    var targetKingdom = await _context.Kingdoms
                        .FirstOrDefaultAsync(k => k.Id == targetKingdomId, cancellationToken);

                    if (targetKingdom == null)
                    {
                        throw new InvalidOperationException($"Target kingdom {targetKingdomId} not found");
                    }

                    var (newActive, newInactive, newTotal) = await GetKingdomPopulationAsync(targetKingdomId, false, cancellationToken);
                    targetKingdom.CurrentPopulation = newTotal;
                    targetKingdom.LastActivity = DateTime.UtcNow;

                    await _context.SaveChangesAsync(cancellationToken);
                    await transaction.CommitAsync(cancellationToken);

                    _logger.LogInformation("Successfully executed merger: moved {PlayerCount} players and {AllianceCount} alliances",
                        playersToMove.Count, alliancesToMove.Count);

                    return targetKingdom;
                }
                catch
                {
                    await transaction.RollbackAsync(cancellationToken);
                    throw;
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error executing merger: {SourceKingdom} -> {TargetKingdom}",
                    sourceKingdomId, targetKingdomId);
                throw new InvalidOperationException($"Failed to execute merger from {sourceKingdomId} to {targetKingdomId}", ex);
            }
        }

        /// <summary>
        /// Gets the royal court (leadership) of a kingdom
        /// </summary>
        public async Task<object> GetKingdomRoyalCourtAsync(int kingdomId, CancellationToken cancellationToken = default)
        {
            try
            {
                _logger.LogDebug("Getting royal court for kingdom {KingdomId}", kingdomId);

                var kingdom = await _context.Kingdoms
                    .FirstOrDefaultAsync(k => k.Id == kingdomId, cancellationToken);

                if (kingdom == null)
                {
                    throw new InvalidOperationException($"Kingdom {kingdomId} not found");
                }

                var topAlliances = await _context.Alliances
                    .Where(a => a.KingdomId == kingdomId && a.IsActive)
                    .OrderByDescending(a => a.Power)
                    .Take(5)
                    .Include(a => a.Leader)
                    .ToListAsync(cancellationToken);

                var royalCourt = new
                {
                    KingdomId = kingdomId,
                    KingdomName = kingdom.Name,
                    KvKHostAllianceId = kingdom.KvKHostAllianceId,
                    TopAlliances = topAlliances.Select(a => new
                    {
                        AllianceId = a.Id,
                        AllianceName = a.Name,
                        LeaderName = a.Leader?.Name ?? "Unknown",
                        Power = a.Power,
                        MemberCount = a.MemberCount
                    }).ToList(),
                    TotalTaxCollected = kingdom.TotalTaxCollected,
                    PowerRank = kingdom.CurrentPowerRank
                };

                _logger.LogDebug("Retrieved royal court for kingdom {KingdomId}", kingdomId);
                return royalCourt;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting royal court for kingdom {KingdomId}", kingdomId);
                throw new InvalidOperationException($"Failed to get royal court for kingdom {kingdomId}", ex);
            }
        }

        /// <summary>
        /// Initiates a royal election for kingdom leadership
        /// </summary>
        public async Task<object> InitiateRoyalElectionAsync(int kingdomId, string electionType, TimeSpan duration, CancellationToken cancellationToken = default)
        {
            try
            {
                _logger.LogInformation("Initiating royal election for kingdom {KingdomId}: {ElectionType}", kingdomId, electionType);

                var candidates = await _context.Alliances
                    .Where(a => a.KingdomId == kingdomId && a.IsActive && a.MemberCount >= 10)
                    .OrderByDescending(a => a.Power)
                    .Take(5)
                    .ToListAsync(cancellationToken);

                var election = new
                {
                    ElectionId = Guid.NewGuid(),
                    KingdomId = kingdomId,
                    ElectionType = electionType,
                    StartTime = DateTime.UtcNow,
                    EndTime = DateTime.UtcNow.Add(duration),
                    Duration = duration,
                    Candidates = candidates.Select(a => new
                    {
                        AllianceId = a.Id,
                        AllianceName = a.Name,
                        LeaderName = a.Leader?.Name ?? "Unknown",
                        Power = a.Power,
                        Votes = 0
                    }).ToList(),
                    Status = "Active"
                };

                _logger.LogInformation("Successfully initiated royal election {ElectionId} with {CandidateCount} candidates",
                    election.ElectionId, candidates.Count);

                return election;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error initiating royal election for kingdom {KingdomId}", kingdomId);
                throw new InvalidOperationException($"Failed to initiate royal election for kingdom {kingdomId}", ex);
            }
        }

        /// <summary>
        /// Updates tax distribution for a kingdom and returns updated kingdom
        /// FIXED: Returns Kingdom entity matching interface signature exactly
        /// </summary>
        public async Task<KingdomModel> UpdateTaxDistributionAsync(int kingdomId, object distributionConfiguration, int distributorPlayerId, CancellationToken cancellationToken = default)
        {
            try
            {
                _logger.LogInformation("Updating tax distribution for kingdom {KingdomId} by player {DistributorPlayerId}",
                    kingdomId, distributorPlayerId);

                var kingdom = await _context.Kingdoms
                    .FirstOrDefaultAsync(k => k.Id == kingdomId, cancellationToken);

                if (kingdom == null)
                {
                    throw new InvalidOperationException($"Kingdom {kingdomId} not found");
                }

                kingdom.LastActivity = DateTime.UtcNow;
                // In production, this would update actual tax distribution settings

                await _context.SaveChangesAsync(cancellationToken);

                _logger.LogInformation("Successfully updated tax distribution for kingdom {KingdomId}", kingdomId);
                return kingdom;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error updating tax distribution for kingdom {KingdomId}", kingdomId);
                throw new InvalidOperationException($"Failed to update tax distribution for kingdom {kingdomId}", ex);
            }
        }

        /// <summary>
        /// Gets kingdom tax status and collection information
        /// </summary>
        public async Task<object> GetKingdomTaxStatusAsync(int kingdomId, CancellationToken cancellationToken = default)
        {
            try
            {
                _logger.LogDebug("Getting tax status for kingdom {KingdomId}", kingdomId);

                var kingdom = await _context.Kingdoms
                    .FirstOrDefaultAsync(k => k.Id == kingdomId, cancellationToken);

                if (kingdom == null)
                {
                    throw new InvalidOperationException($"Kingdom {kingdomId} not found");
                }

                var (activePlayers, _, _) = await GetKingdomPopulationAsync(kingdomId, false, cancellationToken);

                var taxStatus = new
                {
                    KingdomId = kingdomId,
                    TotalTaxCollected = kingdom.TotalTaxCollected,
                    TaxRate = 0.04m, // 4% standard rate
                    EligibleTaxpayers = activePlayers,
                    LastCollectionDate = kingdom.LastActivity,
                    NextCollectionDate = DateTime.UtcNow.AddDays(1),
                    TaxTreasury = kingdom.TotalTaxCollected * 0.5m, // 50% goes to royal treasury
                    Status = "Active"
                };

                _logger.LogDebug("Retrieved tax status for kingdom {KingdomId}", kingdomId);
                return taxStatus;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting tax status for kingdom {KingdomId}", kingdomId);
                throw new InvalidOperationException($"Failed to get tax status for kingdom {kingdomId}", ex);
            }
        }

        /// <summary>
        /// Gets comprehensive analytics for a kingdom
        /// </summary>
        public async Task<object> GetKingdomAnalyticsAsync(int kingdomId, TimeSpan analysisTimeframe, CancellationToken cancellationToken = default)
        {
            try
            {
                _logger.LogDebug("Getting analytics for kingdom {KingdomId} over timeframe {Timeframe}", kingdomId, analysisTimeframe);

                var kingdom = await _context.Kingdoms
                    .FirstOrDefaultAsync(k => k.Id == kingdomId, cancellationToken);

                if (kingdom == null)
                {
                    throw new InvalidOperationException($"Kingdom {kingdomId} not found");
                }

                var (activePlayers, inactivePlayers, totalPlayers) = await GetKingdomPopulationAsync(kingdomId, false, cancellationToken);
                var allianceCount = await _context.Alliances.Where(a => a.KingdomId == kingdomId && a.IsActive).CountAsync(cancellationToken);
                var totalPower = await _context.Players.Where(p => p.KingdomId == kingdomId && p.IsActive).SumAsync(p => p.Power, cancellationToken);

                var analytics = new
                {
                    KingdomId = kingdomId,
                    KingdomName = kingdom.Name,
                    AnalysisTimeframe = analysisTimeframe.ToString(),
                    Population = totalPlayers,
                    ActivePlayers = activePlayers,
                    InactivePlayers = inactivePlayers,
                    AllianceCount = allianceCount,
                    TotalPower = totalPower,
                    PowerRank = kingdom.CurrentPowerRank,
                    IsInKvK = kingdom.IsInKvK,
                    TotalTaxCollected = kingdom.TotalTaxCollected,
                    CreatedAt = kingdom.CreatedAt,
                    LastActivity = kingdom.LastActivity,
                    GrowthRate = totalPlayers / Math.Max(1, (DateTime.UtcNow - kingdom.CreatedAt).Days),
                    Status = kingdom.IsActive ? "Active" : "Archived"
                };

                _logger.LogDebug("Retrieved analytics for kingdom {KingdomId}", kingdomId);
                return analytics;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting analytics for kingdom {KingdomId}", kingdomId);
                throw new InvalidOperationException($"Failed to get analytics for kingdom {kingdomId}", ex);
            }
        }

        /// <summary>
        /// Gets benchmark analysis comparing kingdom to others
        /// </summary>
        public async Task<object> GetKingdomBenchmarkAnalysisAsync(int kingdomId, string benchmarkType, CancellationToken cancellationToken = default)
        {
            try
            {
                _logger.LogDebug("Getting benchmark analysis for kingdom {KingdomId}: {BenchmarkType}", kingdomId, benchmarkType);

                var kingdom = await _context.Kingdoms
                    .FirstOrDefaultAsync(k => k.Id == kingdomId, cancellationToken);

                if (kingdom == null)
                {
                    throw new InvalidOperationException($"Kingdom {kingdomId} not found");
                }

                var allKingdoms = await _context.Kingdoms
                    .Where(k => k.IsActive)
                    .ToListAsync(cancellationToken);

                var (currentActive, _, currentTotal) = await GetKingdomPopulationAsync(kingdomId, false, cancellationToken);
                var avgPopulation = 0.0;

                if (allKingdoms.Any())
                {
                    var populationTasks = allKingdoms.Select(async k => await GetKingdomPopulationAsync(k.Id, false, cancellationToken));
                    var populations = await Task.WhenAll(populationTasks);
                    avgPopulation = populations.Select(p => p.TotalPlayers).Average();
                }

                var benchmark = new
                {
                    KingdomId = kingdomId,
                    BenchmarkType = benchmarkType,
                    KingdomPopulation = currentTotal,
                    AveragePopulation = Math.Round(avgPopulation, 1),
                    PopulationPercentile = CalculatePercentile(currentTotal, allKingdoms.Count),
                    PowerRank = kingdom.CurrentPowerRank,
                    TotalKingdoms = allKingdoms.Count,
                    Performance = currentTotal > avgPopulation ? "Above Average" : "Below Average",
                    GeneratedAt = DateTime.UtcNow
                };

                _logger.LogDebug("Generated benchmark analysis for kingdom {KingdomId}", kingdomId);
                return benchmark;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting benchmark analysis for kingdom {KingdomId}", kingdomId);
                throw new InvalidOperationException($"Failed to get benchmark analysis for kingdom {kingdomId}", ex);
            }
        }

        /// <summary>
        /// Generates comprehensive health report for a kingdom
        /// </summary>
        public async Task<object> GenerateKingdomHealthReportAsync(int kingdomId, CancellationToken cancellationToken = default)
        {
            try
            {
                _logger.LogInformation("Generating health report for kingdom {KingdomId}", kingdomId);

                var kingdom = await _context.Kingdoms
                    .FirstOrDefaultAsync(k => k.Id == kingdomId, cancellationToken);

                if (kingdom == null)
                {
                    throw new InvalidOperationException($"Kingdom {kingdomId} not found");
                }

                var (activePlayers, inactivePlayers, totalPlayers) = await GetKingdomPopulationAsync(kingdomId, false, cancellationToken);
                var allianceCount = await _context.Alliances.Where(a => a.KingdomId == kingdomId && a.IsActive).CountAsync(cancellationToken);
                var totalPower = await _context.Players.Where(p => p.KingdomId == kingdomId && p.IsActive).SumAsync(p => p.Power, cancellationToken);

                var healthScore = CalculateHealthScore(totalPlayers, allianceCount, totalPower, kingdom);
                var recommendations = GenerateHealthRecommendations(healthScore, totalPlayers, allianceCount, kingdom);

                var healthReport = new
                {
                    KingdomId = kingdomId,
                    KingdomName = kingdom.Name,
                    OverallHealthScore = healthScore,
                    Population = totalPlayers,
                    ActivePlayers = activePlayers,
                    InactivePlayers = inactivePlayers,
                    AllianceCount = allianceCount,
                    TotalPower = totalPower,
                    PowerRank = kingdom.CurrentPowerRank,
                    IsInKvK = kingdom.IsInKvK,
                    DaysSinceCreated = (DateTime.UtcNow - kingdom.CreatedAt).Days,
                    LastActivityDaysAgo = (DateTime.UtcNow - kingdom.LastActivity).Days,
                    HealthStatus = GetHealthStatus(healthScore),
                    Recommendations = recommendations,
                    ReportGeneratedAt = DateTime.UtcNow
                };

                _logger.LogInformation("Generated health report for kingdom {KingdomId} with score {HealthScore}",
                    kingdomId, healthScore);

                return healthReport;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error generating health report for kingdom {KingdomId}", kingdomId);
                throw new InvalidOperationException($"Failed to generate health report for kingdom {kingdomId}", ex);
            }
        }

        /// <summary>
        /// Gets all kingdoms with optional filtering
        /// </summary>
        public async Task<IEnumerable<KingdomModel>> GetAllKingdomsAsync(bool activeOnly = true, int? limit = null, CancellationToken cancellationToken = default)
        {
            try
            {
                _logger.LogDebug("Getting all kingdoms, active only: {ActiveOnly}, limit: {Limit}", activeOnly, limit);

                var query = _context.Kingdoms.AsQueryable();

                if (activeOnly)
                {
                    query = query.Where(k => k.IsActive);
                }

                query = query.OrderByDescending(k => k.CurrentPowerRank);

                if (limit.HasValue)
                {
                    query = query.Take(limit.Value);
                }

                var kingdoms = await query.ToListAsync(cancellationToken);

                _logger.LogDebug("Retrieved {Count} kingdoms", kingdoms.Count);
                return kingdoms;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting all kingdoms");
                throw new InvalidOperationException("Failed to get all kingdoms", ex);
            }
        }

        /// <summary>
        /// Searches kingdoms globally based on criteria
        /// </summary>
        public async Task<IEnumerable<KingdomModel>> SearchKingdomsGloballyAsync(object searchCriteria, int maxResults, CancellationToken cancellationToken = default)
        {
            try
            {
                _logger.LogDebug("Searching kingdoms globally with max results: {MaxResults}", maxResults);

                // For now, return kingdoms ordered by power rank (in production, would parse searchCriteria)
                var kingdoms = await _context.Kingdoms
                    .Where(k => k.IsActive)
                    .OrderBy(k => k.CurrentPowerRank)
                    .Take(maxResults)
                    .ToListAsync(cancellationToken);

                _logger.LogDebug("Found {Count} kingdoms in global search", kingdoms.Count);
                return kingdoms;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error searching kingdoms globally");
                throw new InvalidOperationException("Failed to search kingdoms globally", ex);
            }
        }

        #endregion

        #region Helper Methods

        private async Task<double> CalculateKvKCompatibilityScore(int kingdom1Id, int kingdom2Id, CancellationToken cancellationToken)
        {
            try
            {
                var (kingdom1Active, _, kingdom1Total) = await GetKingdomPopulationAsync(kingdom1Id, false, cancellationToken);
                var (kingdom2Active, _, kingdom2Total) = await GetKingdomPopulationAsync(kingdom2Id, false, cancellationToken);

                // Simple compatibility calculation based on population similarity
                var populationDifference = Math.Abs(kingdom1Active - kingdom2Active);
                var maxPopulation = Math.Max(kingdom1Active, kingdom2Active);

                if (maxPopulation == 0) return 0.5; // Default score for empty kingdoms

                var compatibilityScore = 1.0 - (populationDifference / (double)maxPopulation);
                return Math.Max(0.0, Math.Min(1.0, compatibilityScore));
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "Error calculating KvK compatibility score, returning default");
                return 0.5;
            }
        }

        private double CalculateMergerCompatibilityScore(int currentPop, int otherPop, KingdomModel currentKingdom, KingdomModel otherKingdom)
        {
            // Population size balance (prefer similar sizes)
            var totalSize = currentPop + otherPop;
            var sizeBalance = 1.0 - Math.Abs(currentPop - otherPop) / (double)Math.Max(currentPop, otherPop);

            // Optimal total size (prefer mergers that result in viable kingdom size 800-1200)
            var sizeOptimality = totalSize >= 800 && totalSize <= 1200 ?
                1.0 : Math.Max(0, (1500 - totalSize) / 300.0);

            return (sizeBalance + sizeOptimality) / 2.0;
        }

        private string[] CalculateMergerBenefits(KingdomModel kingdom, int currentPop, int otherPop)
        {
            var benefits = new List<string>();

            benefits.Add($"Combined population: {currentPop + otherPop}");
            benefits.Add("Increased alliance diversity");
            benefits.Add("Enhanced KvK competitiveness");

            if (kingdom.CurrentPowerRank < 50)
            {
                benefits.Add("Access to high-ranking kingdom benefits");
            }

            return benefits.ToArray();
        }

        private int CalculatePercentile(int value, int totalCount)
        {
            if (totalCount == 0) return 50;
            // Simplified percentile calculation
            return Math.Min(100, Math.Max(0, (value * 100) / (totalCount * 1500))); // Assuming max 1500 per kingdom
        }

        private int CalculateHealthScore(int population, int allianceCount, long totalPower, KingdomModel kingdom)
        {
            var score = 50; // Base score

            // Population health (0-30 points)
            if (population > 1000) score += 30;
            else if (population > 500) score += 20;
            else if (population > 100) score += 10;

            // Alliance diversity (0-20 points)
            if (allianceCount > 10) score += 20;
            else if (allianceCount > 5) score += 15;
            else if (allianceCount > 2) score += 10;
            else if (allianceCount > 0) score += 5;

            // Activity (0-20 points)
            var daysSinceActivity = (DateTime.UtcNow - kingdom.LastActivity).Days;
            if (daysSinceActivity < 1) score += 20;
            else if (daysSinceActivity < 7) score += 15;
            else if (daysSinceActivity < 30) score += 10;
            else score -= 10;

            // Power ranking (0-30 points)
            if (kingdom.CurrentPowerRank <= 10) score += 30;
            else if (kingdom.CurrentPowerRank <= 50) score += 20;
            else if (kingdom.CurrentPowerRank <= 100) score += 10;

            return Math.Max(0, Math.Min(100, score));
        }

        private string GetHealthStatus(int healthScore)
        {
            return healthScore switch
            {
                >= 80 => "Excellent",
                >= 60 => "Good",
                >= 40 => "Fair",
                >= 20 => "Poor",
                _ => "Critical"
            };
        }

        private List<string> GenerateHealthRecommendations(int healthScore, int population, int allianceCount, KingdomModel kingdom)
        {
            var recommendations = new List<string>();

            if (population < 500)
                recommendations.Add("Recruit more players to increase kingdom strength");

            if (allianceCount < 5)
                recommendations.Add("Encourage formation of more alliances for better organization");

            if ((DateTime.UtcNow - kingdom.LastActivity).Days > 7)
                recommendations.Add("Increase kingdom activity through events and competitions");

            if (kingdom.CurrentPowerRank > 50)
                recommendations.Add("Focus on power growth through coordinated alliance activities");

            if (!kingdom.IsInKvK && population > 800)
                recommendations.Add("Consider participating in KvK events for greater rewards");

            if (recommendations.Count == 0)
                recommendations.Add("Kingdom is performing well - maintain current strategies");

            return recommendations;
        }

        #endregion
    }
}