/**
 * VNA System Web UI - Main Entry Point
 * Modern ES6+ JavaScript with modular architecture
 */

import { WebSocketManager } from './modules/websocket.js';
import { ChartManager } from './modules/charts.js';
import { UIManager } from './modules/ui.js';
import { NotificationManager } from './modules/notifications.js';
import { StorageManager } from './modules/storage.js';
import { SettingsManager } from './modules/settings.js';
import { AcquisitionManager } from './modules/acquisition.js';
import { renderIcons } from './modules/icons.js';

/**
 * Main Application Class
 * Coordinates all modules and manages application lifecycle
 */
class VNADashboard {
    constructor() {
        this.isInitialized = false;
        this.config = {
            websocket: {
                url: this.getWebSocketURL(),
                reconnectInterval: 3000,
                maxReconnectAttempts: 10
            },
            charts: {
                theme: 'dark',
                updateInterval: 100,
                maxDataPoints: 1000,
                animation: true
            },
            ui: {
                autoHideNotifications: true,
                notificationTimeout: 5000
            }
        };

        // Core managers (initialization order matters)
        this.storage = new StorageManager();
        this.notifications = new NotificationManager();

        // WebSocket first (needed by charts for bscan click handler)
        this.websocket = new WebSocketManager(this.config.websocket, this.notifications);

        // Charts after websocket (uses websocket for bscan click handler)
        this.charts = new ChartManager(this.config.charts, this.notifications, this.websocket);

        // UI receives dependencies from outside
        this.ui = new UIManager(this.notifications, this.websocket, this.charts);

        this.acquisition = new AcquisitionManager(this.notifications);
        this.settings = new SettingsManager(this.notifications, this.websocket, this.acquisition);

        // Bind methods
        this.handleWebSocketData = this.handleWebSocketData.bind(this);
        this.handleVisibilityChange = this.handleVisibilityChange.bind(this);
        this.handleBeforeUnload = this.handleBeforeUnload.bind(this);
    }

    /**
     * Initialize the application
     */
    async init() {
        try {
            console.log('Initializing VNA Dashboard...');

            // Render SVG icons
            renderIcons();

            // Initialize modules in correct order
            await this.initializeModules();

            // Set up event listeners
            this.setupEventListeners();

            // Connect WebSocket
            await this.websocket.connect();

            this.isInitialized = true;
            console.log('VNA Dashboard initialized successfully');

            // Show welcome notification
            this.notifications.show({
                type: 'info',
                title: 'Панель готова',
                message: 'Соединение с системой установлено. Ожидание данных свипа...'
            });

        } catch (error) {
            console.error('Failed to initialize VNA Dashboard:', error);
            this.notifications.show({
                type: 'error',
                title: 'Сбой инициализации',
                message: error.message || 'Не удалось инициализировать панель'
            });
        }
    }

    /**
     * Initialize all modules
     */
    async initializeModules() {
        // Initialize chart manager (DOM containers)
        await this.charts.init();

        // Initialize UI manager
        await this.ui.init();

        // Initialize acquisition manager first (required by settings)
        this.acquisition.initialize();

        // Initialize settings manager
        await this.settings.init();

        // Set up UI event handlers
        this.setupUIHandlers();

        // Load and apply user preferences after UI is initialized
        const preferences = await this.storage.getPreferences();
        if (preferences) {
            this.cleanupPreferences(preferences);
            this.applyPreferences(preferences);
            this.savePreferences();
        }
    }

    /**
     * Set up event listeners
     */
    setupEventListeners() {
        // WebSocket events - UIManager handles most of this
        this.websocket.on('data', this.handleWebSocketData);

        // Browser events
        document.addEventListener('visibilitychange', this.handleVisibilityChange);
        window.addEventListener('beforeunload', this.handleBeforeUnload);

        // Keyboard shortcuts
        document.addEventListener('keydown', this.handleKeyboardShortcuts.bind(this));
    }

    /**
     * Set up UI-specific event handlers
     */
    setupUIHandlers() {
        // Navigation
        this.ui.onViewChange((view) => {
            console.log(` Switched to view: ${view}`);
            if (view === 'settings') {
                this.settings.refresh();
            }
        });

        // Processor toggles (UI-only visibility)
        this.ui.onProcessorToggle((processor, enabled) => {
            console.log(` Processor ${processor}: ${enabled ? 'enabled' : 'disabled'}`);
            this.charts.toggleProcessor(processor, enabled);
            this.savePreferences();
        });

    }

    /**
     * Handle non-processor WebSocket data
     */
    handleWebSocketData(data) {
        // UIManager handles processor_result directly, we only handle other types
        if (data.type === 'system_status') {
            this.ui.updateSystemStatus(data.data);
        } else if (data.type === 'processor_history') {
            console.log('Received processor history:', data);
        }
        // Note: 'error' is handled by WebSocket manager directly
    }

    /**
     * Handle visibility changes (tab switch, minimize, etc.)
     */
    handleVisibilityChange() {
        if (document.hidden) {
            this.charts.pause();
        } else {
            this.charts.resume();
        }
    }

    /**
     * Handle before unload (page close/refresh)
     */
    handleBeforeUnload() {
        this.savePreferences();
        this.websocket.disconnect();
    }

    /**
     * Handle keyboard shortcuts
     */
    handleKeyboardShortcuts(event) {
        const activeElement = document.activeElement;
        const activeTag = activeElement?.tagName?.toLowerCase();
        const isEditable = activeElement?.isContentEditable ||
            activeTag === 'input' ||
            activeTag === 'textarea' ||
            activeTag === 'select';
        const key = event.key?.toLowerCase();

        if (!isEditable && !event.ctrlKey && !event.metaKey && !event.altKey && key === 's') {
            if (event.repeat) {
                return;
            }
            event.preventDefault();
            this.acquisition?.triggerSingleSweep?.();
            return;
        }

        // Ctrl/Cmd + Shift + R: Reconnect WebSocket
        if ((event.ctrlKey || event.metaKey) && key === 'r' && event.shiftKey) {
            event.preventDefault();
            this.websocket.reconnect();
        }
    }


    /**
     * Clean up old/invalid preferences
     */
    cleanupPreferences(preferences) {
        const invalidProcessors = ['sweep_counter'];
        if (preferences.disabledProcessors && Array.isArray(preferences.disabledProcessors)) {
            preferences.disabledProcessors = preferences.disabledProcessors.filter(
                processor => !invalidProcessors.includes(processor)
            );
            if (preferences.disabledProcessors.length === 0) {
                delete preferences.disabledProcessors;
            }
        }
    }

    /**
     * Apply user preferences
     */
    applyPreferences(preferences) {
        try {
            if (preferences.disabledProcessors && Array.isArray(preferences.disabledProcessors)) {
                preferences.disabledProcessors.forEach(proc => {
                    if (this.ui && typeof this.ui.setProcessorEnabled === 'function') {
                        this.ui.setProcessorEnabled(proc, false);
                    }
                });
            }

            if (preferences.theme) {
                if (this.ui && typeof this.ui.setTheme === 'function') {
                    this.ui.setTheme(preferences.theme);
                }
            }
        } catch (error) {
            console.warn('Error applying preferences:', error);
        }
    }

    /**
     * Save current preferences
     */
    async savePreferences() {
        try {
            const preferences = {
                disabledProcessors: this.charts.getDisabledProcessors(),
                theme: this.ui.getCurrentTheme(),
                timestamp: Date.now()
            };
            await this.storage.savePreferences(preferences);
        } catch (error) {
            console.warn('Failed to save preferences:', error);
        }
    }

    /**
     * Get WebSocket URL based on current location
     */
    getWebSocketURL() {
        const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
        const host = location.host;
        return `${protocol}//${host}/ws/processing`;
    }

    /**
     * Cleanup resources
     */
    destroy() {
        if (!this.isInitialized) return;

        console.log('Cleaning up VNA Dashboard...');

        document.removeEventListener('visibilitychange', this.handleVisibilityChange);
        window.removeEventListener('beforeunload', this.handleBeforeUnload);

        this.websocket.disconnect();

        this.charts.destroy();
        this.settings.destroy();
        this.ui.destroy();
        this.notifications.destroy();

        this.isInitialized = false;
        console.log('VNA Dashboard cleanup complete');
    }
}

// Initialize dashboard when DOM is ready
if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', () => {
        window.vnaDashboard = new VNADashboard();
        window.vnaDashboard.init();
    });
} else {
    window.vnaDashboard = new VNADashboard();
    window.vnaDashboard.init();
}

// Global error handling
window.addEventListener('error', (event) => {
    console.error('Global error:', event.error);
});

window.addEventListener('unhandledrejection', (event) => {
    console.error('Unhandled promise rejection:', event.reason);
});

// Development helpers
window.debug = {
    dashboard: () => window.vnaDashboard,
    websocket: () => window.vnaDashboard?.websocket,
    charts: () => window.vnaDashboard?.charts,
    ui: () => window.vnaDashboard?.ui,
    settings: () => window.vnaDashboard?.settings,
    acquisition: () => window.vnaDashboard?.acquisition
};
