import { DomainEventBus } from '../runtime/DomainEventBus';
import { ServiceRegistry } from './ServiceRegistry';
import { ServiceMonitor } from './ServiceMonitor';

// 服务类型定义
export interface ServiceDefinition {
  id: string;
  name: string;
  version: string;
  dependencies: string[];
  healthCheck: () => Promise<boolean>;
  start: () => Promise<void>;
  stop: () => Promise<void>;
  metadata?: Record<string, any>;
}

// 服务状态
export type ServiceStatus = 'stopped' | 'starting' | 'running' | 'stopping' | 'error';

// 服务实例
export interface ServiceInstance {
  definition: ServiceDefinition;
  status: ServiceStatus;
  lastHealthCheck: Date;
  error?: string;
}

// 服务编排器
export class ServiceOrchestrator {
  private static instance: ServiceOrchestrator;
  private serviceRegistry: ServiceRegistry;
  private serviceMonitor: ServiceMonitor;
  private serviceInstances: Map<string, ServiceInstance> = new Map();
  private eventBus: DomainEventBus;

  private constructor() {
    this.serviceRegistry = ServiceRegistry.getInstance();
    this.serviceMonitor = ServiceMonitor.getInstance();
    this.eventBus = DomainEventBus.getInstance();
  }

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

  // 注册服务
  async registerService(service: ServiceDefinition): Promise<void> {
    // 验证服务依赖
    for (const dependency of service.dependencies) {
      if (!this.serviceRegistry.getService(dependency)) {
        throw new Error(`Dependency ${dependency} not found`);
      }
    }

    // 注册到服务注册表
    await this.serviceRegistry.registerService(service);

    // 创建服务实例
    const instance: ServiceInstance = {
      definition: service,
      status: 'stopped',
      lastHealthCheck: new Date()
    };

    this.serviceInstances.set(service.id, instance);
    this.eventBus.publish('service.registered', { serviceId: service.id });
  }

  // 启动服务
  async startService(serviceId: string): Promise<void> {
    const instance = this.serviceInstances.get(serviceId);
    if (!instance) {
      throw new Error(`Service ${serviceId} not found`);
    }

    if (instance.status === 'running') {
      return;
    }

    // 启动依赖服务
    for (const dependencyId of instance.definition.dependencies) {
      await this.startService(dependencyId);
    }

    instance.status = 'starting';
    this.eventBus.publish('service.starting', { serviceId });

    try {
      await instance.definition.start();
      instance.status = 'running';
      instance.lastHealthCheck = new Date();
      this.eventBus.publish('service.started', { serviceId });
    } catch (error) {
      instance.status = 'error';
      instance.error = error instanceof Error ? error.message : String(error);
      this.eventBus.publish('service.error', { serviceId, error: instance.error });
      throw error;
    }
  }

  // 停止服务
  async stopService(serviceId: string): Promise<void> {
    const instance = this.serviceInstances.get(serviceId);
    if (!instance) {
      throw new Error(`Service ${serviceId} not found`);
    }

    if (instance.status === 'stopped') {
      return;
    }

    // 检查是否有其他服务依赖此服务
    const dependentServices = Array.from(this.serviceInstances.values())
      .filter(s => s.definition.dependencies.includes(serviceId));

    if (dependentServices.length > 0) {
      throw new Error(`Service ${serviceId} is being used by other services: ${dependentServices.map(s => s.definition.id).join(', ')}`);
    }

    instance.status = 'stopping';
    this.eventBus.publish('service.stopping', { serviceId });

    try {
      await instance.definition.stop();
      instance.status = 'stopped';
      this.eventBus.publish('service.stopped', { serviceId });
    } catch (error) {
      instance.status = 'error';
      instance.error = error instanceof Error ? error.message : String(error);
      this.eventBus.publish('service.error', { serviceId, error: instance.error });
      throw error;
    }
  }

  // 启动所有服务
  async startAllServices(): Promise<void> {
    const services = Array.from(this.serviceInstances.values());
    
    // 按依赖顺序排序
    const sortedServices = this.topologicalSort(services);

    for (const service of sortedServices) {
      await this.startService(service.definition.id);
    }
  }

  // 停止所有服务
  async stopAllServices(): Promise<void> {
    const services = Array.from(this.serviceInstances.values());
    
    // 按依赖顺序的逆序排序
    const sortedServices = this.topologicalSort(services).reverse();

    for (const service of sortedServices) {
      try {
        await this.stopService(service.definition.id);
      } catch (error) {
        console.error(`Error stopping service ${service.definition.id}:`, error);
      }
    }
  }

  // 拓扑排序服务依赖
  private topologicalSort(services: ServiceInstance[]): ServiceInstance[] {
    const visited = new Set<string>();
    const temp = new Set<string>();
    const result: ServiceInstance[] = [];

    const visit = (serviceId: string) => {
      if (temp.has(serviceId)) {
        throw new Error('Circular dependency detected');
      }

      if (visited.has(serviceId)) {
        return;
      }

      temp.add(serviceId);

      const service = services.find(s => s.definition.id === serviceId);
      if (service) {
        for (const dependencyId of service.definition.dependencies) {
          visit(dependencyId);
        }
      }

      temp.delete(serviceId);
      visited.add(serviceId);
      
      const foundService = services.find(s => s.definition.id === serviceId);
      if (foundService) {
        result.push(foundService);
      }
    };

    for (const service of services) {
      if (!visited.has(service.definition.id)) {
        visit(service.definition.id);
      }
    }

    return result;
  }

  // 获取服务状态
  getServiceStatus(serviceId: string): ServiceStatus | undefined {
    const instance = this.serviceInstances.get(serviceId);
    return instance?.status;
  }

  // 获取所有服务状态
  getAllServiceStatuses(): Map<string, ServiceStatus> {
    const statuses = new Map<string, ServiceStatus>();
    for (const [id, instance] of this.serviceInstances) {
      statuses.set(id, instance.status);
    }
    return statuses;
  }

  // 健康检查
  async healthCheck(serviceId: string): Promise<boolean> {
    const instance = this.serviceInstances.get(serviceId);
    if (!instance) {
      return false;
    }

    try {
      const healthy = await instance.definition.healthCheck();
      instance.lastHealthCheck = new Date();
      
      if (instance.status === 'error' && healthy) {
        instance.status = 'running';
        instance.error = undefined;
        this.eventBus.publish('service.recovered', { serviceId });
      }

      return healthy;
    } catch (error) {
      instance.status = 'error';
      instance.error = error instanceof Error ? error.message : String(error);
      instance.lastHealthCheck = new Date();
      this.eventBus.publish('service.error', { serviceId, error: instance.error });
      return false;
    }
  }

  // 执行所有服务的健康检查
  async healthCheckAll(): Promise<Map<string, boolean>> {
    const results = new Map<string, boolean>();
    
    for (const serviceId of this.serviceInstances.keys()) {
      const healthy = await this.healthCheck(serviceId);
      results.set(serviceId, healthy);
    }

    return results;
  }
}
