/**
 * Galaxy Strike Online - Server Ship System
 * Manages ship data, upgrades, and combat mechanics
 */

class ShipSystem {
    constructor() {
        this.shipTemplates = new Map();
        this.playerShips = new Map(); // userId -> array of ships
        this.initializeShipTemplates();
    }
    
    initializeShipTemplates() {
        // Starter Ships
        this.addShipTemplate('starter_cruiser', {
            name: 'Starter Cruiser',
            class: 'Cruiser',
            description: 'A reliable cruiser for beginners',
            rarity: 'Common',
            baseStats: {
                health: 100,
                maxHealth: 100,
                attack: 10,
                defense: 5,
                speed: 10,
                energy: 50,
                maxEnergy: 50
            },
            slots: {
                weapon: 2,
                armor: 1,
                module: 1
            },
            requirements: {
                level: 1,
                credits: 0
            },
            experience: 0,
            requiredExp: 100,
            texture: 'assets/textures/ships/starter_cruiser.png'
        });
        
        this.addShipTemplate('light_fighter', {
            name: 'Light Fighter',
            class: 'Fighter',
            description: 'Fast and agile fighter ship',
            rarity: 'Common',
            baseStats: {
                health: 80,
                maxHealth: 80,
                attack: 15,
                defense: 3,
                speed: 15,
                energy: 40,
                maxEnergy: 40
            },
            slots: {
                weapon: 3,
                armor: 0,
                module: 2
            },
            requirements: {
                level: 3,
                credits: 1000
            },
            experience: 0,
            requiredExp: 150,
            texture: 'assets/textures/ships/light_fighter.png'
        });
        
        this.addShipTemplate('heavy_bomber', {
            name: 'Heavy Bomber',
            class: 'Bomber',
            description: 'Slow but powerful bomber',
            rarity: 'Uncommon',
            baseStats: {
                health: 150,
                maxHealth: 150,
                attack: 25,
                defense: 10,
                speed: 5,
                energy: 60,
                maxEnergy: 60
            },
            slots: {
                weapon: 4,
                armor: 2,
                module: 1
            },
            requirements: {
                level: 5,
                credits: 5000
            },
            experience: 0,
            requiredExp: 200,
            texture: 'assets/textures/ships/heavy_bomber.png'
        });
        
        this.addShipTemplate('exploration_vessel', {
            name: 'Exploration Vessel',
            class: 'Explorer',
            description: 'Versatile ship for exploration missions',
            rarity: 'Rare',
            baseStats: {
                health: 120,
                maxHealth: 120,
                attack: 12,
                defense: 8,
                speed: 12,
                energy: 80,
                maxEnergy: 80
            },
            slots: {
                weapon: 2,
                armor: 1,
                module: 3
            },
            requirements: {
                level: 8,
                credits: 15000
            },
            experience: 0,
            requiredExp: 300,
            texture: 'assets/textures/ships/exploration_vessel.png'
        });
        
        this.addShipTemplate('battle_cruiser', {
            name: 'Battle Cruiser',
            class: 'Cruiser',
            description: 'Heavy combat cruiser',
            rarity: 'Rare',
            baseStats: {
                health: 200,
                maxHealth: 200,
                attack: 30,
                defense: 15,
                speed: 8,
                energy: 70,
                maxEnergy: 70
            },
            slots: {
                weapon: 5,
                armor: 3,
                module: 2
            },
            requirements: {
                level: 12,
                credits: 50000
            },
            experience: 0,
            requiredExp: 500,
            texture: 'assets/textures/ships/battle_cruiser.png'
        });
        
        this.addShipTemplate('flagship', {
            name: 'Flagship',
            class: 'Capital',
            description: 'Ultimate command vessel',
            rarity: 'Legendary',
            baseStats: {
                health: 500,
                maxHealth: 500,
                attack: 50,
                defense: 30,
                speed: 6,
                energy: 150,
                maxEnergy: 150
            },
            slots: {
                weapon: 8,
                armor: 5,
                module: 4
            },
            requirements: {
                level: 20,
                credits: 500000
            },
            experience: 0,
            requiredExp: 1000,
            texture: 'assets/textures/ships/flagship.png'
        });
    }
    
    addShipTemplate(id, template) {
        this.shipTemplates.set(id, {
            id,
            ...template,
            createdAt: new Date().toISOString()
        });
    }
    
    getShipTemplate(id) {
        return this.shipTemplates.get(id);
    }
    
    getShipTemplatesByClass(shipClass) {
        return Array.from(this.shipTemplates.values()).filter(template => template.class === shipClass);
    }
    
    getShipTemplatesByRarity(rarity) {
        return Array.from(this.shipTemplates.values()).filter(template => template.rarity === rarity);
    }
    
    getAllShipTemplates() {
        return Array.from(this.shipTemplates.values());
    }
    
    initializePlayerShips(userId) {
        if (!this.playerShips.has(userId)) {
            this.playerShips.set(userId, []);
            
            // Give starter ship to new players
            const starterShip = this.createShip(userId, 'starter_cruiser');
            if (starterShip) {
                this.playerShips.get(userId).push(starterShip);
            }
        }
        return this.playerShips.get(userId);
    }
    
    createShip(userId, templateId, customizations = {}) {
        const template = this.shipTemplates.get(templateId);
        if (!template) {
            throw new Error(`Ship template not found: ${templateId}`);
        }
        
        const ship = {
            id: `ship_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
            userId,
            templateId,
            name: customizations.name || template.name,
            class: template.class,
            rarity: template.rarity,
            level: customizations.level || 1,
            experience: 0,
            requiredExp: template.requiredExp,
            stats: { ...template.baseStats },
            maxStats: { ...template.baseStats },
            slots: { ...template.slots },
            equippedItems: {},
            texture: template.texture,
            status: 'active',
            createdAt: new Date().toISOString(),
            lastUsed: new Date().toISOString()
        };
        
        return ship;
    }
    
    getPlayerShips(userId) {
        return this.playerShips.get(userId) || this.initializePlayerShips(userId);
    }
    
    getShip(userId, shipId) {
        const ships = this.getPlayerShips(userId);
        return ships.find(ship => ship.id === shipId);
    }
    
    getCurrentShip(userId) {
        const ships = this.getPlayerShips(userId);
        return ships.find(ship => ship.status === 'active' && ship.lastUsed === Math.max(...ships.map(s => new Date(s.lastUsed).getTime())));
    }
    
    setCurrentShip(userId, shipId) {
        const ships = this.getPlayerShips(userId);
        const ship = ships.find(s => s.id === shipId);
        
        if (!ship) {
            throw new Error('Ship not found');
        }
        
        // Update last used time for all ships
        ships.forEach(s => {
            if (s.id === shipId) {
                s.status = 'active';
                s.lastUsed = new Date().toISOString();
            } else {
                s.status = 'inactive';
            }
        });
        
        return ship;
    }
    
    addExperience(userId, shipId, amount) {
        const ship = this.getShip(userId, shipId);
        if (!ship) {
            throw new Error('Ship not found');
        }
        
        ship.experience += amount;
        
        // Check for level up
        let levelsGained = 0;
        while (ship.experience >= ship.requiredExp) {
            ship.experience -= ship.requiredExp;
            ship.level += 1;
            levelsGained++;
            
            // Increase stats on level up
            this.levelUpShip(ship);
            
            // Update required experience for next level
            ship.requiredExp = this.getExperienceNeeded(ship.level);
        }
        
        return {
            experienceGained: amount,
            levelsGained,
            newLevel: ship.level,
            newStats: ship.stats
        };
    }
    
    levelUpShip(ship) {
        const statIncrease = 1.1; // 10% increase per level
        
        for (const [stat, value] of Object.entries(ship.stats)) {
            if (typeof value === 'number') {
                ship.stats[stat] = Math.floor(value * statIncrease);
                ship.maxStats[stat] = Math.floor(ship.maxStats[stat] * statIncrease);
            }
        }
    }
    
    getExperienceNeeded(level) {
        // Exponential experience curve
        return Math.floor(100 * Math.pow(1.5, level - 1));
    }
    
    upgradeShip(userId, shipId, upgradeType) {
        const ship = this.getShip(userId, shipId);
        if (!ship) {
            throw new Error('Ship not found');
        }
        
        switch (upgradeType) {
            case 'health':
                ship.stats.health = Math.floor(ship.stats.health * 1.2);
                ship.stats.maxHealth = Math.floor(ship.stats.maxHealth * 1.2);
                break;
            case 'attack':
                ship.stats.attack = Math.floor(ship.stats.attack * 1.15);
                break;
            case 'defense':
                ship.stats.defense = Math.floor(ship.stats.defense * 1.15);
                break;
            case 'speed':
                ship.stats.speed = Math.floor(ship.stats.speed * 1.1);
                break;
            case 'energy':
                ship.stats.energy = Math.floor(ship.stats.energy * 1.2);
                ship.stats.maxEnergy = Math.floor(ship.stats.maxEnergy * 1.2);
                break;
            default:
                throw new Error('Invalid upgrade type');
        }
        
        return {
            upgradeType,
            newStats: ship.stats
        };
    }
    
    equipItem(userId, shipId, slot, itemId) {
        const ship = this.getShip(userId, shipId);
        if (!ship) {
            throw new Error('Ship not found');
        }
        
        if (!ship.slots[slot]) {
            throw new Error('Invalid slot type');
        }
        
        ship.equippedItems[slot] = itemId;
        
        return {
            slot,
            itemId,
            equippedItems: ship.equippedItems
        };
    }
    
    unequipItem(userId, shipId, slot) {
        const ship = this.getShip(userId, shipId);
        if (!ship) {
            throw new Error('Ship not found');
        }
        
        const itemId = ship.equippedItems[slot];
        delete ship.equippedItems[slot];
        
        return {
            slot,
            itemId,
            equippedItems: ship.equippedItems
        };
    }
    
    repairShip(userId, shipId, amount = null) {
        const ship = this.getShip(userId, shipId);
        if (!ship) {
            throw new Error('Ship not found');
        }
        
        if (amount === null) {
            // Full repair
            ship.stats.health = ship.stats.maxHealth;
        } else {
            // Partial repair
            ship.stats.health = Math.min(ship.stats.health + amount, ship.stats.maxHealth);
        }
        
        return {
            health: ship.stats.health,
            maxHealth: ship.stats.maxHealth,
            repaired: amount || (ship.stats.maxHealth - ship.stats.health)
        };
    }
    
    deleteShip(userId, shipId) {
        const ships = this.getPlayerShips(userId);
        const shipIndex = ships.findIndex(ship => ship.id === shipId);
        
        if (shipIndex === -1) {
            throw new Error('Ship not found');
        }
        
        const deletedShip = ships.splice(shipIndex, 1)[0];
        
        // If this was the current ship, set a new current ship
        if (deletedShip.status === 'active' && ships.length > 0) {
            ships[0].status = 'active';
            ships[0].lastUsed = new Date().toISOString();
        }
        
        return deletedShip;
    }
    
    getShipClasses() {
        const classes = new Set();
        for (const template of this.shipTemplates.values()) {
            classes.add(template.class);
        }
        return Array.from(classes).sort();
    }
    
    getShipRarities() {
        const rarities = new Set();
        for (const template of this.shipTemplates.values()) {
            rarities.add(template.rarity);
        }
        return Array.from(rarities).sort();
    }
    
    getAvailableShips(userId, playerLevel = 1) {
        return Array.from(this.shipTemplates.values())
            .filter(template => template.requirements.level <= playerLevel)
            .map(template => ({
                id: template.id,
                name: template.name,
                class: template.class,
                rarity: template.rarity,
                description: template.description,
                requirements: template.requirements,
                baseStats: template.baseStats,
                slots: template.slots,
                texture: template.texture
            }));
    }
    
    getPlayerShipStats(userId) {
        const ships = this.getPlayerShips(userId);
        
        return {
            totalShips: ships.length,
            activeShip: this.getCurrentShip(userId),
            shipClasses: ships.reduce((acc, ship) => {
                acc[ship.class] = (acc[ship.class] || 0) + 1;
                return acc;
            }, {}),
            averageLevel: ships.length > 0 ? Math.floor(ships.reduce((sum, ship) => sum + ship.level, 0) / ships.length) : 0,
            totalExperience: ships.reduce((sum, ship) => sum + ship.experience, 0)
        };
    }
}

module.exports = ShipSystem;
