/*
 * File: ShadowedRealms.Core/Models/Kingdom/Kingdom.cs
 * Created: 2025-10-19
 * Last Modified: 2025-10-19
 * Description: Core Kingdom entity representing a game server/realm. Handles kingdom-level statistics, population management, and serves as the root entity for all kingdom-scoped data.
 * Last Edit Notes: Added missing properties for repository compatibility and IKingdomScoped interface implementation
 */

using ShadowedRealms.Core.Interfaces;
using ShadowedRealms.Core.Models.Alliance;
using ShadowedRealms.Core.Models.Player;
using System.ComponentModel.DataAnnotations;

namespace ShadowedRealms.Core.Models.Kingdom
{
    public class Kingdom : IKingdomScoped
    {
        public int Id { get; set; }

        [Required]
        [StringLength(50, MinimumLength = 3)]
        public string Name { get; set; } = string.Empty;

        [Required]
        public int Number { get; set; }

        [Required]
        public DateTime CreatedAt { get; set; } = DateTime.UtcNow;

        [Required]
        public bool IsActive { get; set; } = true;

        [Required]
        [Range(100, 3000)]
        public int MaxPopulation { get; set; } = 1500;

        [Required]
        [Range(0, int.MaxValue)]
        public int CurrentPopulation { get; set; } = 0;

        [Required]
        [Range(0, long.MaxValue)]
        public long TotalPower { get; set; } = 0;

        public DateTime? LastKvKDate { get; set; }

        [Range(0, int.MaxValue)]
        public int KvKWins { get; set; } = 0;

        [Range(0, int.MaxValue)]
        public int KvKLosses { get; set; } = 0;

        [Range(0, int.MaxValue)]
        public int KvKDraws { get; set; } = 0;

        public bool IsEligibleForKvK { get; set; } = true;

        public bool AcceptingNewPlayers { get; set; } = true;

        public DateTime? MergerAvailableDate { get; set; }

        public bool IsEligibleForMerger { get; set; } = false;

        [StringLength(500)]
        public string? Description { get; set; }

        [StringLength(200)]
        public string? WelcomeMessage { get; set; }

        // Kingdom settings
        public bool AutoKickInactivePlayers { get; set; } = true;

        [Range(1, 90)]
        public int InactivityKickDays { get; set; } = 30;

        public bool EnableTaxSystem { get; set; } = false;

        [Range(0.0, 0.1)]
        public decimal TaxRate { get; set; } = 0.04m; // 4% default

        // ADDED: Missing properties that repository expects
        public DateTime LastActivity { get; set; } = DateTime.UtcNow;

        public decimal TotalTaxCollected { get; set; } = 0m;

        public bool IsInKvK { get; set; } = false;

        public int? KvKHostAllianceId { get; set; }

        public int CurrentPowerRank { get; set; } = 0;

        // IKingdomScoped implementation - Kingdom is a root entity, so KingdomId is its own Id
        public int KingdomId
        {
            get => Id;
            set => Id = value;
        }

        // Navigation properties
        public virtual ICollection<Player.Player> Players { get; set; } = new List<Player.Player>();

        public virtual ICollection<Alliance.Alliance> Alliances { get; set; } = new List<Alliance.Alliance>();

        // Computed properties
        public int ActivePlayerCount => Players?.Count(p => p.IsActive) ?? 0;

        public int ActiveAllianceCount => Alliances?.Count(a => a.IsActive && a.Members.Any(m => m.IsActive)) ?? 0;

        public double PopulationPercentage => MaxPopulation > 0 ? (double)CurrentPopulation / MaxPopulation * 100 : 0;

        public bool IsNearCapacity => PopulationPercentage >= 90;

        public bool IsOverCapacity => CurrentPopulation > MaxPopulation;

        public int KvKTotalGames => KvKWins + KvKLosses + KvKDraws;

        public double KvKWinRate => KvKTotalGames > 0 ? (double)KvKWins / KvKTotalGames * 100 : 0;

        public bool CanParticipateInKvK => IsActive && IsEligibleForKvK && ActiveAllianceCount >= 3;

        public int DaysUntilMergerEligible
        {
            get
            {
                if (MergerAvailableDate == null) return -1;
                var days = (MergerAvailableDate.Value - DateTime.UtcNow).Days;
                return Math.Max(0, days);
            }
        }

        // Kingdom health metrics
        public KingdomHealthStatus GetHealthStatus()
        {
            if (!IsActive) return KingdomHealthStatus.Inactive;

            var activePlayers = ActivePlayerCount;
            var populationPercentage = PopulationPercentage;

            if (activePlayers < 100) return KingdomHealthStatus.Critical;
            if (activePlayers < 300 || populationPercentage < 20) return KingdomHealthStatus.Poor;
            if (activePlayers < 600 || populationPercentage < 40) return KingdomHealthStatus.Fair;
            if (activePlayers < 900 || populationPercentage < 60) return KingdomHealthStatus.Good;

            return KingdomHealthStatus.Excellent;
        }

        // Kingdom merger eligibility check
        public bool CanMergeWith(Kingdom otherKingdom)
        {
            if (otherKingdom == null || !otherKingdom.IsActive || !IsActive)
                return false;

            if (!IsEligibleForMerger || !otherKingdom.IsEligibleForMerger)
                return false;

            var combinedPopulation = CurrentPopulation + otherKingdom.CurrentPopulation;
            var targetMaxPopulation = Math.Max(MaxPopulation, otherKingdom.MaxPopulation);

            return combinedPopulation <= targetMaxPopulation * 1.1; // Allow 10% over capacity temporarily
        }

        // Resource tax calculation
        public long CalculateTaxAmount(long resourceAmount)
        {
            if (!EnableTaxSystem || TaxRate <= 0)
                return 0;

            return (long)(resourceAmount * (decimal)TaxRate);
        }

        // Kingdom progression tracking
        public void UpdatePopulation()
        {
            CurrentPopulation = Players?.Count(p => p.IsActive) ?? 0;
            TotalPower = Players?.Where(p => p.IsActive).Sum(p => p.Power) ?? 0;
            LastActivity = DateTime.UtcNow; // Update last activity when population changes

            // Update merger eligibility based on population health
            var healthStatus = GetHealthStatus();
            IsEligibleForMerger = healthStatus == KingdomHealthStatus.Critical ||
                                healthStatus == KingdomHealthStatus.Poor;

            // Set merger available date if becoming eligible
            if (IsEligibleForMerger && MergerAvailableDate == null)
            {
                MergerAvailableDate = DateTime.UtcNow.AddDays(30); // 30-day waiting period
            }
            else if (!IsEligibleForMerger)
            {
                MergerAvailableDate = null;
            }
        }

        // KvK record management
        public void RecordKvKResult(KvKResult result)
        {
            switch (result)
            {
                case KvKResult.Win:
                    KvKWins++;
                    break;
                case KvKResult.Loss:
                    KvKLosses++;
                    break;
                case KvKResult.Draw:
                    KvKDraws++;
                    break;
            }

            LastKvKDate = DateTime.UtcNow;
            LastActivity = DateTime.UtcNow; // Update last activity

            // Update KvK eligibility based on recent performance and kingdom health
            var healthStatus = GetHealthStatus();
            IsEligibleForKvK = healthStatus != KingdomHealthStatus.Critical &&
                              healthStatus != KingdomHealthStatus.Inactive;
        }

        // Validation methods
        public List<string> ValidateKingdomSettings()
        {
            var errors = new List<string>();

            if (MaxPopulation < 100)
                errors.Add("Maximum population must be at least 100 players");

            if (MaxPopulation > 3000)
                errors.Add("Maximum population cannot exceed 3000 players");

            if (TaxRate < 0 || TaxRate > 0.1m)
                errors.Add("Tax rate must be between 0% and 10%");

            if (InactivityKickDays < 1 || InactivityKickDays > 90)
                errors.Add("Inactivity kick period must be between 1 and 90 days");

            if (string.IsNullOrWhiteSpace(Name) || Name.Length < 3)
                errors.Add("Kingdom name must be at least 3 characters long");

            return errors;
        }

        public override string ToString()
        {
            return $"Kingdom {Number}: {Name} ({CurrentPopulation}/{MaxPopulation} players)";
        }
    }

    // Supporting enums
    public enum KingdomHealthStatus
    {
        Inactive = 0,
        Critical = 1,
        Poor = 2,
        Fair = 3,
        Good = 4,
        Excellent = 5
    }

    public enum KvKResult
    {
        Win = 1,
        Loss = 2,
        Draw = 3
    }
}