// WiFi DensePose Application - Main Entry Point

import { TabManager } from './components/TabManager.js';
import { DashboardTab } from './components/DashboardTab.js';
import { HardwareTab } from './components/HardwareTab.js';
import { LiveDemoTab } from './components/LiveDemoTab.js';
import { SensingTab } from './components/SensingTab.js';
import { apiService } from './services/api.service.js';
import { wsService } from './services/websocket.service.js';
import { healthService } from './services/health.service.js';
import { sensingService } from './services/sensing.service.js';
import { backendDetector } from './utils/backend-detector.js';
import { KeyboardShortcuts } from './utils/keyboard-shortcuts.js';
import { PerfMonitor } from './utils/perf-monitor.js';
import { toastManager } from './utils/toast.js';
import { ThemeToggle } from './utils/theme-toggle.js';
import { CommandPalette } from './utils/command-palette.js';
import { ActivityLog } from './utils/activity-log.js';
import { DataExport } from './utils/data-export.js';
import { FullscreenManager } from './utils/fullscreen.js';
import { ConnectionStatus } from './utils/connection-status.js';
import { MobileNav } from './utils/mobile-nav.js';
import { Router } from './utils/router.js';
import { Onboarding } from './utils/onboarding.js';
import { IdleManager } from './utils/idle-manager.js';
import { NotificationCenter } from './utils/notification-center.js';
import { i18n } from './utils/i18n.js';
import { ScreenshotTool } from './utils/screenshot.js';
import { UptimeClock } from './utils/uptime-clock.js';
import { QuickSettings } from './utils/quick-settings.js';

class WiFiDensePoseApp {
  constructor() {
    this.components = {};
    this.isInitialized = false;
  }

  // Initialize application
  async init() {
    try {
      console.log('Initializing WiFi DensePose UI...');
      
      // Set up error handling
      this.setupErrorHandling();
      
      // Initialize services
      await this.initializeServices();
      
      // Initialize UI components
      this.initializeComponents();

      // Initialize enhancements
      this.initializeEnhancements();

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

      this.isInitialized = true;
      console.log('WiFi DensePose UI initialized successfully');
      
    } catch (error) {
      console.error('Failed to initialize application:', error);
      this.showGlobalError('Failed to initialize application. Please refresh the page.');
    }
  }

  // Initialize services
  async initializeServices() {
    // Add request interceptor for error handling
    apiService.addResponseInterceptor(async (response, url) => {
      if (!response.ok && response.status === 401) {
        console.warn('Authentication required for:', url);
        // Handle authentication if needed
      }
      return response;
    });

    // Detect backend availability and initialize accordingly
    const useMock = await backendDetector.shouldUseMockServer();
    
    if (useMock) {
      console.log('🧪 Initializing with mock server for testing');
      // Import and start mock server only when needed
      const { mockServer } = await import('./utils/mock-server.js');
      mockServer.start();
      
      // Show notification to user
      this.showBackendStatus('Mock server active - testing mode', 'warning');
    } else {
      console.log('🔌 Connecting to backend...');

      try {
        const health = await healthService.checkLiveness();
        console.log('✅ Backend responding:', health);
        this.showBackendStatus('Connected to Rust sensing server', 'success');
      } catch (error) {
        console.warn('⚠️ Backend not available:', error.message);
        this.showBackendStatus('Backend unavailable — start sensing-server', 'warning');
      }

      // Start the sensing WebSocket service early so the dashboard and
      // live-demo tabs can show the correct data-source status immediately.
      sensingService.start();
    }
  }

  // Initialize UI components
  initializeComponents() {
    const container = document.querySelector('.container');
    if (!container) {
      throw new Error('Main container not found');
    }

    // Initialize tab manager
    this.components.tabManager = new TabManager(container);
    this.components.tabManager.init();

    // Initialize tab components
    this.initializeTabComponents();

    // Set up tab change handling
    this.components.tabManager.onTabChange((newTab, oldTab) => {
      this.handleTabChange(newTab, oldTab);
    });

  }

  // Initialize individual tab components
  initializeTabComponents() {
    // Dashboard tab
    const dashboardContainer = document.getElementById('dashboard');
    if (dashboardContainer) {
      this.components.dashboard = new DashboardTab(dashboardContainer);
      this.components.dashboard.init().catch(error => {
        console.error('Failed to initialize dashboard:', error);
      });
    }

    // Hardware tab
    const hardwareContainer = document.getElementById('hardware');
    if (hardwareContainer) {
      this.components.hardware = new HardwareTab(hardwareContainer);
      this.components.hardware.init();
    }

    // Live demo tab
    const demoContainer = document.getElementById('demo');
    if (demoContainer) {
      this.components.demo = new LiveDemoTab(demoContainer);
      this.components.demo.init();
    }

    // Sensing tab
    const sensingContainer = document.getElementById('sensing');
    if (sensingContainer) {
      this.components.sensing = new SensingTab(sensingContainer);
    }

    // Training tab - lazy load to avoid breaking other tabs if import fails
    this.initTrainingTab();

    // Architecture tab - static content, no component needed

    // Performance tab - static content, no component needed

    // Applications tab - static content, no component needed
  }

  // Lazy-load Training tab panels (dynamic import so failures don't break other tabs)
  async initTrainingTab() {
    try {
      const [{ default: TrainingPanel }, { default: ModelPanel }] = await Promise.all([
        import('./components/TrainingPanel.js'),
        import('./components/ModelPanel.js')
      ]);

      const trainingContainer = document.getElementById('training-panel-container');
      if (trainingContainer) {
        this.components.trainingPanel = new TrainingPanel(trainingContainer);
      }

      const modelContainer = document.getElementById('model-panel-container');
      if (modelContainer) {
        this.components.modelPanel = new ModelPanel(modelContainer);
      }
    } catch (error) {
      console.error('Failed to load Training tab components:', error);
    }
  }

  // Initialize enhancement modules
  initializeEnhancements() {
    // Toast notifications
    toastManager.init();

    // Connection status widget in header
    this.connectionStatus = new ConnectionStatus();
    this.connectionStatus.init();

    // Theme toggle
    this.themeToggle = new ThemeToggle();
    this.themeToggle.init();

    // Performance monitor
    this.perfMonitor = new PerfMonitor();
    this.perfMonitor.init();

    // Activity log
    this.activityLog = new ActivityLog();
    this.activityLog.init();

    // Data export
    this.dataExport = new DataExport();
    this.dataExport.init();

    // Fullscreen manager
    this.fullscreenManager = new FullscreenManager();
    this.fullscreenManager.init();

    // Command palette (Ctrl+K)
    this.commandPalette = new CommandPalette(this);
    this.commandPalette.init();

    // Mobile navigation (hamburger menu for small screens)
    this.mobileNav = new MobileNav();
    this.mobileNav.init();

    // Notification center (bell icon in header)
    this.notificationCenter = new NotificationCenter();
    this.notificationCenter.init();

    // Screenshot tool
    this.screenshotTool = new ScreenshotTool();
    this.screenshotTool.init();

    // Uptime clock
    this.uptimeClock = new UptimeClock();
    this.uptimeClock.init();

    // Quick settings panel
    this.quickSettings = new QuickSettings(this);
    this.quickSettings.init();

    // Internationalization (EN/PL)
    i18n.init();

    // Keyboard shortcuts (pass app reference for tab switching)
    this.keyboardShortcuts = new KeyboardShortcuts(this);
    this.keyboardShortcuts.register('l', 'Toggle activity log', () => {
      document.dispatchEvent(new CustomEvent('toggle-activity-log'));
    });
    this.keyboardShortcuts.register('e', 'Export sensor data', () => {
      document.dispatchEvent(new CustomEvent('export-data'));
    });
    this.keyboardShortcuts.register('f', 'Toggle fullscreen', () => {
      document.dispatchEvent(new CustomEvent('toggle-fullscreen'));
    });
    this.keyboardShortcuts.register('s', 'Take screenshot', () => {
      document.dispatchEvent(new CustomEvent('take-screenshot'));
    });
    this.keyboardShortcuts.init();

    // Listen for show-shortcuts from command palette
    document.addEventListener('show-shortcuts', () => {
      this.keyboardShortcuts.showHelp();
    });

    // Register PWA service worker
    this.registerServiceWorker();

    // URL hash router (bookmarkable tabs)
    this.router = new Router(this);
    this.router.init();

    // Idle detection (pause updates when inactive)
    this.idleManager = new IdleManager();
    this.idleManager.onIdle(() => {
      healthService.stopHealthMonitoring();
      console.info('[App] Paused health monitoring (idle)');
    });
    this.idleManager.onActive(() => {
      healthService.startHealthMonitoring();
      console.info('[App] Resumed health monitoring (active)');
    });
    this.idleManager.init();

    // Onboarding tour (first-run walkthrough)
    this.onboarding = new Onboarding(this);
    this.onboarding.init();
  }

  // Register service worker for offline capability
  registerServiceWorker() {
    if ('serviceWorker' in navigator) {
      navigator.serviceWorker.register('./sw.js').then(reg => {
        console.info('Service worker registered:', reg.scope);
      }).catch(err => {
        console.warn('Service worker registration failed:', err);
      });
    }
  }

  // Handle tab changes
  handleTabChange(newTab, oldTab) {
    console.log(`Tab changed from ${oldTab} to ${newTab}`);
    
    // Stop demo if leaving demo tab
    if (oldTab === 'demo' && this.components.demo) {
      this.components.demo.stopDemo();
    }
    
    // Update components based on active tab
    switch (newTab) {
      case 'dashboard':
        // Dashboard auto-updates when visible
        break;
        
      case 'hardware':
        // Hardware visualization is always active
        break;
        
      case 'demo':
        // Demo starts manually
        break;

      case 'sensing':
        // Lazy-init sensing tab on first visit
        if (this.components.sensing && !this.components.sensing.splatRenderer) {
          this.components.sensing.init().catch(error => {
            console.error('Failed to initialize sensing tab:', error);
          });
        }
        break;

      case 'training':
        // Refresh panels when training tab becomes visible
        if (this.components.trainingPanel && typeof this.components.trainingPanel.refresh === 'function') {
          this.components.trainingPanel.refresh();
        }
        if (this.components.modelPanel && typeof this.components.modelPanel.refresh === 'function') {
          this.components.modelPanel.refresh();
        }
        break;
    }
  }

  // Set up global event listeners
  setupEventListeners() {
    // Handle window resize
    window.addEventListener('resize', () => {
      this.handleResize();
    });

    // Handle visibility change
    document.addEventListener('visibilitychange', () => {
      this.handleVisibilityChange();
    });

    // Handle before unload
    window.addEventListener('beforeunload', () => {
      this.cleanup();
    });
  }

  // Handle window resize
  handleResize() {
    // Update canvas sizes if needed
    const canvases = document.querySelectorAll('canvas');
    canvases.forEach(canvas => {
      const rect = canvas.parentElement.getBoundingClientRect();
      if (canvas.width !== rect.width || canvas.height !== rect.height) {
        canvas.width = rect.width;
        canvas.height = rect.height;
      }
    });
  }

  // Handle visibility change
  handleVisibilityChange() {
    if (document.hidden) {
      // Pause updates when page is hidden
      console.log('Page hidden, pausing updates');
      healthService.stopHealthMonitoring();
    } else {
      // Resume updates when page is visible
      console.log('Page visible, resuming updates');
      healthService.startHealthMonitoring();
    }
  }

  // Set up error handling
  setupErrorHandling() {
    window.addEventListener('error', (event) => {
      if (event.error) {
        console.error('Global error:', event.error);
        this.showGlobalError('An unexpected error occurred');
      }
    });

    window.addEventListener('unhandledrejection', (event) => {
      if (event.reason) {
        console.error('Unhandled promise rejection:', event.reason);
        this.showGlobalError('An unexpected error occurred');
      }
    });
  }

  // Show backend status notification (uses enhanced toast system)
  showBackendStatus(message, type) {
    const toastType = type === 'success' ? 'success' : 'warning';
    toastManager[toastType](message, {
      duration: type === 'success' ? 3000 : 8000
    });
  }

  // Show global error message (uses enhanced toast system)
  showGlobalError(message) {
    toastManager.error(message, { duration: 6000 });
  }

  // Clean up resources
  cleanup() {
    console.log('Cleaning up application resources...');
    
    // Dispose all components
    Object.values(this.components).forEach(component => {
      if (component && typeof component.dispose === 'function') {
        component.dispose();
      }
    });

    // Disconnect all WebSocket connections
    wsService.disconnectAll();

    // Stop health monitoring
    healthService.dispose();

    // Dispose enhancements
    if (this.keyboardShortcuts) this.keyboardShortcuts.dispose();
    if (this.perfMonitor) this.perfMonitor.dispose();
    if (this.themeToggle) this.themeToggle.dispose();
    if (this.commandPalette) this.commandPalette.dispose();
    if (this.activityLog) this.activityLog.dispose();
    if (this.dataExport) this.dataExport.dispose();
    if (this.fullscreenManager) this.fullscreenManager.dispose();
    if (this.connectionStatus) this.connectionStatus.dispose();
    if (this.mobileNav) this.mobileNav.dispose();
    if (this.router) this.router.dispose();
    if (this.onboarding) this.onboarding.dispose();
    if (this.idleManager) this.idleManager.dispose();
    if (this.notificationCenter) this.notificationCenter.dispose();
    if (this.screenshotTool) this.screenshotTool.dispose();
    if (this.uptimeClock) this.uptimeClock.dispose();
    if (this.quickSettings) this.quickSettings.dispose();
    i18n.dispose();
    toastManager.dispose();
  }

  // Public API
  getComponent(name) {
    return this.components[name];
  }

  isReady() {
    return this.isInitialized;
  }
}

// Initialize app when DOM is ready
document.addEventListener('DOMContentLoaded', () => {
  window.wifiDensePoseApp = new WiFiDensePoseApp();
  window.wifiDensePoseApp.init();
});

// Export for testing
export { WiFiDensePoseApp };