// Clean SPA Router - Unified routing system for LibrePortal
class LibrePortalSPAClean {
  constructor() {
    this.routes = new Map();
    this.currentRoute = null;
    this.isLoading = false;
    this.dataLoaded = false;
    this.apps = [];
    this.categories = [];
    this.init();
  }

  async init() {
    //console.log('🚀 Clean SPA: Initializing...');
    
    // Setup routes immediately
    this.setupRoutes();
    
    // Wait for DOM to be ready
    if (document.readyState === 'loading') {
      await new Promise(resolve => {
        document.addEventListener('DOMContentLoaded', resolve);
      });
    }
    
    // Wait for topbar to load first
    await this.waitForTopbar();
    
    // Load data first
    await this.loadCoreData();
    
    // Handle initial route
    this.handleInitialRoute();
    
    //console.log('✅ Clean SPA: Initialization complete');
  }

  async waitForTopbar() {
    //console.log('⏳ Waiting for topbar to load...');
    
    // Wait for topbar component to be available and loaded
    let attempts = 0;
    const maxAttempts = 20; // 2 seconds max (reduced from 5 seconds)
    
    while (attempts < maxAttempts) {
      if (typeof TopbarComponent !== 'undefined' && TopbarComponent.loadTopbar) {
        try {
          await TopbarComponent.loadTopbar();
          //console.log('✅ Topbar loaded successfully');
          return;
        } catch (error) {
          console.warn('⚠️ Topbar loading failed, retrying...', error);
        }
      }
      
      await new Promise(resolve => setTimeout(resolve, 100));
      attempts++;
    }
    
    console.warn('⚠️ Topbar failed to load after 2 seconds, continuing without topbar');
    // Don't block the entire app if topbar fails
  }

  setupRoutes() {
    // Clean route definitions with explicit handlers
    this.routes.set('/', () => this.handleDashboard());
    this.routes.set('/dashboard', () => this.handleDashboard());
    this.routes.set('/apps', () => this.handleApps());
    this.routes.set('/apps*', () => this.handleApps());      // /apps/<category> — MUST precede /app* (/apps startsWith /app)
    this.routes.set('/app', () => this.handleAppDetail());   // /app/<name>
    this.routes.set('/app*', () => this.handleAppDetail());
    this.routes.set('/admin', () => this.handleAdmin());     // Admin area (path-based: /admin/config/<x>, /admin/tools/<x>)
    this.routes.set('/admin*', () => this.handleAdmin());
    this.routes.set('/config', () => this.handleConfigRedirect());  // legacy → /admin
    this.routes.set('/config*', () => this.handleConfigRedirect());
    this.routes.set('/tasks', () => this.handleTasks()); // Handle /tasks without query
    this.routes.set('/tasks*', () => this.handleTasks()); // Handle /tasks with query
    this.routes.set('/backup', () => this.handleBackup());
    this.routes.set('/backup*', () => this.handleBackup());
    this.routes.set('/peers', () => this.handlePeers());
    this.routes.set('/peers*', () => this.handlePeers());
    this.routes.set('/ssh', () => this.handleSsh());       // legacy → /admin/tools/ssh-access
    this.routes.set('/ssh*', () => this.handleSsh());

    //console.log('📍 Routes registered:', Array.from(this.routes.keys()));
  }

  async loadCoreData() {
    //console.log('📊 Loading core data...');
    
    try {
      // Load apps
      if (typeof DataLoader !== 'undefined' && DataLoader.loadApps) {
        this.apps = await DataLoader.loadApps();
        window.apps = this.apps;
        //console.log(`📱 Loaded ${this.apps.length} apps`);
      }
      
      // Load categories
      if (typeof DataLoader !== 'undefined' && DataLoader.loadCategories) {
        this.categories = await DataLoader.loadCategories();
        window.categories = this.categories;
        window.sidebarCategories = this.categories; // Ensure this is always available
        //console.log(`📂 Loaded ${Object.keys(this.categories).length} categories`);
      }
      
      this.dataLoaded = true;
      //console.log('✅ Core data loaded successfully');
      
    } catch (error) {
      console.error('❌ Failed to load core data:', error);
      this.showError('Failed to load application data');
    }
  }

  handleInitialRoute() {
    const path = window.location.pathname + window.location.search;
    // console.log('🎯 SPA: Handling initial route:', path);
    
    // Handle root path - redirect to dashboard
    if (path === '/' || path === '') {
      // console.log('🏠 SPA: Redirecting to dashboard');
      this.navigate('/dashboard', false);
    } else {
      // console.log('🔀 SPA: Navigating to:', path);
      this.navigate(path, false); // Don't add to history for initial load
    }
  }

  async navigate(path, addToHistory = true) {
    // console.log('🚀 SPA: navigate called with:', path, 'addToHistory:', addToHistory);
    
    if (this.isLoading) {
      // console.log('⏳ Navigation already in progress, ignoring:', path);
      return;
    }

    if (this.currentRoute === path && addToHistory) {
      //console.log('🔄 Same route, skipping navigation:', path);
      return;
    }

    // Unsaved-config guard — an app's config panel registers
    // window.__appConfigNavGuard while it has unsaved changes, so it can
    // intercept navigation away (Apply / Discard / Stay).
    if (typeof window.__appConfigNavGuard === 'function') {
      try {
        const decision = await window.__appConfigNavGuard(path);
        if (decision === 'stay') return;
      } catch (e) {
        console.error('Nav guard error:', e);
      }
    }

    // Force data reload when navigating to dashboard, even if same route
    if (path === '/dashboard' || path === '/') {
      // console.log('🔄 Dashboard navigation detected, forcing data reload');
      // Trigger dashboard data reload after a short delay to ensure DOM is ready
      setTimeout(() => {
        if (typeof loadDashboardData === 'function') {
          loadDashboardData();
        }
      }, 100);
    }

    this.isLoading = true;
    //console.log('🧭 Navigating to:', path);

    try {
      // Update browser history
      if (addToHistory) {
        history.pushState({ route: path }, '', path);
      }

      this.currentRoute = path;

      // Find and execute route handler
      const handler = this.findRouteHandler(path);
      if (handler) {
        await handler();
      } else {
        console.warn('❌ No handler found for:', path);
        this.showError('Page not found');
      }

      // Update navigation highlighting after content loads
      if (typeof window.topbarNavigationHighlighting === 'function') {
        //console.log('🔗 SPA: Updating navigation highlighting after navigation');
        window.topbarNavigationHighlighting();
      }

    } catch (error) {
      console.error('❌ Navigation error:', error);
      this.showError('Navigation failed');
    } finally {
      this.isLoading = false;
    }
  }

  findRouteHandler(path) {
    //console.log('🔍 Finding handler for path:', path);
    
    // Exact match first
    if (this.routes.has(path)) {
      //console.log('✅ Exact match found:', path);
      return this.routes.get(path);
    }

    // Handle query parameters - strip them for matching
    let basePath = path;
    if (path.includes('?')) {
      basePath = path.split('?')[0];
    }
    
    //console.log('🔍 Checking base path:', basePath, 'for full path:', path);
    
    // Check base path against routes
    if (this.routes.has(basePath)) {
      //console.log('✅ Base path match found:', basePath);
      return this.routes.get(basePath);
    }

    // Wildcard matching for remaining cases
    for (const [route, handler] of this.routes) {
      if (route.includes('*')) {
        const pattern = route.replace('*', '');
        if (basePath.startsWith(pattern)) {
          //console.log('✅ Wildcard match:', pattern, 'for base path:', basePath);
          return handler;
        }
      }
    }

    //console.log('❌ No handler found for:', path);
    //console.log('❌ Base path:', basePath);
    //console.log('❌ Available routes:', Array.from(this.routes.keys()));
    return null;
  }

  async handleDashboard() {
    // console.log('🏠 SPA: Loading dashboard...');
    
    try {
      // console.log('📄 SPA: Fetching dashboard content...');
      const html = await this.fetchContent('/html/dashboard-content.html');
      // console.log('📄 SPA: Dashboard content fetched, loading...');
      this.loadContent(html, 'Dashboard');
      // console.log('📄 SPA: Dashboard content loaded');
      
      // Dashboard should already be initialized by SystemLoader
      if (typeof loadInstalledApps === 'function') {
        // console.log('📱 SPA: Loading installed apps...');
        loadInstalledApps();
      }
    } catch (error) {
      console.error('❌ Dashboard load error:', error);
      this.showError('Failed to load dashboard');
    }
  }

  async handleBackup() {
    try {
      const html = await this.fetchContent('/html/backup-content.html');
      this.loadContent(html, 'Backups');
      if (typeof BackupPage !== 'undefined') {
        window.backupPage = new BackupPage();
        await window.backupPage.init();
      } else {
        console.error('BackupPage class not loaded');
      }
    } catch (error) {
      console.error('❌ Backup page load error:', error);
      this.showError('Failed to load backup page');
    }
  }

  async handlePeers() {
    try {
      const html = await this.fetchContent('/html/peers-content.html');
      this.loadContent(html, 'Peers');
      if (typeof PeersPage !== 'undefined') {
        window.peersPage = new PeersPage();
        await window.peersPage.init();
      } else {
        console.error('PeersPage class not loaded');
      }
    } catch (error) {
      console.error('❌ Peers page load error:', error);
      this.showError('Failed to load peers page');
    }
  }

  async handleSsh() {
    // Legacy /ssh → SSH Access under the Admin area.
    this.navigate('/admin/tools/ssh-access', true);
  }

  async handleApps() {
    //console.log('📱 Loading apps...');
    
    // Category from the path (/apps/<category>), else legacy ?=<cat> / ?apps=.
    const seg = window.location.pathname.replace(/^\/apps\/?/, '').split('/')[0];
    if (seg) {
        window.appsCategory = decodeURIComponent(seg);
    } else {
        const search = window.location.search || '';
        if (search.includes('?=')) {
            window.appsCategory = (window.location.pathname + search).split('?=')[1] || 'all';
        } else {
            window.appsCategory = new URLSearchParams(search).get('apps') || 'all';
        }
    }
    
    try {
      // Ensure unified layout is loaded (like the old SPA)
      if (!document.querySelector('.apps-layout')) {
        //console.log('📄 Loading apps layout HTML...');
        const html = await this.fetchContent('/html/apps-unified-layout.html');
        this.loadContent(html, 'Applications');
      } else {
        //console.log('📄 Apps layout already exists, skipping HTML load');
      }
      
      // Apps manager should already be initialized by SystemLoader
      if (window.appsManager) {
        //console.log('✅ AppsManager already initialized by SystemLoader');
        await window.appsManager.initialize();
        
        //console.log('✅ Apps loaded successfully');
      } else {
        console.error('AppsManager not available - SystemLoader should have initialized it');
        throw new Error('AppsManager not initialized by SystemLoader');
      }
    } catch (error) {
      console.error('❌ Apps load error:', error);
      this.showError('Failed to load applications: ' + error.message);
    }
  }

  async handleAppDetail() {
    //console.log('🔍 Loading app detail...');
    
    // Extract app name. Path-based /app/<name> first, then legacy ?app= / ?=name.
    const url = new URL(window.location);
    let appName = url.pathname.replace(/^\/app\/?/, '').split('/')[0];
    appName = appName ? decodeURIComponent(appName) : '';

    if (!appName) appName = url.searchParams.get('app');

    // Handle old format ?=appname&tab=tabname
    if (!appName && url.search.includes('?=')) {
      const queryPart = url.search.replace('?', '');
      const parts = queryPart.split('&');
      for (const part of parts) {
        if (part.startsWith('=')) {
          appName = part.substring(1); // Remove the '='
          break;
        }
      }
    }
    
    //console.log('🔍 Parsed app name:', appName, 'from URL:', url.search);
    
    if (!appName) {
      this.navigate('/apps', false);
      return;
    }
    
    try {
      const html = await this.fetchContent('/html/apps-unified-layout.html');
      this.loadContent(html, appName); // Will be updated after app data loads
      
      // AppTabbedManager should already be initialized by SystemLoader
      if (window.appTabbedManager) {
        // console.log('✅ AppTabbedManager already initialized by SystemLoader');
        await window.appTabbedManager.initialize();
      } else {
        console.error('AppTabbedManager not available - SystemLoader should have initialized it');
        throw new Error('AppTabbedManager not initialized by SystemLoader');
      }
      
      //console.log('✅ App detail loaded:', appName);
    } catch (error) {
      console.error('❌ App detail load error:', error);
      this.showError('Failed to load application details');
    }
  }

  // Admin area. Path-based: /admin (overview), /admin/config/<category>,
  // /admin/tools/ssh-access. Reuses the config page shell + ConfigManager.
  async handleAdmin() {
    window.configCategory = window.adminCategoryFromPath(window.location.pathname);

    try {
      const html = await this.fetchContent('/html/config-content.html');
      this.loadContent(html, 'Admin');

      if (window.configManager) {
        if (typeof window.configManager.renderConfig === 'function') {
          await window.configManager.renderConfig(window.configCategory || 'overview');
        }
      } else {
        console.error('ConfigManager not available - SystemLoader should have initialized it');
        throw new Error('ConfigManager not initialized by SystemLoader');
      }
    } catch (error) {
      console.error('❌ Admin load error:', error);
      this.showError('Failed to load the Admin area');
    }
  }

  // Legacy /config and /config?=<x> → the path-based /admin equivalent.
  async handleConfigRedirect() {
    const search = window.location.search || '';
    let cat = 'overview';
    if (search.includes('?=')) {
      cat = (window.location.pathname + search).split('?=')[1] || 'overview';
    } else {
      cat = new URLSearchParams(search).get('config') || 'overview';
    }
    this.navigate(window.adminPath(cat), true);
  }

  async handleTasks() {
    //console.log('📋 Loading tasks...');
    
    try {
      const html = await this.fetchContent('/html/tasks-content.html');
      this.loadContent(html, 'Tasks');
      
      // Tasks manager should already be initialized by SystemLoader
      if (window.tasksManager) {
        //console.log('✅ TasksManager already initialized by SystemLoader');
        await window.tasksManager.init();
      } else {
        console.warn('⚠️ TasksManager not available yet, task functionality will be limited');
        // Don't throw error - just show warning and continue
        // The task system will be available when the user actually interacts with tasks
      }
    } catch (error) {
      console.error('❌ Tasks load error:', error);
      this.showError('Failed to load tasks');
    }
  }

  async fetchContent(url) {
    //console.log('📥 Fetching:', url);
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}: ${response.statusText}`);
    }
    return await response.text();
  }

  async loadScript(src) {
    const scriptId = src.replace(/[^a-zA-Z0-9]/g, '_');
    if (document.getElementById(scriptId)) {
      return; // Already loaded
    }

    return new Promise((resolve, reject) => {
      const script = document.createElement('script');
      script.src = src;
      script.id = scriptId;
      script.onload = resolve;
      script.onerror = reject;
      document.head.appendChild(script);
    });
  }

  loadContent(html, title) {
    const container = document.getElementById('main-content') || document.querySelector('.main');
    if (!container) {
      throw new Error('Content container not found');
    }

    container.innerHTML = html;
    document.title = `${title} - LibrePortal`;
    
    // Update navigation highlighting
    this.updateNavigation();
  }

  updateNavigation() {
    //console.log('🔗 SPA: Using fallback navigation logic');
    
    // Remove ALL active classes
    document.querySelectorAll('.nav-item').forEach(item => {
      item.classList.remove('active');
      item.classList.remove('nav-active');
    });

    // Use path-based detection only for consistency
    const path = window.location.pathname;
    
    let activeId = 'nav-dashboard'; // default
    
    if (path.startsWith('/app') || path.startsWith('/apps')) {
      activeId = 'nav-app-center';
    } else if (path.startsWith('/admin') || path.startsWith('/config') || path.startsWith('/ssh')) {
      activeId = 'nav-config';
    } else if (path.startsWith('/tasks')) {
      activeId = 'nav-tasks';
    } else if (path.startsWith('/backup')) {
      activeId = 'nav-backup';
    } else if (path === '/' || path === '/dashboard') {
      activeId = 'nav-dashboard';
    }

    //console.log('🔗 SPA: Setting active nav:', activeId);
    const activeElement = document.getElementById(activeId);
    if (activeElement) {
      activeElement.classList.add('nav-active');
    }
  }

  showError(message) {
    const container = document.getElementById('main-content') || document.querySelector('.main');
    if (container) {
      container.innerHTML = `
        <div class="error-page">
          <h2>Error</h2>
          <p>${message}</p>
          <button onclick="location.reload()">Reload Page</button>
        </div>
      `;
    }
  }
}

// Admin area path helpers (shared by the SPA, sidebar, overview, ssh page).
// Map a category to its path-based URL, and parse a path back to a category.
window.adminPath = function (category) {
  if (!category || category === 'overview') return '/admin';
  if (category === 'ssh-access') return '/admin/tools/ssh-access';
  return '/admin/config/' + category;
};
window.adminCategoryFromPath = function (pathname) {
  const segs = String(pathname || '').replace(/^\/admin\/?/, '').split('/').filter(Boolean);
  if (!segs.length || segs[0] === 'overview') return 'overview';
  if (segs[0] === 'config') return segs[1] || 'general';
  if (segs[0] === 'tools') return segs[1] || 'overview';
  return segs[0];
};

// Global navigation function for click handlers
window.navigateToRoute = function(href) {
  if (window.spaClean) {
    //console.log('🔗 Converting href:', href);
    
    // Convert href to clean path - handle various formats
    let route = href.replace('.html', '').replace('./', '').replace(/^\//, '');
    
    // Handle special cases
    if (route === '' || route === 'index') {
      route = '/apps'; // index goes to apps (main app center)
    } else if (route === 'dashboard') {
      route = '/dashboard';
    } else if (route === 'apps') {
      route = '/apps';
    } else if (route === 'config' || route === 'admin') {
      route = '/admin';
    } else if (route === 'tasks') {
      route = '/tasks';
    } else if (!route.startsWith('/')) {
      route = '/' + route;
    }
    
    //console.log('🎯 Final route:', route);
    window.spaClean.navigate(route);
  }
};

// Handle browser back/forward
window.addEventListener('popstate', (e) => {
  if (e.state && e.state.route && window.spaClean) {
    window.spaClean.navigate(e.state.route, false);
  }
});

// Handle internal link clicks
document.addEventListener('click', (e) => {
  const target = e.target.closest('a');
  if (target && target.href) {
    const href = target.getAttribute('href');
    if (href && (href.startsWith('/') || href.startsWith('./'))) {
      e.preventDefault();
      window.navigateToRoute(href);
    }
  }
});

// SPA initialization is now handled by SystemLoader
// LibrePortalSPAClean instance will be created centrally
