/**
 * Mock for modules/index.js to avoid import.meta issues in Jest
 */

export const activeModules = new Map();

export const registerModules = jest.fn(async () => {
  // Use the global mock function if available
  const globFn = global.importMeta?.glob || (() => ({}));
  const modules = globFn('./*/index.js', { eager: true });
  
  const domModules = new Set(
    Array.from(document.querySelectorAll('[data-module]')).map(el => el.dataset.module).filter(Boolean)
  );
  
  const usedModules = new Set(domModules);
  const fallbackMode = usedModules.size === 0;
  
  // Use the already mocked dependencies from Jest
  const { dependencyManager } = require('../../../../../resources/js/core/DependencyManager.js');
  const { moduleErrorBoundary } = require('../../../../../resources/js/core/ModuleErrorBoundary.js');
  const { stateManager } = require('../../../../../resources/js/core/StateManager.js');
  
  // Phase 1: Register all modules with dependency manager
  Object.entries(modules).forEach(([path, mod]) => {
    const name = path.split('/').slice(-2, -1)[0];
    
    if(!fallbackMode && !usedModules.has(name)) {
      return;
    }
    
    if (typeof mod.definition === 'object') {
      dependencyManager.register(mod.definition);
    } else {
      const defaultDef = {
        name,
        version: '1.0.0',
        dependencies: [],
        provides: [],
        priority: 0
      };
      dependencyManager.register(defaultDef);
    }
  });
  
  // Phase 2: Calculate initialization order
  const initOrder = dependencyManager.calculateInitializationOrder();
  
  // Phase 3: Initialize modules in dependency order
  for (const name of initOrder) {
    if(!fallbackMode && !usedModules.has(name)) {
      continue;
    }
    
    const mod = Object.entries(modules).find(([path]) => path.includes(name))?.[1];
    if (!mod) continue;
    
    const config = {};
    
    const dependencyCheck = dependencyManager.checkDependencies(name);
    if (!dependencyCheck.satisfied) {
      activeModules.set(name, {
        mod: null,
        config,
        error: new Error(dependencyCheck.reason),
        original: mod
      });
      continue;
    }
    
    try {
      dependencyManager.markInitializing(name);
      
      const wrappedMod = moduleErrorBoundary.wrapModule(mod, name);
      const scopedState = stateManager.createScope(name);
      
      if (typeof mod.init === 'function') {
        await mod.init(config, scopedState);
      }
      
      activeModules.set(name, {
        mod: wrappedMod,
        config,
        state: scopedState,
        original: mod
      });
      
      dependencyManager.markInitialized(name);
    } catch (error) {
      activeModules.set(name, {
        mod: null,
        config,
        error,
        original: mod
      });
    }
  }
});

export const destroyModules = jest.fn(() => {
  for (const [name, moduleData] of activeModules) {
    try {
      if (moduleData.mod && typeof moduleData.mod.destroy === 'function') {
        moduleData.mod.destroy();
      }
      if (moduleData.state && typeof moduleData.state.cleanup === 'function') {
        moduleData.state.cleanup();
      }
    } catch (error) {
      // Handle errors gracefully
    }
  }
  
  activeModules.clear();
  
  // Use the already mocked dependencies
  const { moduleErrorBoundary } = require('../../../../../resources/js/core/ModuleErrorBoundary.js');
  const { stateManager } = require('../../../../../resources/js/core/StateManager.js');
  const { dependencyManager } = require('../../../../../resources/js/core/DependencyManager.js');
  
  moduleErrorBoundary.reset();
  stateManager.resetAll();
  dependencyManager.reset();
});

export const getModuleHealth = jest.fn(() => {
  const health = {
    total: activeModules.size,
    active: 0,
    failed: 0,
    modules: {},
    errorBoundary: {
      totalCrashedModules: 0,
      crashedModules: [],
      recoveryAttempts: {}
    }
  };
  
  for (const [name, moduleData] of activeModules) {
    if (moduleData.error) {
      health.failed++;
      health.modules[name] = {
        status: 'failed',
        error: moduleData.error.message
      };
    } else {
      health.active++;
      health.modules[name] = {
        status: 'active'
      };
    }
  }
  
  return health;
});