/*
 * File: /src/server/ShadowedRealms.Core/Interfaces/Repositories/IKingdomRepository.cs
 * Created: 2025-10-19
 * Last Modified: 2025-10-19
 * Description: Kingdom repository interface defining kingdom-specific data access operations.
 *              Handles kingdom lifecycle, population management, KvK events, merger systems,
 *              and democratic political mechanics. Since Kingdom is the root scoping entity,
 *              this interface includes special operations for cross-kingdom queries when needed.
 * Last Edit Notes: Initial implementation with population management, KvK systems, merger mechanics, and political operations.
 */

using ShadowedRealms.Core.Models;
using ShadowedRealms.Core.Models.Kingdom;
using System.Linq.Expressions;

namespace ShadowedRealms.Core.Interfaces.Repositories
{
    /// <summary>
    /// Repository interface for Kingdom entity operations, providing kingdom lifecycle management,
    /// population control, KvK event coordination, merger systems, and democratic political mechanics.
    /// This is the root repository that enables cross-kingdom operations when specifically needed.
    /// </summary>
    public interface IKingdomRepository : IRepository<Kingdom, int>
    {
        #region Kingdom Lifecycle Management

        /// <summary>
        /// Creates a new kingdom with initial configuration and assigns it the next available kingdom number.
        /// Automatically sets up default political structure and resource allocation systems.
        /// </summary>
        /// <param name="kingdomName">The name for the new kingdom</param>
        /// <param name="serverRegion">The server region where the kingdom will be hosted</param>
        /// <param name="cancellationToken">Cancellation token for async operation</param>
        /// <returns>The newly created kingdom with initial configuration</returns>
        /// <exception cref="ArgumentException">Thrown when kingdomName is invalid or serverRegion is not supported</exception>
        /// <exception cref="InvalidOperationException">Thrown when kingdom creation fails due to system constraints</exception>
        /// <exception cref="OperationCanceledException">Thrown when operation is cancelled</exception>
        Task<Kingdom> CreateNewKingdomAsync(string kingdomName, string serverRegion,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// Gets all kingdoms that are currently accepting new players based on population thresholds.
        /// Returns kingdoms with population below the maximum capacity (1,500 players) sorted by creation date.
        /// </summary>
        /// <param name="cancellationToken">Cancellation token for async operation</param>
        /// <returns>Available kingdoms for new player registration</returns>
        /// <exception cref="OperationCanceledException">Thrown when operation is cancelled</exception>
        Task<IEnumerable<Kingdom>> GetAvailableKingdomsForNewPlayersAsync(CancellationToken cancellationToken = default);

        /// <summary>
        /// Gets the newest kingdom that has space for new players, creating one if none exist.
        /// This is used for the default kingdom assignment when players don't choose manually.
        /// </summary>
        /// <param name="serverRegion">The preferred server region for kingdom selection</param>
        /// <param name="cancellationToken">Cancellation token for async operation</param>
        /// <returns>The newest available kingdom or a newly created one</returns>
        /// <exception cref="ArgumentException">Thrown when serverRegion is invalid</exception>
        /// <exception cref="InvalidOperationException">Thrown when kingdom selection/creation fails</exception>
        /// <exception cref="OperationCanceledException">Thrown when operation is cancelled</exception>
        Task<Kingdom> GetNewestAvailableKingdomAsync(string serverRegion,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// Archives a kingdom that no longer has active players or has been merged into another kingdom.
        /// Preserves historical data while removing the kingdom from active matchmaking and operations.
        /// </summary>
        /// <param name="kingdomId">The ID of the kingdom to archive</param>
        /// <param name="archiveReason">The reason for archiving (merger, inactivity, etc.)</param>
        /// <param name="cancellationToken">Cancellation token for async operation</param>
        /// <returns>True if kingdom was archived successfully</returns>
        /// <exception cref="ArgumentException">Thrown when kingdomId is invalid or kingdom cannot be archived</exception>
        /// <exception cref="InvalidOperationException">Thrown when kingdom has active players or pending operations</exception>
        /// <exception cref="OperationCanceledException">Thrown when operation is cancelled</exception>
        Task<bool> ArchiveKingdomAsync(int kingdomId, string archiveReason,
            CancellationToken cancellationToken = default);

        #endregion

        #region Population Management

        /// <summary>
        /// Gets the current population count for a specific kingdom including active and inactive players.
        /// Used for kingdom capacity management and merger eligibility determination.
        /// </summary>
        /// <param name="kingdomId">The kingdom to get population for</param>
        /// <param name="includeInactive">Whether to include players who haven't logged in recently</param>
        /// <param name="cancellationToken">Cancellation token for async operation</param>
        /// <returns>Current population statistics for the kingdom</returns>
        /// <exception cref="ArgumentException">Thrown when kingdomId is invalid</exception>
        /// <exception cref="OperationCanceledException">Thrown when operation is cancelled</exception>
        Task<(int ActivePlayers, int InactivePlayers, int TotalPlayers)> GetKingdomPopulationAsync(int kingdomId,
            bool includeInactive = false, CancellationToken cancellationToken = default);

        /// <summary>
        /// Gets kingdoms that are eligible for population-based merger based on low active player counts.
        /// Returns kingdoms with fewer than the minimum viable population (typically 300-500 active players).
        /// </summary>
        /// <param name="minimumViablePopulation">The minimum population threshold for kingdom viability</param>
        /// <param name="cancellationToken">Cancellation token for async operation</param>
        /// <returns>Kingdoms eligible for merger due to low population</returns>
        /// <exception cref="ArgumentException">Thrown when minimumViablePopulation is invalid</exception>
        /// <exception cref="OperationCanceledException">Thrown when operation is cancelled</exception>
        Task<IEnumerable<Kingdom>> GetKingdomsEligibleForMergerAsync(int minimumViablePopulation = 400,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// Updates the population statistics for a kingdom, typically called when players join/leave.
        /// Automatically triggers kingdom capacity events when thresholds are reached.
        /// </summary>
        /// <param name="kingdomId">The kingdom to update</param>
        /// <param name="populationChange">The change in population (positive for joins, negative for leaves)</param>
        /// <param name="cancellationToken">Cancellation token for async operation</param>
        /// <returns>Updated kingdom with new population statistics</returns>
        /// <exception cref="ArgumentException">Thrown when kingdomId is invalid</exception>
        /// <exception cref="InvalidOperationException">Thrown when population change would violate system constraints</exception>
        /// <exception cref="OperationCanceledException">Thrown when operation is cancelled</exception>
        Task<Kingdom> UpdateKingdomPopulationAsync(int kingdomId, int populationChange,
            CancellationToken cancellationToken = default);

        #endregion

        #region KvK Event Management

        /// <summary>
        /// Gets kingdoms that are eligible for KvK matchmaking based on power levels, participation history,
        /// and time zone compatibility. Uses multi-dimensional analysis beyond raw power comparison.
        /// </summary>
        /// <param name="targetKingdomId">The kingdom requesting matchmaking</param>
        /// <param name="eventType">The type of KvK event being organized</param>
        /// <param name="cancellationToken">Cancellation token for async operation</param>
        /// <returns>Kingdoms eligible for KvK matchmaking with compatibility scores</returns>
        /// <exception cref="ArgumentException">Thrown when targetKingdomId is invalid or eventType is unsupported</exception>
        /// <exception cref="OperationCanceledException">Thrown when operation is cancelled</exception>
        Task<IEnumerable<(Kingdom Kingdom, double CompatibilityScore)>> GetKvKEligibleKingdomsAsync(int targetKingdomId,
            string eventType, CancellationToken cancellationToken = default);

        /// <summary>
        /// Creates a new KvK event linking multiple kingdoms and initializes event-specific data structures.
        /// Sets up coalition systems, territory assignments, and victory condition tracking.
        /// </summary>
        /// <param name="participatingKingdomIds">The kingdoms participating in the event</param>
        /// <param name="eventType">The type of KvK event (3-kingdom, alliance wars, etc.)</param>
        /// <param name="startDate">When the event begins</param>
        /// <param name="duration">How long the event lasts</param>
        /// <param name="cancellationToken">Cancellation token for async operation</param>
        /// <returns>The created KvK event with initial configuration</returns>
        /// <exception cref="ArgumentException">Thrown when parameters are invalid or kingdoms are ineligible</exception>
        /// <exception cref="InvalidOperationException">Thrown when event creation fails due to system constraints</exception>
        /// <exception cref="OperationCanceledException">Thrown when operation is cancelled</exception>
        Task<object> CreateKvKEventAsync(IEnumerable<int> participatingKingdomIds, string eventType,
            DateTime startDate, TimeSpan duration, CancellationToken cancellationToken = default);

        /// <summary>
        /// Gets the current KvK events that a kingdom is participating in, including event status and performance metrics.
        /// Returns both active events and recent historical events for context.
        /// </summary>
        /// <param name="kingdomId">The kingdom to get KvK events for</param>
        /// <param name="includeHistorical">Whether to include completed events from the last 30 days</param>
        /// <param name="cancellationToken">Cancellation token for async operation</param>
        /// <returns>KvK events associated with the kingdom</returns>
        /// <exception cref="ArgumentException">Thrown when kingdomId is invalid</exception>
        /// <exception cref="OperationCanceledException">Thrown when operation is cancelled</exception>
        Task<IEnumerable<object>> GetKingdomKvKEventsAsync(int kingdomId, bool includeHistorical = false,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// Updates KvK performance metrics for a kingdom based on event participation and outcomes.
        /// Affects future matchmaking and influences kingdom power ratings.
        /// </summary>
        /// <param name="kingdomId">The kingdom to update</param>
        /// <param name="eventResult">The outcome of the KvK event</param>
        /// <param name="participationMetrics">Detailed participation statistics</param>
        /// <param name="cancellationToken">Cancellation token for async operation</param>
        /// <returns>Updated kingdom with new KvK performance data</returns>
        /// <exception cref="ArgumentException">Thrown when parameters are invalid</exception>
        /// <exception cref="InvalidOperationException">Thrown when update fails due to business rules</exception>
        /// <exception cref="OperationCanceledException">Thrown when operation is cancelled</exception>
        Task<Kingdom> UpdateKvKPerformanceAsync(int kingdomId, object eventResult, object participationMetrics,
            CancellationToken cancellationToken = default);

        #endregion

        #region Kingdom Merger System

        /// <summary>
        /// Initiates a merger proposal between two kingdoms, starting the democratic voting process.
        /// Both kingdoms must vote to approve the merger for it to proceed.
        /// </summary>
        /// <param name="initiatingKingdomId">The kingdom proposing the merger</param>
        /// <param name="targetKingdomId">The kingdom being invited to merge</param>
        /// <param name="proposalReason">The rationale for the merger proposal</param>
        /// <param name="cancellationToken">Cancellation token for async operation</param>
        /// <returns>The merger proposal with voting configuration</returns>
        /// <exception cref="ArgumentException">Thrown when kingdom IDs are invalid or kingdoms are ineligible</exception>
        /// <exception cref="InvalidOperationException">Thrown when merger proposal cannot be created</exception>
        /// <exception cref="OperationCanceledException">Thrown when operation is cancelled</exception>
        Task<object> ProposeMergerAsync(int initiatingKingdomId, int targetKingdomId, string proposalReason,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// Gets kingdoms that are compatible for merger based on population, power levels, play styles,
        /// and cultural compatibility. Used for suggesting merger partners to struggling kingdoms.
        /// </summary>
        /// <param name="kingdomId">The kingdom seeking merger partners</param>
        /// <param name="cancellationToken">Cancellation token for async operation</param>
        /// <returns>Compatible kingdoms with compatibility scores and merger benefits analysis</returns>
        /// <exception cref="ArgumentException">Thrown when kingdomId is invalid</exception>
        /// <exception cref="OperationCanceledException">Thrown when operation is cancelled</exception>
        Task<IEnumerable<(Kingdom Kingdom, double CompatibilityScore, string[] Benefits)>> GetMergerCompatibleKingdomsAsync(
            int kingdomId, CancellationToken cancellationToken = default);

        /// <summary>
        /// Executes an approved merger between two kingdoms, transferring all players, alliances, and resources
        /// to the surviving kingdom while preserving historical data and alliance relationships.
        /// </summary>
        /// <param name="survivingKingdomId">The kingdom that will continue to exist</param>
        /// <param name="mergingKingdomId">The kingdom that will be absorbed</param>
        /// <param name="mergerConfiguration">Settings for how the merger should be executed</param>
        /// <param name="cancellationToken">Cancellation token for async operation</param>
        /// <returns>The updated surviving kingdom with merged population and resources</returns>
        /// <exception cref="ArgumentException">Thrown when parameters are invalid or merger is not approved</exception>
        /// <exception cref="InvalidOperationException">Thrown when merger execution fails</exception>
        /// <exception cref="OperationCanceledException">Thrown when operation is cancelled</exception>
        Task<Kingdom> ExecuteMergerAsync(int survivingKingdomId, int mergingKingdomId, object mergerConfiguration,
            CancellationToken cancellationToken = default);

        #endregion

        #region Democratic Political System

        /// <summary>
        /// Gets the current royal court members for a kingdom including elected positions and appointed roles.
        /// Returns the democratic leadership structure with terms, election dates, and approval ratings.
        /// </summary>
        /// <param name="kingdomId">The kingdom to get leadership for</param>
        /// <param name="cancellationToken">Cancellation token for async operation</param>
        /// <returns>Current royal court structure with leadership details</returns>
        /// <exception cref="ArgumentException">Thrown when kingdomId is invalid</exception>
        /// <exception cref="OperationCanceledException">Thrown when operation is cancelled</exception>
        Task<object> GetKingdomRoyalCourtAsync(int kingdomId, CancellationToken cancellationToken = default);

        /// <summary>
        /// Initiates an election for a royal position within the kingdom's democratic system.
        /// Sets up the voting process, candidate registration, and election timeline.
        /// </summary>
        /// <param name="kingdomId">The kingdom holding the election</param>
        /// <param name="position">The royal position being elected (King, Chancellor, etc.)</param>
        /// <param name="electionDuration">How long the election period lasts</param>
        /// <param name="cancellationToken">Cancellation token for async operation</param>
        /// <returns>The election configuration with voting details</returns>
        /// <exception cref="ArgumentException">Thrown when parameters are invalid or election cannot be held</exception>
        /// <exception cref="InvalidOperationException">Thrown when election initiation fails</exception>
        /// <exception cref="OperationCanceledException">Thrown when operation is cancelled</exception>
        Task<object> InitiateRoyalElectionAsync(int kingdomId, string position, TimeSpan electionDuration,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// Updates the tax distribution settings for a kingdom based on royal court decisions.
        /// Manages the 4% resource tax on conquered kingdoms and how it's distributed among citizens.
        /// </summary>
        /// <param name="kingdomId">The kingdom to update tax settings for</param>
        /// <param name="taxDistributionRules">The new tax distribution configuration</param>
        /// <param name="authorizingPlayerId">The royal court member authorizing the change</param>
        /// <param name="cancellationToken">Cancellation token for async operation</param>
        /// <returns>Updated kingdom with new tax distribution settings</returns>
        /// <exception cref="ArgumentException">Thrown when parameters are invalid or player lacks authority</exception>
        /// <exception cref="InvalidOperationException">Thrown when tax update fails due to business rules</exception>
        /// <exception cref="OperationCanceledException">Thrown when operation is cancelled</exception>
        Task<Kingdom> UpdateTaxDistributionAsync(int kingdomId, object taxDistributionRules, int authorizingPlayerId,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// Gets kingdoms that have conquered other kingdoms and are collecting the 4% resource tax.
        /// Returns the tax collection status and distribution metrics for royal court oversight.
        /// </summary>
        /// <param name="kingdomId">The kingdom to get tax information for</param>
        /// <param name="cancellationToken">Cancellation token for async operation</param>
        /// <returns>Tax collection and distribution details</returns>
        /// <exception cref="ArgumentException">Thrown when kingdomId is invalid</exception>
        /// <exception cref="OperationCanceledException">Thrown when operation is cancelled</exception>
        Task<object> GetKingdomTaxStatusAsync(int kingdomId, CancellationToken cancellationToken = default);

        #endregion

        #region Analytics and Reporting

        /// <summary>
        /// Gets comprehensive kingdom statistics including population trends, economic metrics,
        /// military strength, and social engagement data for administrative analysis.
        /// </summary>
        /// <param name="kingdomId">The kingdom to get statistics for</param>
        /// <param name="timeRange">The time period to analyze (last 7 days, 30 days, etc.)</param>
        /// <param name="cancellationToken">Cancellation token for async operation</param>
        /// <returns>Detailed kingdom analytics and performance metrics</returns>
        /// <exception cref="ArgumentException">Thrown when parameters are invalid</exception>
        /// <exception cref="OperationCanceledException">Thrown when operation is cancelled</exception>
        Task<object> GetKingdomAnalyticsAsync(int kingdomId, TimeSpan timeRange,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// Gets kingdom performance metrics compared to other kingdoms in the same server region.
        /// Provides percentile rankings for population, activity, military strength, and economic health.
        /// </summary>
        /// <param name="kingdomId">The kingdom to benchmark</param>
        /// <param name="serverRegion">The server region for comparison</param>
        /// <param name="cancellationToken">Cancellation token for async operation</param>
        /// <returns>Benchmark analysis with percentile rankings</returns>
        /// <exception cref="ArgumentException">Thrown when parameters are invalid</exception>
        /// <exception cref="OperationCanceledException">Thrown when operation is cancelled</exception>
        Task<object> GetKingdomBenchmarkAnalysisAsync(int kingdomId, string serverRegion,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// Generates a kingdom health report identifying potential issues like population decline,
        /// economic problems, or social tensions that might require intervention.
        /// </summary>
        /// <param name="kingdomId">The kingdom to analyze</param>
        /// <param name="cancellationToken">Cancellation token for async operation</param>
        /// <returns>Kingdom health assessment with recommended actions</returns>
        /// <exception cref="ArgumentException">Thrown when kingdomId is invalid</exception>
        /// <exception cref="OperationCanceledException">Thrown when operation is cancelled</exception>
        Task<object> GenerateKingdomHealthReportAsync(int kingdomId, CancellationToken cancellationToken = default);

        #endregion

        #region Cross-Kingdom Operations (Special Authorization)

        /// <summary>
        /// Gets all kingdoms in the system - SPECIAL METHOD that bypasses kingdom scoping.
        /// Should only be used for administrative operations and system-level analytics.
        /// Requires special authorization and should be logged for security audit.
        /// </summary>
        /// <param name="includeArchived">Whether to include archived kingdoms</param>
        /// <param name="authorizingAdminId">The admin ID authorizing this cross-kingdom access</param>
        /// <param name="cancellationToken">Cancellation token for async operation</param>
        /// <returns>All kingdoms in the system</returns>
        /// <exception cref="UnauthorizedAccessException">Thrown when admin authorization is invalid</exception>
        /// <exception cref="OperationCanceledException">Thrown when operation is cancelled</exception>
        Task<IEnumerable<Kingdom>> GetAllKingdomsAsync(bool includeArchived = false, int? authorizingAdminId = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// Searches for kingdoms across all servers by name or other criteria.
        /// SPECIAL METHOD for administrative use that bypasses normal kingdom scoping.
        /// </summary>
        /// <param name="searchCriteria">The search parameters</param>
        /// <param name="authorizingAdminId">The admin ID authorizing this cross-kingdom search</param>
        /// <param name="cancellationToken">Cancellation token for async operation</param>
        /// <returns>Kingdoms matching the search criteria across all servers</returns>
        /// <exception cref="ArgumentNullException">Thrown when searchCriteria is null</exception>
        /// <exception cref="UnauthorizedAccessException">Thrown when admin authorization is invalid</exception>
        /// <exception cref="OperationCanceledException">Thrown when operation is cancelled</exception>
        Task<IEnumerable<Kingdom>> SearchKingdomsGloballyAsync(object searchCriteria, int authorizingAdminId,
            CancellationToken cancellationToken = default);

        #endregion
    }
}