/**
 * Galaxy Strike Online - Server Idle System
 * Manages offline progression and idle mechanics
 */

class IdleSystem {
    constructor() {
        // Idle settings
        this.maxOfflineTime = 7 * 24 * 60 * 60 * 1000; // 7 days in milliseconds
        this.playerLastActive = new Map(); // userId -> last active timestamp
        this.playerProductionRates = new Map(); // userId -> production rates
        this.playerAchievements = new Map(); // userId -> achievements
        
        // Default production rates
        this.defaultProductionRates = {
            credits: 0.1, // 1 credit every 10 seconds (0.1 per second)
            experience: 0, // no auto experience - only from dungeons
            energy: 1/300 // 1 energy every 5 minutes (1/300 per second)
        };
        
        // Offline rates (different from online rates)
        this.offlineProductionRates = {
            credits: 1/60, // 1 credit every 1 minute (1/60 per second)
            experience: 0, // no experience offline - only from dungeons
            energy: 1/300 // 1 energy every 5 minutes (same as online)
        };
        
        // Idle rewards
        this.offlineRewards = {
            credits: 0,
            experience: 0,
            energy: 0,
            items: []
        };
        
        // Idle bonuses
        this.bonuses = {
            premium: 1.0,
            guild: 1.0,
            research: 1.0
        };
        
        // Idle achievements
        this.achievements = {
            totalOfflineTime: 0,
            maxOfflineSession: 0,
            totalIdleCredits: 0,
            totalIdleExperience: 0
        };
    }
    
    initializePlayerData(userId) {
        console.log('[IDLE SYSTEM] initializePlayerData called for userId:', userId);
        console.log('[IDLE SYSTEM] Current playerProductionRates size:', this.playerProductionRates.size);
        
        if (!this.playerLastActive.has(userId)) {
            console.log('[IDLE SYSTEM] Initializing new player data for:', userId);
            this.playerLastActive.set(userId, Date.now());
            this.playerProductionRates.set(userId, { ...this.defaultProductionRates });
            console.log('[IDLE SYSTEM] Set production rates for', userId, ':', this.defaultProductionRates);
            this.playerAchievements.set(userId, {
                totalOfflineTime: 0,
                maxOfflineSession: 0,
                totalIdleCredits: 0,
                totalIdleExperience: 0
            });
            console.log('[IDLE SYSTEM] Player data initialized successfully for:', userId);
        } else {
            console.log('[IDLE SYSTEM] Player data already exists for:', userId);
            const existingRates = this.playerProductionRates.get(userId);
            console.log('[IDLE SYSTEM] Existing production rates:', existingRates);
        }
    }
    
    updateLastActive(userId) {
        this.playerLastActive.set(userId, Date.now());
    }
    
    updateProductionRates(userId, rates) {
        this.playerProductionRates.set(userId, {
            ...this.defaultProductionRates,
            ...rates
        });
    }
    
    calculateOfflineProgress(userId) {
        this.initializePlayerData(userId);
        
        const lastActive = this.playerLastActive.get(userId);
        const currentTime = Date.now();
        const offlineTime = currentTime - lastActive;
        
        // Cap offline time to maximum
        const cappedOfflineTime = Math.min(offlineTime, this.maxOfflineTime);
        
        if (cappedOfflineTime <= 0) {
            return {
                offlineTime: 0,
                rewards: {
                    credits: 0,
                    experience: 0,
                    energy: 0,
                    items: []
                }
            };
        }
        
        const productionRates = this.playerProductionRates.get(userId);
        const achievements = this.playerAchievements.get(userId);
        
        // Calculate offline rewards using offline rates
        const offlineSeconds = Math.floor(cappedOfflineTime / 1000);
        const offlineRates = this.offlineProductionRates;
        const rewards = {
            credits: Math.floor(offlineRates.credits * offlineSeconds),
            experience: Math.floor(offlineRates.experience * offlineSeconds),
            energy: Math.floor(offlineRates.energy * offlineSeconds),
            items: []
        };
        
        // Update achievements
        achievements.totalOfflineTime += cappedOfflineTime;
        achievements.maxOfflineSession = Math.max(achievements.maxOfflineSession, cappedOfflineTime);
        achievements.totalIdleCredits += rewards.credits;
        achievements.totalIdleExperience += rewards.experience;
        
        // Update last active time
        this.playerLastActive.set(userId, currentTime);
        
        return {
            offlineTime: cappedOfflineTime,
            offlineSeconds,
            rewards,
            productionRates
        };
    }
    
    applyIdleRewards(userId, playerData) {
        const progress = this.calculateOfflineProgress(userId);
        
        if (progress.offlineTime > 0) {
            // Apply rewards to player data
            if (playerData.stats) {
                playerData.stats.credits = (playerData.stats.credits || 0) + progress.rewards.credits;
                playerData.stats.experience = (playerData.stats.experience || 0) + progress.rewards.experience;
            }
            
            if (playerData.resources) {
                playerData.resources.energy = (playerData.resources.energy || 0) + progress.rewards.energy;
            }
            
            // Add items if any
            if (progress.rewards.items && progress.rewards.items.length > 0) {
                if (!playerData.inventory) {
                    playerData.inventory = [];
                }
                playerData.inventory.push(...progress.rewards.items);
            }
        }
        
        return progress;
    }
    
    getProductionRates(userId) {
        this.initializePlayerData(userId);
        return this.playerProductionRates.get(userId);
    }
    
    updateBonuses(userId, bonuses) {
        this.initializePlayerData(userId);
        const currentRates = this.playerProductionRates.get(userId);
        
        // Apply bonuses to production rates
        const bonusMultiplier = 
            (bonuses.premium || this.defaultBonuses.premium) *
            (bonuses.guild || this.defaultBonuses.guild) *
            (bonuses.research || this.defaultBonuses.research);
        
        const updatedRates = {};
        for (const [resource, baseRate] of Object.entries(this.defaultProductionRates)) {
            updatedRates[resource] = Math.floor(baseRate * bonusMultiplier);
        }
        
        this.playerProductionRates.set(userId, updatedRates);
        return updatedRates;
    }
    
    getAchievements(userId) {
        this.initializePlayerData(userId);
        return this.playerAchievements.get(userId);
    }
    
    getIdleStats(userId) {
        this.initializePlayerData(userId);
        const achievements = this.playerAchievements.get(userId);
        const productionRates = this.playerProductionRates.get(userId);
        
        return {
            lastActive: this.playerLastActive.get(userId),
            productionRates,
            achievements,
            maxOfflineTime: this.maxOfflineTime,
            currentOfflineTime: Date.now() - this.playerLastActive.get(userId)
        };
    }
    
    // Calculate idle income for a specific time period
    calculateIncomeForTime(userId, timeInSeconds) {
        this.initializePlayerData(userId);
        const productionRates = this.playerProductionRates.get(userId);
        
        return {
            credits: Math.floor(productionRates.credits * timeInSeconds),
            experience: Math.floor(productionRates.experience * timeInSeconds),
            energy: Math.floor(productionRates.energy * timeInSeconds)
        };
    }
    
    // Get time until next milestone
    getTimeUntilMilestone(userId, targetCredits = 10000) {
        this.initializePlayerData(userId);
        const productionRates = this.playerProductionRates.get(userId);
        const currentOfflineTime = Date.now() - this.playerLastActive.get(userId);
        
        if (productionRates.credits <= 0) {
            return { seconds: Infinity, hours: Infinity };
        }
        
        const creditsPerSecond = productionRates.credits;
        const secondsNeeded = Math.ceil(targetCredits / creditsPerSecond);
        
        return {
            seconds: secondsNeeded,
            minutes: Math.ceil(secondsNeeded / 60),
            hours: Math.ceil(secondsNeeded / 3600)
        };
    }
    
    // Process idle rewards for multiple users (batch processing)
    processBatchIdleRewards(userIds) {
        const results = new Map();
        
        for (const userId of userIds) {
            try {
                const progress = this.calculateOfflineProgress(userId);
                results.set(userId, {
                    success: true,
                    progress
                });
            } catch (error) {
                results.set(userId, {
                    success: false,
                    error: error.message
                });
            }
        }
        
        return results;
    }
    
    // Generate online idle rewards (called periodically while player is online)
    generateOnlineIdleRewards(userId, deltaTimeMs) {
        console.log('[IDLE SYSTEM] generateOnlineIdleRewards called for userId:', userId, 'deltaTimeMs:', deltaTimeMs);
        
        const productionRates = this.playerProductionRates.get(userId);
        console.log('[IDLE SYSTEM] Production rates for', userId, ':', productionRates);
        
        if (!productionRates) {
            console.log('[IDLE SYSTEM] No production rates found for', userId, '- returning 0 rewards');
            return {
                credits: 0,
                experience: 0,
                energy: 0
            };
        }
        
        const deltaTimeSeconds = deltaTimeMs / 1000;
        console.log('[IDLE SYSTEM] Delta time seconds:', deltaTimeSeconds);
        console.log('[IDLE SYSTEM] Raw calculation:', productionRates.credits, '*', deltaTimeSeconds, '=', productionRates.credits * deltaTimeSeconds);
        
        const creditsBeforeFloor = productionRates.credits * deltaTimeSeconds;
        const rewards = {
            credits: Math.floor(creditsBeforeFloor),
            experience: Math.floor(productionRates.experience * deltaTimeSeconds),
            energy: Math.floor(productionRates.energy * deltaTimeSeconds)
        };
        
        console.log('[IDLE SYSTEM] Credits before floor:', creditsBeforeFloor, 'after floor:', rewards.credits);
        console.log('[IDLE SYSTEM] Calculated rewards for', userId, ':', rewards);
        return rewards;
    }
    
    // Reset idle data for a user
    resetPlayerData(userId) {
        this.playerLastActive.delete(userId);
        this.playerProductionRates.delete(userId);
        this.playerAchievements.delete(userId);
    }
    
    // Get global idle statistics
    getGlobalStats() {
        const totalPlayers = this.playerLastActive.size;
        let totalOfflineTime = 0;
        let totalIdleCredits = 0;
        let totalIdleExperience = 0;
        
        for (const achievements of this.playerAchievements.values()) {
            totalOfflineTime += achievements.totalOfflineTime;
            totalIdleCredits += achievements.totalIdleCredits;
            totalIdleExperience += achievements.totalIdleExperience;
        }
        
        return {
            totalPlayers,
            totalOfflineTime,
            totalIdleCredits,
            totalIdleExperience,
            averageOfflineTime: totalPlayers > 0 ? totalOfflineTime / totalPlayers : 0
        };
    }
}

module.exports = IdleSystem;
