import { logger } from '../../utils/logger';
import { FeatureGovernanceService } from '../governance/FeatureGovernanceService';
import { SERVICE_CONFIGS, ServiceConfig } from '../../config/serviceConfig';

export interface DomainModule {
  name: string;
  priority: number;
  init: () => Promise<void>;
  isAgi?: boolean;
  config?: ServiceConfig;
}

class ServiceStateManager {
  private static instance: ServiceStateManager;
  private enabledServices: Set<string>;
  private initializedServices: Set<string> = new Set();
  private failedServices: Map<string, string> = new Map();

  private constructor() {
    this.enabledServices = new Set(
      SERVICE_CONFIGS.filter(s => s.enabled).map(s => s.name)
    );
  }

  static getInstance(): ServiceStateManager {
    if (!this.instance) {
      this.instance = new ServiceStateManager();
    }
    return this.instance;
  }

  isEnabled(name: string): boolean {
    return this.enabledServices.has(name);
  }

  enable(name: string): void {
    this.enabledServices.add(name);
  }

  disable(name: string): void {
    this.enabledServices.delete(name);
  }

  markInitialized(name: string): void {
    this.initializedServices.add(name);
    this.failedServices.delete(name);
  }

  markFailed(name: string, error: string): void {
    this.failedServices.set(name, error);
  }

  getStatus(): {
    enabled: string[];
    initialized: string[];
    failed: Map<string, string>;
  } {
    return {
      enabled: Array.from(this.enabledServices),
      initialized: Array.from(this.initializedServices),
      failed: new Map(this.failedServices),
    };
  }

  getAllServices(): Array<{
    name: string;
    enabled: boolean;
    initialized: boolean;
    error?: string;
    config?: ServiceConfig;
  }> {
    return SERVICE_CONFIGS.map(config => ({
      name: config.name,
      enabled: this.enabledServices.has(config.name),
      initialized: this.initializedServices.has(config.name),
      error: this.failedServices.get(config.name),
      config,
    }));
  }

  setEnabledServices(services: string[]): void {
    this.enabledServices = new Set(services);
  }
}

export const serviceStateManager = ServiceStateManager.getInstance();

export class DomainRegistry {
  private static modules: DomainModule[] = [];

  static register(module: DomainModule) {
    const config = SERVICE_CONFIGS.find(s => s.name === module.name);
    this.modules.push({ ...module, config });
  }

  static async bootstrap(tenantId?: string) {
    const sortedModules = [...this.modules].sort((a, b) => a.priority - b.priority);

    const isAgiBaseMode = await FeatureGovernanceService.isEnabled('CORE_AGI_BASE_MODE', tenantId);
    
    const state = ServiceStateManager.getInstance();
    const enabledCount = sortedModules.filter(m => state.isEnabled(m.name)).length;
    
    logger.info(`[DomainRegistry] Bootstrapping ${enabledCount}/${sortedModules.length} modules... (AGI Base Mode: ${isAgiBaseMode})`);

    for (const module of sortedModules) {
      if (!state.isEnabled(module.name)) {
        logger.info(`[DomainRegistry] Skipping disabled module: ${module.name}`);
        continue;
      }

      if (module.isAgi && isAgiBaseMode) {
        logger.warn(`[DomainRegistry] Skipping Heavy AGI module: ${module.name} (Base Mode Active)`);
        continue;
      }

      try {
        await module.init();
        state.markInitialized(module.name);
        logger.info(`[DomainRegistry] Module initialized: ${module.name}`);
      } catch (err: unknown) {
        const errorMessage = err instanceof Error ? err.message : String(err);
        logger.error(`[DomainRegistry] Module ${module.name} failed to initialize: ${errorMessage}`);
        state.markFailed(module.name, errorMessage);
        if (module.priority < 10) {
          throw err;
        }
      }
    }

    logger.info('✅ [DomainRegistry] Bootstrap completed successfully.');
  }

  static Priority = {
    CORE_INFRA: 0,
    SECURITY: 5,
    RUNTIME: 10,
    BIZ_DOMAIN: 20,
    AGI_HEAVY: 50,
    SUPPORT: 100
  };

  static getDomains(): DomainModule[] {
    return [...this.modules];
  }

  static getServiceStatus() {
    return ServiceStateManager.getInstance().getAllServices();
  }

  static setEnabledServices(services: string[]): void {
    ServiceStateManager.getInstance().setEnabledServices(services);
  }

  static enableService(name: string): void {
    ServiceStateManager.getInstance().enable(name);
  }

  static disableService(name: string): void {
    ServiceStateManager.getInstance().disable(name);
  }
}
