/**
 * UI Manager
 * Handles user interface interactions and state management
 */

import { formatProcessorName, debounce } from './utils.js';
import { renderIcons } from './icons.js';

export class UIManager {
    constructor(notifications, websocket, charts) {
        this.notifications = notifications;
        this.websocket = websocket;   // injected WebSocketManager
        this.charts = charts;         // injected ChartManager

        // UI Elements
        this.elements = {
            connectionStatus: null,
            processorToggles: null,
            sweepCount: null,
            dataRate: null,
            navButtons: null,
            views: null
        };

        // State
        this.currentView = 'dashboard';
        this.connectionStatus = 'disconnected';
        // processorId -> { enabled, uiParameters, config }
        this.processors = new Map();

        // Event handlers
        this.eventHandlers = {
            viewChange: [],
            processorToggle: [],
        };
    }

    /**
     * Initialize UI Manager
     */
    async init() {
        console.log('Initializing UI Manager...');

        // Get DOM elements
        this.findElements();

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

        // Initialize UI state
        this.initializeUIState();

        // Wire WebSocket events
        if (this.websocket) {
            this.websocket.on('connecting', () => this.setConnectionStatus('connecting'));
            this.websocket.on('connected', () => this.setConnectionStatus('connected'));
            this.websocket.on('disconnected', () => this.setConnectionStatus('disconnected'));

            // main data stream from backend
            this.websocket.on('processor_result', (payload) => this.onProcessorResult(payload));
        }

        console.log('UI Manager initialized');
    }

    /**
     * Find and cache DOM elements
     */
    findElements() {
        this.elements.connectionStatus = document.getElementById('connectionStatus');
        this.elements.processorToggles = document.getElementById('processorToggles');
        this.elements.navButtons = document.querySelectorAll('.nav-btn[data-view]');
        this.elements.views = document.querySelectorAll('.view');

        // Validate required elements
        const required = ['connectionStatus', 'processorToggles'];
        for (const key of required) {
            if (!this.elements[key]) {
                throw new Error(`Required UI element not found: ${key}`);
            }
        }
    }

    /**
     * Set up event listeners
     */
    setupEventListeners() {
        // Navigation
        this.elements.navButtons.forEach(button => {
            button.addEventListener('click', (e) => {
                const view = e.currentTarget.dataset.view;
                this.switchView(view);
            });
        });

        // Processor toggles container (event delegation)
        this.elements.processorToggles.addEventListener('click', (e) => {
            const toggle = e.target.closest('.processor-toggle');
            if (!toggle) return;
            const processor = toggle.dataset.processor;
            const isEnabled = toggle.classList.contains('processor-toggle--active');
            this.toggleProcessor(processor, !isEnabled);
        });


        // Window resize
        window.addEventListener('resize', debounce(() => this.handleResize(), 300));
    }

    /**
     * Initialize UI state
     */
    initializeUIState() {
        this.setConnectionStatus('disconnected');
        this.switchView(this.currentView);
    }


    /**
     * Switch between views
     */
    switchView(viewName) {
        if (this.currentView === viewName) return;

        this.elements.navButtons.forEach(button => {
            const isActive = button.dataset.view === viewName;
            button.classList.toggle('nav-btn--active', isActive);
        });

        this.elements.views.forEach(view => {
            const isActive = view.id === `${viewName}View`;
            view.classList.toggle('view--active', isActive);
        });

        this.currentView = viewName;
        this.emitEvent('viewChange', viewName);
    }

    /**
     * Update connection status
     */
    setConnectionStatus(status) {
        if (this.connectionStatus === status) return;

        this.connectionStatus = status;

        const statusElement = this.elements.connectionStatus;
        const textElement = statusElement.querySelector('.status-indicator__text');

        // Remove existing status classes
        statusElement.classList.remove(
            'status-indicator--connected',
            'status-indicator--connecting',
            'status-indicator--disconnected'
        );

        // Add new status class and update text
        switch (status) {
            case 'connected':
                statusElement.classList.add('status-indicator--connected');
                textElement.textContent = 'Подключено';
                break;
            case 'connecting':
                statusElement.classList.add('status-indicator--connecting');
                textElement.textContent = 'Подключение...';
                break;
            case 'disconnected':
            default:
                statusElement.classList.add('status-indicator--disconnected');
                textElement.textContent = 'Отключено';
                break;
        }
    }

    /**
     * Handle incoming processor result from backend
     */
    onProcessorResult(payload) {
        const { processor_id, timestamp, data, plotly_config, ui_parameters, metadata } = payload;
        if (!processor_id) return;

        // Register/update processor in UI map
        const proc = this.processors.get(processor_id) || { enabled: true };
        proc.uiParameters = ui_parameters || [];
        proc.config = metadata?.config || {};
        this.processors.set(processor_id, proc);

        // Refresh toggles
        this.refreshProcessorToggles();

        // Pass to charts
        if (this.charts) {
            this.charts.addResult({
                processor_id,
                timestamp,
                data,
                plotly_config,
                metadata
            });
        }
    }

    /**
     * Rebuild processor toggles
     */
    refreshProcessorToggles() {
        const container = this.elements.processorToggles;
        if (!container) return;

        container.innerHTML = '';
        for (const [name, data] of this.processors.entries()) {
            const toggle = document.createElement('div');
            toggle.className = `processor-toggle ${data.enabled ? 'processor-toggle--active' : ''}`;
            toggle.dataset.processor = name;
            toggle.innerHTML = `
                <div class="processor-toggle__checkbox"></div>
                <div class="processor-toggle__label">${formatProcessorName(name)}</div>
            `;
            container.appendChild(toggle);
        }

        renderIcons(container);
    }

    /**
     * Toggle processor visibility (UI-only)
     */
    toggleProcessor(processorId, enabled) {
        const proc = this.processors.get(processorId) || { enabled: true };
        proc.enabled = enabled;
        this.processors.set(processorId, proc);

        // Update toggle UI
        const toggle = this.elements.processorToggles.querySelector(`[data-processor="${processorId}"]`);
        if (toggle) {
            toggle.classList.toggle('processor-toggle--active', enabled);
        } else {
            this.refreshProcessorToggles();
        }

        // Update charts
        if (this.charts) {
            this.charts.toggleProcessor(processorId, enabled);
        }

        this.emitEvent('processorToggle', processorId, enabled);
    }

    /**
     * Public API
     */
    setProcessorEnabled(processorId, enabled) {
        if (!processorId) return;

        if (!this.processors.has(processorId)) {
            const processor = { enabled };
            this.processors.set(processorId, processor);
            return;
        }

        this.toggleProcessor(processorId, enabled);
    }

    handleResize() {
        console.log('Window resized');
        // Charts handle their own resize
    }

    // System status and theme methods simplified
    updateSystemStatus(statusData) { console.log('System status:', statusData); }
    setTheme(theme) { document.documentElement.setAttribute('data-theme', theme); }
    getCurrentTheme() { return document.documentElement.getAttribute('data-theme') || 'dark'; }

    // Events
    onViewChange(callback) { this.eventHandlers.viewChange.push(callback); }
    onProcessorToggle(callback) { this.eventHandlers.processorToggle.push(callback); }

    emitEvent(eventType, ...args) {
        if (this.eventHandlers[eventType]) {
            this.eventHandlers[eventType].forEach(handler => {
                try { handler(...args); }
                catch (error) { console.error(` Error in ${eventType} handler:`, error); }
            });
        }
    }

    getStats() {
        return {
            currentView: this.currentView,
            connectionStatus: this.connectionStatus,
            processorsCount: this.processors.size
        };
    }

    destroy() {
        console.log('Cleaning up UI Manager...');

        // Clear event handlers
        Object.keys(this.eventHandlers).forEach(key => {
            this.eventHandlers[key] = [];
        });

        // Clear processors
        this.processors.clear();

        console.log('UI Manager cleanup complete');
    }
}
