/**
 * Galaxy Strike Online - Server Crafting System
 * Manages crafting recipes, materials, and item creation
 */

class CraftingSystem {
    constructor() {
        this.recipes = new Map();
        this.playerCrafting = new Map(); // userId -> crafting data
        this.initializeRecipes();
    }
    
    initializeRecipes() {
        // Basic weapon recipes
        this.addRecipe('basic_blaster', {
            name: 'Basic Blaster',
            type: 'weapon',
            rarity: 'common',
            description: 'A simple blaster for beginners',
            materials: {
                'iron_ore': 5,
                'copper_wire': 3,
                'energy_crystal': 1
            },
            results: {
                'basic_blaster': 1,
                'experience': 25
            },
            skillRequired: 1,
            craftingTime: 5000 // 5 seconds
        });
        
        // Advanced weapon recipes
        this.addRecipe('plasma_cannon', {
            name: 'Plasma Cannon',
            type: 'weapon',
            rarity: 'rare',
            description: 'A powerful plasma-based weapon',
            materials: {
                'iron_ore': 15,
                'copper_wire': 10,
                'energy_crystal': 5,
                'rare_metal': 3
            },
            results: {
                'plasma_cannon': 1,
                'experience': 100
            },
            skillRequired: 10,
            craftingTime: 15000 // 15 seconds
        });
        
        // Armor recipes
        this.addRecipe('basic_armor', {
            name: 'Basic Armor',
            type: 'armor',
            rarity: 'common',
            description: 'Light protection for beginners',
            materials: {
                'iron_ore': 8,
                'copper_wire': 2
            },
            results: {
                'basic_armor': 1,
                'experience': 30
            },
            skillRequired: 2,
            craftingTime: 8000 // 8 seconds
        });
        
        // Consumable recipes
        this.addRecipe('health_kit', {
            name: 'Health Kit',
            type: 'consumable',
            rarity: 'common',
            description: 'Restores health when used',
            materials: {
                'iron_ore': 2,
                'energy_crystal': 1
            },
            results: {
                'health_kit': 3,
                'experience': 10
            },
            skillRequired: 1,
            craftingTime: 2000 // 2 seconds
        });
    }
    
    addRecipe(id, recipe) {
        this.recipes.set(id, {
            id,
            ...recipe,
            createdAt: new Date().toISOString()
        });
    }
    
    getRecipe(id) {
        return this.recipes.get(id);
    }
    
    getAllRecipes() {
        return Array.from(this.recipes.values());
    }
    
    getRecipesByType(type) {
        return Array.from(this.recipes.values()).filter(recipe => recipe.type === type);
    }
    
    getRecipesByRarity(rarity) {
        return Array.from(this.recipes.values()).filter(recipe => recipe.rarity === rarity);
    }
    
    initializePlayerData(userId) {
        if (!this.playerCrafting.has(userId)) {
            this.playerCrafting.set(userId, {
                skill: 1,
                experience: 0,
                knownRecipes: new Set(['basic_blaster', 'health_kit']), // Start with basic recipes
                craftingHistory: [],
                totalCrafted: 0
            });
        }
        return this.playerCrafting.get(userId);
    }
    
    getPlayerData(userId) {
        return this.playerCrafting.get(userId) || this.initializePlayerData(userId);
    }
    
    canCraft(userId, recipeId, playerInventory) {
        const recipe = this.getRecipe(recipeId);
        if (!recipe) {
            return { canCraft: false, reason: 'Recipe not found' };
        }
        
        const playerData = this.getPlayerData(userId);
        
        // Check skill requirement
        if (playerData.skill < recipe.skillRequired) {
            return { canCraft: false, reason: 'Insufficient crafting skill' };
        }
        
        // Check materials
        for (const [material, amount] of Object.entries(recipe.materials)) {
            const playerAmount = playerInventory[material] || 0;
            if (playerAmount < amount) {
                return { canCraft: false, reason: `Insufficient ${material}` };
            }
        }
        
        return { canCraft: true };
    }
    
    async craftItem(userId, recipeId, playerInventory) {
        const canCraftResult = this.canCraft(userId, recipeId, playerInventory);
        if (!canCraftResult.canCraft) {
            throw new Error(canCraftResult.reason);
        }
        
        const recipe = this.getRecipe(recipeId);
        const playerData = this.getPlayerData(userId);
        
        // Remove materials from inventory
        for (const [material, amount] of Object.entries(recipe.materials)) {
            playerInventory[material] = (playerInventory[material] || 0) - amount;
        }
        
        // Add results to inventory
        for (const [item, amount] of Object.entries(recipe.results)) {
            if (item !== 'experience') {
                playerInventory[item] = (playerInventory[item] || 0) + amount;
            }
        }
        
        // Add experience and update stats
        const experienceGained = recipe.results.experience || 0;
        playerData.experience += experienceGained;
        playerData.totalCrafted += 1;
        
        // Check for skill up
        const oldSkill = playerData.skill;
        const newSkill = this.calculateSkillLevel(playerData.experience);
        playerData.skill = newSkill;
        
        // Record crafting history
        playerData.craftingHistory.push({
            recipeId,
            timestamp: new Date().toISOString(),
            experienceGained,
            skillUp: newSkill > oldSkill
        });
        
        // Keep only last 100 crafting records
        if (playerData.craftingHistory.length > 100) {
            playerData.craftingHistory = playerData.craftingHistory.slice(-100);
        }
        
        return {
            success: true,
            recipe,
            results: recipe.results,
            experienceGained,
            newSkill,
            skillUp: newSkill > oldSkill,
            playerInventory
        };
    }
    
    calculateSkillLevel(experience) {
        // Simple skill progression: 100 XP per level
        return Math.floor(experience / 100) + 1;
    }
    
    learnRecipe(userId, recipeId) {
        const recipe = this.getRecipe(recipeId);
        if (!recipe) {
            throw new Error('Recipe not found');
        }
        
        const playerData = this.getPlayerData(userId);
        playerData.knownRecipes.add(recipeId);
        
        return {
            success: true,
            recipeId,
            recipeName: recipe.name
        };
    }
    
    getPlayerKnownRecipes(userId) {
        const playerData = this.getPlayerData(userId);
        return Array.from(playerData.knownRecipes).map(recipeId => this.getRecipe(recipeId));
    }
    
    getCraftingStats(userId) {
        const playerData = this.getPlayerData(userId);
        return {
            skill: playerData.skill,
            experience: playerData.experience,
            totalCrafted: playerData.totalCrafted,
            knownRecipesCount: playerData.knownRecipes.size,
            recentCrafting: playerData.craftingHistory.slice(-10)
        };
    }
    
    discoverRecipe(userId, recipeId) {
        const recipe = this.getRecipe(recipeId);
        if (!recipe) {
            throw new Error('Recipe not found');
        }
        
        const playerData = this.getPlayerData(userId);
        
        if (playerData.knownRecipes.has(recipeId)) {
            return { success: false, reason: 'Recipe already known' };
        }
        
        // Chance to discover based on skill level
        const discoveryChance = Math.min(0.1 + (playerData.skill * 0.05), 0.5);
        const discovered = Math.random() < discoveryChance;
        
        if (discovered) {
            playerData.knownRecipes.add(recipeId);
            return {
                success: true,
                recipeId,
                recipeName: recipe.name,
                discovered: true
            };
        }
        
        return { success: false, discovered: false };
    }
}

module.exports = CraftingSystem;
