const { ipcMain, BrowserWindow } = require("electron");
const EcosystemLauncher = require("./EcosystemLauncher");

class EcosystemManager {
    constructor(windowManager, instanceId) {
        this.windowManager = windowManager;
        this.instanceId = instanceId;
        this.ecosystemApps = new Map(); // Catalog of apps that belong to this ecosystem
        this.openWindows = new Map(); // Track open windows by app_id -> [windows]
        this.setupIPC();
        
        EcosystemLauncher.setRequestHandler(
            (webappData) => this.handleNewAppRequest(webappData),
        );
    }

    setupIPC() {
        try {
            // Listen for requests to open new apps in this ecosystem
            ipcMain.on('open-ecosystem-app', (event, webappData) => {
                this.handleNewAppRequest(webappData);
            });
        } catch (error) {
            console.warn('Could not setup IPC:', error.message);
        }
    }

    async handleNewAppRequest(webappData, sourceWindow = null) {
        try {
            const WebApp = require("../utils/WebApp");
            const webapp = Object.assign(new WebApp(), webappData);

            if (sourceWindow
                && !sourceWindow.isDestroyed()
                && sourceWindow.swaiWebApp?.reuse_window_for_ecosystem_navigation) {
                const previousAppId = sourceWindow.swaiWebApp.app_id;
                console.log(
                    `Reusing ${previousAppId} window for ecosystem app ${webapp.app_name}`,
                );
                this.addApp(webapp);
                await this.windowManager.reuseWindowForApp(sourceWindow, webapp);
                this.untrackWindow(previousAppId, sourceWindow);
                this.trackWindow(webapp.app_id, sourceWindow);
                sourceWindow.show();
                sourceWindow.focus();
                return;
            }
            
            // Ensure SwaiRegistry is initialized if this is an ecosystem app
            if (webapp.ecosystem && this.windowManager.swaiRegistry) {
                if (!this.windowManager.swaiRegistry.initializationComplete) {
                    console.log(`Initializing SwaiRegistry for new ecosystem app: ${webapp.app_name}`);
                    await this.windowManager.swaiRegistry.initialize();
                }
            }
            
            // Check if this app is already running
            const existingWindows = this.openWindows.get(webapp.app_id) || [];
            
            if (existingWindows.length > 0) {
                // Same app is already running
                if (!webapp.allow_multi_window) {
                    // Bring existing window to front
                    console.log(`Bringing existing ${webapp.app_name} window to front`);
                    const firstWindow = existingWindows[0];
                    if (firstWindow && !firstWindow.isDestroyed()) {
                        firstWindow.show();
                        firstWindow.focus();
                        if (firstWindow.moveTop) {
                            firstWindow.moveTop();
                        }
                    }
                    return;
                } else {
                    // allow_multi_window is true, create another window
                    console.log(`Creating additional window for ${webapp.app_name}`);
                }
            } else {
                // Different app in same ecosystem, add it to our tracking
                console.log(`Opening new app in ecosystem: ${webapp.app_name}`);
                this.addApp(webapp);
            }
            
            // Create new window
            const newWindow = this.windowManager.createWindow(webapp);
            this.trackWindow(webapp.app_id, newWindow);
        } catch (error) {
            console.error('Error handling new app request:', error);
        }
    }

    addApp(webapp) {
        this.ecosystemApps.set(webapp.app_id, webapp);
        console.log(`Added ${webapp.app_name} to ecosystem instance`);
    }

    addApps(webapps) {
        for (const webapp of webapps) {
            this.addApp(webapp);
        }
    }

    removeApp(appId) {
        this.ecosystemApps.delete(appId);
        console.log(`Removed app ${appId} from ecosystem instance`);
    }

    trackWindow(appId, window) {
        try {
            if (!this.openWindows.has(appId)) {
                this.openWindows.set(appId, []);
            }
            
            this.openWindows.get(appId).push(window);
            
            // Clean up when window is closed
            window.on('closed', () => {
                this.untrackWindow(appId, window);
            });
            
            console.log(`Now tracking ${this.openWindows.get(appId).length} windows for ${appId}`);
        } catch (error) {
            console.error('Error tracking window:', error);
        }
    }

    untrackWindow(appId, window) {
        try {
            if (this.openWindows.has(appId)) {
                const windows = this.openWindows.get(appId);
                const index = windows.indexOf(window);
                if (index > -1) {
                    windows.splice(index, 1);
                    
                    // Keep the app in the ecosystem catalog so future handoffs can still find it.
                    if (windows.length === 0) {
                        this.openWindows.delete(appId);
                    }
                }
            }
        } catch (error) {
            console.error('Error untracking window:', error);
        }
    }

    cleanup() {
        EcosystemLauncher.setRequestHandler(null);
    }

    getApps() {
        return Array.from(this.ecosystemApps.values());
    }

    getOpenWindows(appId = null) {
        if (appId) {
            return this.openWindows.get(appId) || [];
        }
        return this.openWindows;
    }
}

module.exports = EcosystemManager;
