/*
 * File: ShadowedRealms.Core/Models/Player/VipRewards.cs
 * Created: 2025-10-19
 * Last Modified: 2025-10-19
 * Description: VIP rewards and milestone system inspired by King of Avalon's undisclosed spending tier rewards. Tracks spending milestones, secret tiers, and monthly/yearly recognition rewards for high-value customers.
 * Last Edit Notes: Initial creation with secret tier system, milestone rewards, and whale retention mechanics
 */

using System.ComponentModel.DataAnnotations;
using System.Text.Json;

namespace ShadowedRealms.Core.Models.Player
{
    public class VipRewards
    {
        public int Id { get; set; }

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

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

        // VIP Points System (separate from spending to allow flexibility)
        [Required]
        [Range(0, int.MaxValue)]
        public int CurrentVipPoints { get; set; } = 0;

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

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

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

        // Secret Spending Tiers (undisclosed like King of Avalon)
        [Range(0, 15)]
        public int SecretTierLevel { get; set; } = 0; // 0-15 undisclosed tiers

        [Range(0, 15)]
        public int HighestSecretTierReached { get; set; } = 0;

        public DateTime? LastSecretTierUnlock { get; set; }

        // Monthly Recognition System
        public bool EligibleForMonthlyRewards { get; set; } = false;

        [Range(0, 12)]
        public int MonthlyRewardsEarned { get; set; } = 0; // How many months they've earned rewards

        public DateTime? LastMonthlyRewardDate { get; set; }

        [Range(0, double.MaxValue)]
        public decimal MonthlySpendingForRewards { get; set; } = 0;

        // Yearly Recognition System  
        public bool EligibleForYearlyRewards { get; set; } = false;

        [Range(0, 10)]
        public int YearlyRewardsEarned { get; set; } = 0; // How many years they've earned rewards

        public DateTime? LastYearlyRewardDate { get; set; }

        [Range(0, double.MaxValue)]
        public decimal YearlySpendingForRewards { get; set; } = 0;

        // Milestone Tracking
        public DateTime? LastMilestoneReached { get; set; }

        [StringLength(100)]
        public string? LastMilestoneType { get; set; }

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

        // Special Recognition Status
        public bool IsVipAmbassador { get; set; } = false; // Top 1% of spenders

        public bool IsFoundingSupporter { get; set; } = false; // Early high spenders

        public bool IsLoyalSupporter { get; set; } = false; // Consistent monthly spenders

        public bool IsLegendarySupporter { get; set; } = false; // Extreme lifetime spenders

        // Streak Tracking
        [Range(0, int.MaxValue)]
        public int ConsecutiveMonthsSpending { get; set; } = 0;

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

        public DateTime? CurrentStreakStartDate { get; set; }

        // Reward History (JSON storage for complex data)
        [StringLength(4000)]
        public string? RewardHistory { get; set; }

        [StringLength(2000)]
        public string? SpecialRecognitions { get; set; }

        // Dates for tracking
        public DateTime CreatedAt { get; set; } = DateTime.UtcNow;

        public DateTime LastUpdated { get; set; } = DateTime.UtcNow;

        public DateTime MonthlyResetDate { get; set; } = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, 1).AddMonths(1);

        public DateTime YearlyResetDate { get; set; } = new DateTime(DateTime.UtcNow.Year + 1, 1, 1);

        // Navigation Properties
        public virtual Player Player { get; set; } = null!;

        public virtual ICollection<VipMilestone> MilestonesReached { get; set; } = new List<VipMilestone>();

        public virtual ICollection<VipReward> RewardsClaimed { get; set; } = new List<VipReward>();

        // Computed Properties
        public int DaysUntilMonthlyReset => (MonthlyResetDate - DateTime.UtcNow).Days;

        public int DaysUntilYearlyReset => (YearlyResetDate - DateTime.UtcNow).Days;

        public bool IsCurrentMonthSpender => MonthlyVipPoints > 0;

        public bool IsCurrentYearSpender => YearlyVipPoints > 0;

        public VipTierStatus CurrentTierStatus => GetVipTierStatus();

        public SecretTierRewardLevel SecretRewardLevel => GetSecretTierRewardLevel();

        public bool HasEarnedMonthlyReward => MonthlyRewardsEarned > 0;

        public bool HasEarnedYearlyReward => YearlyRewardsEarned > 0;

        public double AverageMonthlySpending => MonthlyRewardsEarned > 0 ? (double)YearlySpendingForRewards / MonthlyRewardsEarned : 0;

        // Business Logic Methods
        public void AddVipPoints(int points, decimal spendingAmount)
        {
            CurrentVipPoints += points;
            LifetimeVipPoints += points;
            MonthlyVipPoints += points;
            YearlyVipPoints += points;

            MonthlySpendingForRewards += spendingAmount;
            YearlySpendingForRewards += spendingAmount;

            CheckForMilestones();
            UpdateSecretTier();
            UpdateSpecialStatus();
            LastUpdated = DateTime.UtcNow;
        }

        private void CheckForMilestones()
        {
            var newMilestones = new List<string>();

            // Check VIP point milestones (every 10,000 points)
            var pointMilestone = (LifetimeVipPoints / 10000) * 10000;
            if (pointMilestone > 0 && (LastMilestoneReached == null ||
                LifetimeVipPoints - (int)(LastMilestoneReached?.Subtract(DateTime.MinValue).TotalDays ?? 0) >= 10000))
            {
                newMilestones.Add($"VIP_POINTS_{pointMilestone}");
            }

            // Check monthly spending milestones
            if (MonthlySpendingForRewards >= 100 && !EligibleForMonthlyRewards)
            {
                EligibleForMonthlyRewards = true;
                newMilestones.Add("MONTHLY_ELIGIBLE");
            }

            // Check yearly spending milestones  
            if (YearlySpendingForRewards >= 500 && !EligibleForYearlyRewards)
            {
                EligibleForYearlyRewards = true;
                newMilestones.Add("YEARLY_ELIGIBLE");
            }

            // Update streak
            UpdateSpendingStreak();

            if (newMilestones.Any())
            {
                TotalMilestonesReached += newMilestones.Count;
                LastMilestoneReached = DateTime.UtcNow;
                LastMilestoneType = string.Join(",", newMilestones);
            }
        }

        private void UpdateSecretTier()
        {
            // Secret tier thresholds (undisclosed to players like KoA)
            var secretTierThresholds = new decimal[]
            {
                0,      // Tier 0
                50,     // Tier 1 - $50 lifetime
                150,    // Tier 2 - $150 lifetime
                300,    // Tier 3 - $300 lifetime
                500,    // Tier 4 - $500 lifetime
                750,    // Tier 5 - $750 lifetime
                1000,   // Tier 6 - $1,000 lifetime
                1500,   // Tier 7 - $1,500 lifetime
                2500,   // Tier 8 - $2,500 lifetime
                4000,   // Tier 9 - $4,000 lifetime
                6000,   // Tier 10 - $6,000 lifetime
                10000,  // Tier 11 - $10,000 lifetime
                15000,  // Tier 12 - $15,000 lifetime
                25000,  // Tier 13 - $25,000 lifetime
                50000,  // Tier 14 - $50,000 lifetime
                100000  // Tier 15 - $100,000 lifetime (theoretical max)
            };

            var newTier = 0;
            for (int i = secretTierThresholds.Length - 1; i >= 0; i--)
            {
                if (YearlySpendingForRewards >= secretTierThresholds[i])
                {
                    newTier = i;
                    break;
                }
            }

            if (newTier > SecretTierLevel)
            {
                SecretTierLevel = newTier;
                if (newTier > HighestSecretTierReached)
                {
                    HighestSecretTierReached = newTier;
                    LastSecretTierUnlock = DateTime.UtcNow;
                }
            }
        }

        private void UpdateSpecialStatus()
        {
            // VIP Ambassador - Top tier current year spenders
            IsVipAmbassador = SecretTierLevel >= 10 && IsCurrentYearSpender;

            // Founding Supporter - High spenders in first 6 months
            var gameAge = DateTime.UtcNow.Subtract(new DateTime(2025, 1, 1)); // Assuming game launch
            IsFoundingSupporter = gameAge.TotalDays <= 180 && HighestSecretTierReached >= 6;

            // Loyal Supporter - 6+ consecutive months of spending
            IsLoyalSupporter = ConsecutiveMonthsSpending >= 6;

            // Legendary Supporter - Lifetime tier 12+
            IsLegendarySupporter = HighestSecretTierReached >= 12;
        }

        private void UpdateSpendingStreak()
        {
            if (IsCurrentMonthSpender)
            {
                if (CurrentStreakStartDate == null)
                {
                    CurrentStreakStartDate = DateTime.UtcNow;
                    ConsecutiveMonthsSpending = 1;
                }
                else
                {
                    var monthsSinceStart = (DateTime.UtcNow.Year - CurrentStreakStartDate.Value.Year) * 12 +
                                         DateTime.UtcNow.Month - CurrentStreakStartDate.Value.Month;
                    ConsecutiveMonthsSpending = monthsSinceStart + 1;
                }

                if (ConsecutiveMonthsSpending > LongestSpendingStreak)
                {
                    LongestSpendingStreak = ConsecutiveMonthsSpending;
                }
            }
        }

        public VipTierStatus GetVipTierStatus()
        {
            return SecretTierLevel switch
            {
                >= 12 => VipTierStatus.Legendary,
                >= 10 => VipTierStatus.Ambassador,
                >= 8 => VipTierStatus.Elite,
                >= 6 => VipTierStatus.Premium,
                >= 4 => VipTierStatus.Advanced,
                >= 2 => VipTierStatus.Standard,
                >= 1 => VipTierStatus.Bronze,
                _ => VipTierStatus.None
            };
        }

        public SecretTierRewardLevel GetSecretTierRewardLevel()
        {
            // Different reward levels based on secret tier (like KoA's system)
            return SecretTierLevel switch
            {
                >= 13 => SecretTierRewardLevel.Mythical,    // $25,000+
                >= 11 => SecretTierRewardLevel.Legendary,   // $10,000+
                >= 9 => SecretTierRewardLevel.Epic,         // $2,500+
                >= 7 => SecretTierRewardLevel.Rare,         // $1,500+
                >= 5 => SecretTierRewardLevel.Uncommon,     // $750+
                >= 3 => SecretTierRewardLevel.Common,       // $300+
                >= 1 => SecretTierRewardLevel.Basic,        // $50+
                _ => SecretTierRewardLevel.None
            };
        }

        // Monthly reset (called by background service)
        public void ResetMonthlyProgress()
        {
            MonthlyVipPoints = 0;
            MonthlySpendingForRewards = 0;
            EligibleForMonthlyRewards = false;
            MonthlyResetDate = MonthlyResetDate.AddMonths(1);

            // Break spending streak if no spending this month
            if (MonthlyVipPoints == 0)
            {
                ConsecutiveMonthsSpending = 0;
                CurrentStreakStartDate = null;
            }

            LastUpdated = DateTime.UtcNow;
        }

        // Yearly reset (called by background service)
        public void ResetYearlyProgress()
        {
            YearlyVipPoints = 0;
            YearlySpendingForRewards = 0;
            EligibleForYearlyRewards = false;
            YearlyResetDate = YearlyResetDate.AddYears(1);
            SecretTierLevel = 0; // Secret tiers reset yearly like KoA

            LastUpdated = DateTime.UtcNow;
        }

        // Reward claiming
        public bool ClaimMonthlyReward()
        {
            if (!EligibleForMonthlyRewards || LastMonthlyRewardDate?.Month == DateTime.UtcNow.Month)
                return false;

            MonthlyRewardsEarned++;
            LastMonthlyRewardDate = DateTime.UtcNow;
            return true;
        }

        public bool ClaimYearlyReward()
        {
            if (!EligibleForYearlyRewards || LastYearlyRewardDate?.Year == DateTime.UtcNow.Year)
                return false;

            YearlyRewardsEarned++;
            LastYearlyRewardDate = DateTime.UtcNow;
            return true;
        }

        public List<VipRewardTier> GetAvailableRewards()
        {
            var rewards = new List<VipRewardTier>();

            // Monthly rewards
            if (EligibleForMonthlyRewards && (LastMonthlyRewardDate?.Month != DateTime.UtcNow.Month))
            {
                rewards.Add(new VipRewardTier
                {
                    Type = "Monthly",
                    TierLevel = SecretTierLevel,
                    RewardLevel = GetSecretTierRewardLevel(),
                    CanClaim = true
                });
            }

            // Yearly rewards
            if (EligibleForYearlyRewards && (LastYearlyRewardDate?.Year != DateTime.UtcNow.Year))
            {
                rewards.Add(new VipRewardTier
                {
                    Type = "Yearly",
                    TierLevel = HighestSecretTierReached,
                    RewardLevel = GetSecretTierRewardLevel(),
                    CanClaim = true
                });
            }

            return rewards;
        }

        public override string ToString()
        {
            var tierStatus = CurrentTierStatus;
            var rewardLevel = SecretRewardLevel;
            return $"VIP {tierStatus} (Secret Tier {SecretTierLevel}) - {rewardLevel} Rewards";
        }
    }

    // Supporting Classes
    public class VipMilestone
    {
        public int Id { get; set; }
        public int VipRewardsId { get; set; }
        public string MilestoneType { get; set; } = string.Empty;
        public string MilestoneDescription { get; set; } = string.Empty;
        public DateTime ReachedAt { get; set; }
        public bool RewardClaimed { get; set; } = false;

        public virtual VipRewards VipRewards { get; set; } = null!;
    }

    public class VipReward
    {
        public int Id { get; set; }
        public int VipRewardsId { get; set; }
        public string RewardType { get; set; } = string.Empty; // "Monthly", "Yearly", "Milestone"
        public SecretTierRewardLevel RewardLevel { get; set; }
        public string RewardContents { get; set; } = string.Empty;
        public DateTime EarnedAt { get; set; }
        public DateTime? ClaimedAt { get; set; }
        public bool IsClaimed { get; set; } = false;

        public virtual VipRewards VipRewards { get; set; } = null!;
    }

    public class VipRewardTier
    {
        public string Type { get; set; } = string.Empty;
        public int TierLevel { get; set; }
        public SecretTierRewardLevel RewardLevel { get; set; }
        public bool CanClaim { get; set; }
    }

    // Supporting Enums
    public enum VipTierStatus
    {
        None = 0,
        Bronze = 1,
        Standard = 2,
        Advanced = 3,
        Premium = 4,
        Elite = 5,
        Ambassador = 6,
        Legendary = 7
    }

    public enum SecretTierRewardLevel
    {
        None = 0,
        Basic = 1,      // $50+ yearly
        Common = 2,     // $300+ yearly
        Uncommon = 3,   // $750+ yearly
        Rare = 4,       // $1,500+ yearly
        Epic = 5,       // $2,500+ yearly
        Legendary = 6,  // $10,000+ yearly
        Mythical = 7    // $25,000+ yearly
    }
}