/**
 * Local Server for Singleplayer Mode
 * A simplified server that runs within the Electron client for offline/singleplayer functionality
 * NOTE: This version requires express, socket.io, and cors dependencies to be installed
 */

class LocalServer {
    constructor() {
        this.app = null;
        this.server = null;
        this.io = null;
        this.port = null;
        this.isRunning = false;
        this.connectedClients = new Map();
        
        console.log('[LOCAL SERVER] LocalServer initialized');
    }
    
    async initialize() {
        try {
            // Try to require dependencies
            if (typeof require !== 'undefined') {
                const express = require('express');
                const { createServer } = require('http');
                const { Server } = require('socket.io');
                const cors = require('cors');
                
                this.setupExpress(express, cors);
                this.createServer = createServer;
                this.ServerClass = Server;
                
                console.log('[LOCAL SERVER] Dependencies loaded successfully');
                return true;
            } else {
                console.warn('[LOCAL SERVER] require() not available, running in browser context');
                return false;
            }
        } catch (error) {
            console.error('[LOCAL SERVER] Failed to load dependencies:', error.message);
            console.log('[LOCAL SERVER] Please install dependencies: npm install express socket.io cors');
            return false;
        }
    }
    
    setupExpress(express, cors) {
        // Initialize Express app
        this.app = express();
        
        // Middleware
        this.app.use(cors({
            origin: ["http://localhost:3000", "http://127.0.0.1:3000", "file://"],
            credentials: true
        }));
        this.app.use(express.json({ limit: '10mb' }));
        this.app.use(express.urlencoded({ extended: true }));
        
        // Health check endpoint
        this.app.get('/health', (req, res) => {
            res.status(200).json({ 
                status: 'OK', 
                timestamp: new Date().toISOString(),
                uptime: process.uptime(),
                mode: 'local'
            });
        });
        
        // API version endpoint
        this.app.get('/api/ssc/version', (req, res) => {
            res.status(200).json({ 
                version: '1.0.0',
                service: 'galaxystrikeonline-local-server',
                timestamp: new Date().toISOString(),
                mode: 'local'
            });
        });
        
        // Mock authentication endpoints for singleplayer
        this.app.post('/api/auth/login', (req, res) => {
            const { email, password } = req.body;
            
            // Auto-authenticate for singleplayer mode
            const mockUser = {
                id: 'local-user',
                email: email || 'local@player.com',
                username: 'Local Player',
                token: 'local-token-' + Date.now(),
                createdAt: new Date().toISOString()
            };
            
            res.status(200).json({
                success: true,
                user: mockUser,
                token: mockUser.token,
                message: 'Logged in to local mode'
            });
        });
        
        this.app.post('/api/auth/register', (req, res) => {
            const { email, password, username } = req.body;
            
            // Auto-register for singleplayer mode
            const mockUser = {
                id: 'local-user',
                email: email || 'local@player.com',
                username: username || 'Local Player',
                token: 'local-token-' + Date.now(),
                createdAt: new Date().toISOString()
            };
            
            res.status(201).json({
                success: true,
                user: mockUser,
                token: mockUser.token,
                message: 'Registered in local mode'
            });
        });
        
        // Mock server browser endpoints
        this.app.get('/api/servers', (req, res) => {
            // Return a single local server
            const localServer = {
                id: 'local-server',
                name: 'Local Singleplayer',
                description: 'Your personal local server for singleplayer gaming',
                type: 'private',
                region: 'local',
                maxPlayers: 1,
                currentPlayers: 0,
                owner: 'Local Player',
                address: 'localhost',
                port: this.port,
                status: 'online',
                createdAt: new Date().toISOString(),
                ping: 0
            };
            
            res.status(200).json({
                success: true,
                servers: [localServer]
            });
        });
        
        // Mock game data endpoints
        this.app.get('/api/game/player/:id', (req, res) => {
            // Return player data from local storage if available
            const playerId = req.params.id;
            let saveData;
            
            try {
                // In Electron context, access localStorage differently
                if (typeof localStorage !== 'undefined') {
                    saveData = localStorage.getItem(`gso_save_slot_1`);
                }
            } catch (error) {
                console.warn('[LOCAL SERVER] Could not access localStorage:', error);
            }
            
            if (saveData) {
                try {
                    const parsedData = JSON.parse(saveData);
                    res.status(200).json({
                        success: true,
                        player: parsedData.player
                    });
                } catch (error) {
                    res.status(500).json({
                        success: false,
                        error: 'Failed to parse save data'
                    });
                }
            } else {
                res.status(404).json({
                    success: false,
                    error: 'No save data found'
                });
            }
        });
        
        this.app.post('/api/game/player/:id/save', (req, res) => {
            // Save player data to local storage
            const playerId = req.params.id;
            const playerData = req.body;
            
            try {
                let existingSaveData = '{}';
                
                // In Electron context, access localStorage differently
                if (typeof localStorage !== 'undefined') {
                    existingSaveData = localStorage.getItem(`gso_save_slot_1`) || '{}';
                }
                
                const parsedExisting = JSON.parse(existingSaveData);
                
                // Merge player data
                parsedExisting.player = playerData;
                parsedExisting.lastSave = Date.now();
                
                if (typeof localStorage !== 'undefined') {
                    localStorage.setItem(`gso_save_slot_1`, JSON.stringify(parsedExisting));
                }
                
                res.status(200).json({
                    success: true,
                    message: 'Player data saved locally'
                });
            } catch (error) {
                res.status(500).json({
                    success: false,
                    error: 'Failed to save player data'
                });
            }
        });
    }
    
    async start(port = 3004) {
        if (this.isRunning) {
            console.log('[LOCAL SERVER] Server is already running on port', this.port);
            return { success: false, error: 'Server already running' };
        }
        
        try {
            // Initialize dependencies if not already done
            if (!this.app) {
                const initialized = await this.initialize();
                if (!initialized) {
                    return { success: false, error: 'Failed to initialize server dependencies' };
                }
            }
            
            this.port = port;
            this.server = this.createServer(this.app);
            this.io = new this.ServerClass(this.server, {
                cors: {
                    origin: ["http://localhost:3000", "http://127.0.0.1:3000", "file://"],
                    methods: ["GET", "POST"]
                }
            });
            
            // Setup Socket.IO handlers
            this.setupSocketHandlers();
            
            // Start the server
            await new Promise((resolve, reject) => {
                this.server.listen(port, (error) => {
                    if (error) {
                        reject(error);
                    } else {
                        resolve();
                    }
                });
            });
            
            this.isRunning = true;
            console.log(`[LOCAL SERVER] Local server started on port ${port}`);
            
            return { 
                success: true, 
                port: port,
                url: `http://localhost:${port}`
            };
            
        } catch (error) {
            console.error('[LOCAL SERVER] Failed to start server:', error);
            return { success: false, error: error.message };
        }
    }
    
    setupSocketHandlers() {
        this.io.on('connection', (socket) => {
            console.log('[LOCAL SERVER] Client connected:', socket.id);
            this.connectedClients.set(socket.id, {
                connectedAt: Date.now(),
                playerData: null
            });
            
            // Handle authentication
            socket.on('authenticate', (data) => {
                console.log('[LOCAL SERVER] Authenticating client:', socket.id, data);
                
                // Auto-authenticate for local mode
                socket.emit('authenticated', {
                    success: true,
                    user: {
                        id: 'local-user',
                        username: 'Local Player',
                        token: 'local-token-' + Date.now()
                    }
                });
                
                // Update client info
                const clientInfo = this.connectedClients.get(socket.id);
                if (clientInfo) {
                    clientInfo.playerData = {
                        id: 'local-user',
                        username: 'Local Player'
                    };
                }
            });
            
            // Handle game data sync
            socket.on('saveGameData', (data) => {
                console.log('[LOCAL SERVER] Saving game data for:', socket.id);
                
                // Save to localStorage (this will be handled by the client-side save system)
                socket.emit('gameDataSaved', {
                    success: true,
                    timestamp: Date.now()
                });
            });
            
            socket.on('loadGameData', (data) => {
                console.log('[LOCAL SERVER] Loading game data for:', socket.id);
                
                // Load from localStorage (this will be handled by the client-side load system)
                let saveData;
                
                try {
                    if (typeof localStorage !== 'undefined') {
                        saveData = localStorage.getItem(`gso_save_slot_1`);
                    }
                } catch (error) {
                    console.warn('[LOCAL SERVER] Could not access localStorage:', error);
                }
                
                if (saveData) {
                    try {
                        const parsedData = JSON.parse(saveData);
                        socket.emit('gameDataLoaded', {
                            success: true,
                            data: parsedData
                        });
                    } catch (error) {
                        socket.emit('gameDataLoaded', {
                            success: false,
                            error: 'Failed to parse save data'
                        });
                    }
                } else {
                    socket.emit('gameDataLoaded', {
                        success: false,
                        error: 'No save data found'
                    });
                }
            });
            
            // Handle disconnection
            socket.on('disconnect', () => {
                console.log('[LOCAL SERVER] Client disconnected:', socket.id);
                this.connectedClients.delete(socket.id);
            });
            
            // Send welcome message
            socket.emit('welcome', {
                message: 'Connected to local server',
                serverInfo: {
                    mode: 'local',
                    port: this.port,
                    timestamp: new Date().toISOString()
                }
            });
        });
    }
    
    async stop() {
        if (!this.isRunning) {
            console.log('[LOCAL SERVER] Server is not running');
            return { success: false, error: 'Server is not running' };
        }
        
        try {
            // Disconnect all clients
            if (this.io) {
                this.io.disconnectSockets();
            }
            
            // Close the server
            if (this.server) {
                await new Promise((resolve) => {
                    this.server.close(resolve);
                });
            }
            
            this.isRunning = false;
            this.port = null;
            this.connectedClients.clear();
            
            console.log('[LOCAL SERVER] Local server stopped');
            return { success: true };
            
        } catch (error) {
            console.error('[LOCAL SERVER] Failed to stop server:', error);
            return { success: false, error: error.message };
        }
    }
    
    getStatus() {
        return {
            isRunning: this.isRunning,
            port: this.port,
            connectedClients: this.connectedClients.size,
            uptime: this.isRunning ? process.uptime() : 0
        };
    }
    
    getUrl() {
        return this.isRunning ? `http://localhost:${this.port}` : null;
    }
}

// Export for use in Node.js environment
if (typeof module !== 'undefined' && module.exports) {
    module.exports = LocalServer;
}

// Export for use in browser environment
if (typeof window !== 'undefined') {
    window.LocalServer = LocalServer;
}
