/**
 * Galaxy Strike Online - Server Quest System
 * Manages quests, progress tracking, and rewards
 */

class QuestSystem {
    constructor() {
        this.quests = new Map();
        this.playerQuests = new Map(); // userId -> quest data
        this.initializeQuests();
    }
    
    initializeQuests() {
        // Tutorial quests
        this.addQuest('tutorial_first_battle', {
            name: 'First Battle',
            description: 'Complete your first battle to learn the basics',
            type: 'tutorial',
            difficulty: 'easy',
            requirements: {
                battlesWon: 1
            },
            rewards: {
                experience: 100,
                credits: 500,
                items: ['health_kit', 'energy_pack']
            },
            prerequisites: [],
            repeatable: false,
            timeLimit: null
        });
        
        // Main Story quests
        this.addQuest('main_story_beginning', {
            name: 'The Beginning',
            description: 'Start your journey as a space pilot',
            type: 'main',
            difficulty: 'easy',
            requirements: {
                level: 1,
                battlesWon: 1
            },
            rewards: {
                experience: 200,
                credits: 1000,
                skillPoints: 2
            },
            prerequisites: [],
            repeatable: false,
            timeLimit: null
        });
        
        this.addQuest('main_story_first_dungeon', {
            name: 'First Dungeon',
            description: 'Complete your first dungeon run',
            type: 'main',
            difficulty: 'medium',
            requirements: {
                level: 5,
                dungeonsCleared: 1
            },
            rewards: {
                experience: 500,
                credits: 2000,
                items: ['rare_weapon']
            },
            prerequisites: ['main_story_beginning'],
            repeatable: false,
            timeLimit: null
        });
        
        this.addQuest('main_story_space_exploration', {
            name: 'Space Explorer',
            description: 'Explore 10 different sectors',
            type: 'main',
            difficulty: 'medium',
            requirements: {
                level: 10,
                sectorsExplored: 10
            },
            rewards: {
                experience: 1000,
                credits: 5000,
                items: ['explorer_badge']
            },
            prerequisites: ['main_story_first_dungeon'],
            repeatable: false,
            timeLimit: null
        });
        
        // Daily quests
        this.addQuest('daily_battles', {
            name: 'Daily Battles',
            description: 'Win 5 battles today',
            type: 'daily',
            difficulty: 'easy',
            requirements: {
                battlesWon: 5
            },
            rewards: {
                experience: 150,
                credits: 750,
                gems: 5
            },
            prerequisites: [],
            repeatable: true,
            timeLimit: 24 * 60 * 60 * 1000 // 24 hours
        });
        
        this.addQuest('daily_exploration', {
            name: 'Daily Exploration',
            description: 'Explore 3 new sectors today',
            type: 'daily',
            difficulty: 'easy',
            requirements: {
                sectorsExplored: 3
            },
            rewards: {
                experience: 100,
                credits: 500,
                gems: 3
            },
            prerequisites: [],
            repeatable: true,
            timeLimit: 24 * 60 * 60 * 1000 // 24 hours
        });
        
        this.addQuest('daily_resources', {
            name: 'Daily Resource Collection',
            description: 'Collect 1000 resources today',
            type: 'daily',
            difficulty: 'medium',
            requirements: {
                resourcesCollected: 1000
            },
            rewards: {
                experience: 200,
                credits: 1000,
                gems: 8
            },
            prerequisites: [],
            repeatable: true,
            timeLimit: 24 * 60 * 60 * 1000 // 24 hours
        });
        
        // Weekly quests
        this.addQuest('weekly_champion', {
            name: 'Weekly Champion',
            description: 'Win 50 battles this week',
            type: 'weekly',
            difficulty: 'hard',
            requirements: {
                battlesWon: 50
            },
            rewards: {
                experience: 2000,
                credits: 10000,
                gems: 50,
                items: ['champion_title']
            },
            prerequisites: [],
            repeatable: true,
            timeLimit: 7 * 24 * 60 * 60 * 1000 // 7 days
        });
        
        this.addQuest('weekly_dungeon_master', {
            name: 'Weekly Dungeon Master',
            description: 'Complete 10 dungeons this week',
            type: 'weekly',
            difficulty: 'hard',
            requirements: {
                dungeonsCleared: 10
            },
            rewards: {
                experience: 3000,
                credits: 15000,
                gems: 75,
                items: ['dungeon_master_cape']
            },
            prerequisites: [],
            repeatable: true,
            timeLimit: 7 * 24 * 60 * 60 * 1000 // 7 days
        });
        
        this.addQuest('weekly_wealth_collector', {
            name: 'Weekly Wealth Collector',
            description: 'Earn 10000 credits this week',
            type: 'weekly',
            difficulty: 'medium',
            requirements: {
                creditsEarned: 10000
            },
            rewards: {
                experience: 1500,
                credits: 5000,
                gems: 25
            },
            prerequisites: [],
            repeatable: true,
            timeLimit: 7 * 24 * 60 * 60 * 1000 // 7 days
        });
        
        // Combat quests
        this.addQuest('warrior_path', {
            name: 'Warrior Path',
            description: 'Win 10 battles to prove your combat skills',
            type: 'combat',
            difficulty: 'medium',
            requirements: {
                battlesWon: 10,
                enemiesDefeated: 50
            },
            rewards: {
                experience: 500,
                credits: 2000,
                items: ['basic_armor']
            },
            prerequisites: ['tutorial_first_battle'],
            repeatable: false,
            timeLimit: null
        });
        
        // Crafting quests
        this.addQuest('novice_crafter', {
            name: 'Novice Crafter',
            description: 'Craft 5 items to learn the basics of crafting',
            type: 'crafting',
            difficulty: 'easy',
            requirements: {
                itemsCrafted: 5
            },
            rewards: {
                experience: 200,
                credits: 1000,
                craftingExperience: 100
            },
            prerequisites: [],
            repeatable: false,
            timeLimit: null
        });
        
        // Exploration quests
        this.addQuest('explorer_spirit', {
            name: 'Explorer Spirit',
            description: 'Discover 5 different locations in the galaxy',
            type: 'exploration',
            difficulty: 'medium',
            requirements: {
                locationsDiscovered: 5
            },
            rewards: {
                experience: 300,
                credits: 1500,
                items: ['navigation_device']
            },
            prerequisites: ['tutorial_first_battle'],
            repeatable: false,
            timeLimit: null
        });
        
        // Daily quests
        this.addQuest('daily_bounty', {
            name: 'Daily Bounty',
            description: 'Complete 3 battles today',
            type: 'daily',
            difficulty: 'easy',
            requirements: {
                battlesWon: 3
            },
            rewards: {
                experience: 150,
                credits: 750
            },
            prerequisites: [],
            repeatable: true,
            timeLimit: 86400000 // 24 hours
        });
        
        // Weekly quests
        this.addQuest('weekly_champion', {
            name: 'Weekly Champion',
            description: 'Win 20 battles this week',
            type: 'weekly',
            difficulty: 'hard',
            requirements: {
                battlesWon: 20
            },
            rewards: {
                experience: 1000,
                credits: 5000,
                items: ['rare_weapon_part']
            },
            prerequisites: [],
            repeatable: true,
            timeLimit: 604800000 // 7 days
        });
    }
    
    addQuest(id, quest) {
        this.quests.set(id, {
            id,
            ...quest,
            createdAt: new Date().toISOString()
        });
    }
    
    getQuest(id) {
        return this.quests.get(id);
    }
    
    getAllQuests() {
        return Array.from(this.quests.values());
    }
    
    getQuestsByType(type) {
        return Array.from(this.quests.values()).filter(quest => quest.type === type);
    }
    
    getQuestsByDifficulty(difficulty) {
        return Array.from(this.quests.values()).filter(quest => quest.difficulty === difficulty);
    }
    
    initializePlayerData(userId) {
        if (!this.playerQuests.has(userId)) {
            const playerData = {
                activeQuests: new Map(),
                completedQuests: new Map(),
                questHistory: [],
                totalQuestsCompleted: 0,
                dailyQuestsCompleted: 0,
                weeklyQuestsCompleted: 0
            };
            
            // Assign starting quests to new players
            this.assignStartingQuests(userId, playerData);
            
            this.playerQuests.set(userId, playerData);
        }
        return this.playerQuests.get(userId);
    }
    
    assignStartingQuests(userId, playerData) {
        console.log(`[QUEST SYSTEM] Assigning starting quests to player ${userId}`);
        
        // Assign main story quests
        const mainStoryQuests = ['main_story_beginning', 'main_story_first_dungeon'];
        mainStoryQuests.forEach(questId => {
            const quest = this.quests.get(questId);
            if (quest && !playerData.activeQuests.has(questId) && !playerData.completedQuests.has(questId)) {
                playerData.activeQuests.set(questId, {
                    ...quest,
                    progress: 0,
                    startedAt: Date.now()
                });
                console.log(`[QUEST SYSTEM] Assigned main story quest: ${quest.name}`);
            }
        });
        
        // Assign daily quests
        this.generateDailyQuests(userId, playerData);
        
        // Assign weekly quests
        this.generateWeeklyQuests(userId, playerData);
        
        console.log(`[QUEST SYSTEM] Player now has ${playerData.activeQuests.size} active quests`);
    }
    
    generateDailyQuests(userId, playerData) {
        console.log(`[QUEST SYSTEM] Generating daily quests for player ${userId}`);
        
        const dailyQuestTemplates = ['daily_battles', 'daily_exploration', 'daily_resources'];
        
        dailyQuestTemplates.forEach(questId => {
            const quest = this.quests.get(questId);
            if (quest) {
                playerData.activeQuests.set(questId, {
                    ...quest,
                    progress: 0,
                    startedAt: Date.now(),
                    type: 'daily',
                    resetTime: Date.now() + (24 * 60 * 60 * 1000) // 24 hours from now
                });
                console.log(`[QUEST SYSTEM] Assigned daily quest: ${quest.name}`);
            }
        });
    }
    
    generateWeeklyQuests(userId, playerData) {
        console.log(`[QUEST SYSTEM] Generating weekly quests for player ${userId}`);
        
        const weeklyQuestTemplates = ['weekly_champion', 'weekly_dungeon_master', 'weekly_wealth_collector'];
        
        weeklyQuestTemplates.forEach(questId => {
            const quest = this.quests.get(questId);
            if (quest) {
                playerData.activeQuests.set(questId, {
                    ...quest,
                    progress: 0,
                    startedAt: Date.now(),
                    type: 'weekly',
                    resetTime: Date.now() + (7 * 24 * 60 * 60 * 1000) // 7 days from now
                });
                console.log(`[QUEST SYSTEM] Assigned weekly quest: ${quest.name}`);
            }
        });
    }
    
    getPlayerData(userId) {
        return this.playerQuests.get(userId) || this.initializePlayerData(userId);
    }
    
    getAvailableQuests(userId) {
        const playerData = this.getPlayerData(userId);
        const availableQuests = [];
        
        for (const [questId, quest] of this.quests) {
            // Skip if already active or completed (for non-repeatable quests)
            if (playerData.activeQuests.has(questId)) continue;
            if (playerData.completedQuests.has(questId) && !quest.repeatable) continue;
            
            // Check prerequisites
            const prerequisitesMet = quest.prerequisites.every(prereqId => 
                playerData.completedQuests.has(prereqId)
            );
            
            if (prerequisitesMet) {
                availableQuests.push({
                    ...quest,
                    status: playerData.activeQuests.has(questId) ? 'active' : 'available'
                });
            }
        }
        
        return availableQuests;
    }
    
    startQuest(userId, questId) {
        const quest = this.getQuest(questId);
        if (!quest) {
            throw new Error('Quest not found');
        }
        
        const playerData = this.getPlayerData(userId);
        
        // Check if quest is already active
        if (playerData.activeQuests.has(questId)) {
            throw new Error('Quest already active');
        }
        
        // Check if quest is completed and not repeatable
        if (playerData.completedQuests.has(questId) && !quest.repeatable) {
            throw new Error('Quest already completed');
        }
        
        // Check prerequisites
        const prerequisitesMet = quest.prerequisites.every(prereqId => 
            playerData.completedQuests.has(prereqId)
        );
        
        if (!prerequisitesMet) {
            throw new Error('Prerequisites not met');
        }
        
        // Start the quest
        const questProgress = {
            questId,
            startedAt: new Date().toISOString(),
            progress: {},
            completed: false,
            expiredAt: quest.timeLimit ? new Date(Date.now() + quest.timeLimit).toISOString() : null
        };
        
        // Initialize progress tracking
        for (const requirement of Object.keys(quest.requirements)) {
            questProgress.progress[requirement] = 0;
        }
        
        playerData.activeQuests.set(questId, questProgress);
        
        return {
            success: true,
            quest,
            progress: questProgress
        };
    }
    
    updateQuestProgress(userId, questId, progressUpdates) {
        const playerData = this.getPlayerData(userId);
        const activeQuest = playerData.activeQuests.get(questId);
        
        if (!activeQuest) {
            throw new Error('Quest not active');
        }
        
        // Check if quest is expired
        if (activeQuest.expiredAt && new Date() > new Date(activeQuest.expiredAt)) {
            playerData.activeQuests.delete(questId);
            throw new Error('Quest expired');
        }
        
        const quest = this.getQuest(questId);
        let updated = false;
        
        // Update progress
        for (const [requirement, amount] of Object.entries(progressUpdates)) {
            if (quest.requirements[requirement] !== undefined) {
                activeQuest.progress[requirement] = Math.min(
                    activeQuest.progress[requirement] + amount,
                    quest.requirements[requirement]
                );
                updated = true;
            }
        }
        
        // Check if quest is completed
        const isCompleted = Object.entries(quest.requirements).every(
            ([requirement, requiredAmount]) => 
                activeQuest.progress[requirement] >= requiredAmount
        );
        
        if (isCompleted && !activeQuest.completed) {
            activeQuest.completed = true;
            activeQuest.completedAt = new Date().toISOString();
            
            return {
                success: true,
                questCompleted: true,
                quest,
                progress: activeQuest.progress
            };
        }
        
        return {
            success: true,
            questCompleted: false,
            quest,
            progress: activeQuest.progress,
            updated
        };
    }
    
    completeQuest(userId, questId) {
        const playerData = this.getPlayerData(userId);
        const activeQuest = playerData.activeQuests.get(questId);
        
        if (!activeQuest) {
            throw new Error('Quest not active');
        }
        
        if (!activeQuest.completed) {
            throw new Error('Quest requirements not met');
        }
        
        const quest = this.getQuest(questId);
        
        // Move to completed quests
        playerData.completedQuests.set(questId, {
            ...activeQuest,
            quest,
            completedAt: new Date().toISOString()
        });
        
        // Remove from active quests
        playerData.activeQuests.delete(questId);
        
        // Update statistics
        playerData.totalQuestsCompleted += 1;
        
        if (quest.type === 'daily') {
            playerData.dailyQuestsCompleted += 1;
        } else if (quest.type === 'weekly') {
            playerData.weeklyQuestsCompleted += 1;
        }
        
        // Add to history
        playerData.questHistory.push({
            questId,
            questName: quest.name,
            completedAt: new Date().toISOString(),
            rewards: quest.rewards
        });
        
        // Keep only last 100 quest records
        if (playerData.questHistory.length > 100) {
            playerData.questHistory = playerData.questHistory.slice(-100);
        }
        
        return {
            success: true,
            quest,
            rewards: quest.rewards,
            statistics: {
                totalCompleted: playerData.totalQuestsCompleted,
                dailyCompleted: playerData.dailyQuestsCompleted,
                weeklyCompleted: playerData.weeklyQuestsCompleted
            }
        };
    }
    
    getPlayerActiveQuests(userId) {
        const playerData = this.getPlayerData(userId);
        const activeQuests = [];
        
        for (const [questId, progress] of playerData.activeQuests) {
            const quest = this.getQuest(questId);
            activeQuests.push({
                ...quest,
                progress: progress.progress,
                startedAt: progress.startedAt,
                expiredAt: progress.expiredAt
            });
        }
        
        return activeQuests;
    }
    
    getPlayerCompletedQuests(userId) {
        const playerData = this.getPlayerData(userId);
        const completedQuests = [];
        
        for (const [questId, completion] of playerData.completedQuests) {
            completedQuests.push({
                ...completion.quest,
                completedAt: completion.completedAt,
                progress: completion.progress
            });
        }
        
        return completedQuests;
    }
    
    getQuestStatistics(userId) {
        const playerData = this.getPlayerData(userId);
        const availableQuests = this.getAvailableQuests(userId);
        
        return {
            activeQuests: playerData.activeQuests.size,
            completedQuests: playerData.completedQuests.size,
            availableQuests: availableQuests.length,
            totalCompleted: playerData.totalQuestsCompleted,
            dailyCompleted: playerData.dailyQuestsCompleted,
            weeklyCompleted: playerData.weeklyQuestsCompleted,
            recentHistory: playerData.questHistory.slice(-10)
        };
    }
    
    resetDailyQuests(userId) {
        const playerData = this.getPlayerData(userId);
        
        // Remove completed daily quests
        for (const [questId, quest] of this.quests) {
            if (quest.type === 'daily') {
                playerData.completedQuests.delete(questId);
                playerData.activeQuests.delete(questId);
            }
        }
        
        playerData.dailyQuestsCompleted = 0;
        
        return { success: true, message: 'Daily quests reset' };
    }
    
    resetWeeklyQuests(userId) {
        const playerData = this.getPlayerData(userId);
        
        // Remove completed weekly quests
        for (const [questId, quest] of this.quests) {
            if (quest.type === 'weekly') {
                playerData.completedQuests.delete(questId);
                playerData.activeQuests.delete(questId);
            }
        }
        
        playerData.weeklyQuestsCompleted = 0;
        
        return { success: true, message: 'Weekly quests reset' };
    }
}

module.exports = QuestSystem;
