/**
 * 多客户端并行控制和管理系统
 * 支持同时管理多个客户端实例，实现负载均衡和故障转移
 */

import { EnhancedClient, EnhancedClientConfig } from './enhanced-client';
import { ApiResponse } from './api-simulator';

interface ClientInstance {
  id: string;
  name: string;
  config: EnhancedClientConfig;
  client: EnhancedClient;
  status: 'online' | 'offline' | 'error';
  lastHeartbeat: Date;
  load: number; // 当前负载 0-100
  capabilities: string[]; // 支持的功能
  tags: string[]; // 标签，用于分组和筛选
}

interface ClientGroup {
  id: string;
  name: string;
  clientIds: string[];
  strategy: 'round-robin' | 'load-balance' | 'failover';
}

interface LoadBalanceRequest {
  type: 'login' | 'api' | 'task' | 'workflow';
  platform?: string;
  action: string;
  data: any;
  priority?: 'high' | 'normal' | 'low';
  requireTags?: string[]; // 要求的客户端标签
  excludeTags?: string[]; // 排除的客户端标签
}

interface LoadBalanceResult {
  clientId: string;
  response: ApiResponse;
  executionTime: number;
}

/**
 * 客户端管理器 - 管理多个客户端实例
 */
export class ClientManager {
  private clients: Map<string, ClientInstance> = new Map();
  private groups: Map<string, ClientGroup> = new Map();
  private roundRobinIndex: Map<string, number> = new Map();

  /**
   * 注册客户端实例
   */
  async registerClient(
    name: string,
    config: EnhancedClientConfig,
    tags: string[] = []
  ): Promise<string> {
    const clientId = this.generateId();
    
    try {
      const client = new EnhancedClient(config);
      await client.start();
      
      const instance: ClientInstance = {
        id: clientId,
        name,
        config,
        client,
        status: 'online',
        lastHeartbeat: new Date(),
        load: 0,
        capabilities: this.detectCapabilities(config),
        tags
      };
      
      this.clients.set(clientId, instance);
      
      // 启动心跳检测
      this.startHeartbeat(clientId);
      
      console.log(`客户端注册成功: ${name} (${clientId})`);
      return clientId;
    } catch (error) {
      console.error(`客户端注册失败: ${name}`, error);
      throw error;
    }
  }

  /**
   * 检测客户端能力
   */
  private detectCapabilities(config: EnhancedClientConfig): string[] {
    const capabilities: string[] = ['api-simulation', 'task-scheduling'];
    
    if (config.headless === false) {
      capabilities.push('remote-desktop');
    }
    
    if (config.proxy) {
      capabilities.push('proxy-support');
    }
    
    return capabilities;
  }

  /**
   * 启动心跳检测
   */
  private startHeartbeat(clientId: string): void {
    const interval = setInterval(async () => {
      const instance = this.clients.get(clientId);
      if (!instance) {
        clearInterval(interval);
        return;
      }
      
      try {
        // 模拟心跳检测
        instance.lastHeartbeat = new Date();
        
        // 更新负载状态
        instance.load = Math.floor(Math.random() * 100); // 模拟负载
        
        // 如果负载过高，标记为错误状态
        if (instance.load > 90) {
          instance.status = 'error';
        } else {
          instance.status = 'online';
        }
        
      } catch (error) {
        instance.status = 'offline';
        console.error(`客户端心跳检测失败: ${clientId}`, error);
      }
    }, 30000); // 每30秒检测一次
  }

  /**
   * 创建客户端组
   */
  createGroup(name: string, strategy: ClientGroup['strategy'], clientIds: string[]): string {
    const groupId = this.generateId();
    
    const group: ClientGroup = {
      id: groupId,
      name,
      clientIds: clientIds.filter(id => this.clients.has(id)),
      strategy
    };
    
    this.groups.set(groupId, group);
    this.roundRobinIndex.set(groupId, 0);
    
    console.log(`客户端组创建成功: ${name} (${groupId})`);
    return groupId;
  }

  /**
   * 负载均衡分发请求
   */
  async distributeRequest(groupId: string, request: LoadBalanceRequest): Promise<LoadBalanceResult> {
    const group = this.groups.get(groupId);
    if (!group) {
      throw new Error(`客户端组不存在: ${groupId}`);
    }
    
    const availableClients = this.getAvailableClients(group.clientIds, request);
    
    if (availableClients.length === 0) {
      throw new Error('没有可用的客户端');
    }
    
    const selectedClient = this.selectClient(group.strategy, availableClients, request);
    
    const startTime = Date.now();
    const response = await this.executeRequest(selectedClient.id, request);
    const executionTime = Date.now() - startTime;
    
    return {
      clientId: selectedClient.id,
      response,
      executionTime
    };
  }

  /**
   * 获取可用的客户端列表
   */
  private getAvailableClients(clientIds: string[], request: LoadBalanceRequest): ClientInstance[] {
    return clientIds
      .map(id => this.clients.get(id))
      .filter((instance): instance is ClientInstance => {
        if (!instance) return false;
        
        // 检查状态
        if (instance.status !== 'online') return false;
        
        // 检查标签要求
        if (request.requireTags && !request.requireTags.every(tag => instance.tags.includes(tag))) {
          return false;
        }
        
        // 检查排除标签
        if (request.excludeTags && request.excludeTags.some(tag => instance.tags.includes(tag))) {
          return false;
        }
        
        // 检查能力要求
        if (request.type === 'api' && !instance.capabilities.includes('api-simulation')) {
          return false;
        }
        
        return true;
      });
  }

  /**
   * 选择客户端（负载均衡策略）
   */
  private selectClient(
    strategy: ClientGroup['strategy'],
    clients: ClientInstance[],
    request: LoadBalanceRequest
  ): ClientInstance {
    switch (strategy) {
      case 'round-robin':
        return this.roundRobinSelect(clients);
      
      case 'load-balance':
        return this.loadBalanceSelect(clients);
      
      case 'failover':
        return this.failoverSelect(clients, request);
      
      default:
        return clients[0];
    }
  }

  /**
   * 轮询选择
   */
  private roundRobinSelect(clients: ClientInstance[]): ClientInstance {
    const groupId = Array.from(this.groups.entries())
      .find(([_, group]) => group.clientIds.some(id => clients.some(c => c.id === id)))?.[0];
    
    if (!groupId) {
      return clients[0];
    }
    
    const currentIndex = this.roundRobinIndex.get(groupId) || 0;
    const selectedIndex = currentIndex % clients.length;
    
    this.roundRobinIndex.set(groupId, currentIndex + 1);
    
    return clients[selectedIndex];
  }

  /**
   * 负载均衡选择（选择负载最低的）
   */
  private loadBalanceSelect(clients: ClientInstance[]): ClientInstance {
    return clients.reduce((prev, current) => 
      prev.load < current.load ? prev : current
    );
  }

  /**
   * 故障转移选择
   */
  private failoverSelect(clients: ClientInstance[], request: LoadBalanceRequest): ClientInstance {
    // 根据优先级和标签选择
    const prioritized = clients.sort((a, b) => {
      // 优先选择负载低的
      if (a.load !== b.load) {
        return a.load - b.load;
      }
      
      // 优先选择有特定标签的
      if (request.requireTags) {
        const aTags = a.tags.filter(tag => request.requireTags!.includes(tag)).length;
        const bTags = b.tags.filter(tag => request.requireTags!.includes(tag)).length;
        
        if (aTags !== bTags) {
          return bTags - aTags;
        }
      }
      
      return 0;
    });
    
    return prioritized[0];
  }

  /**
   * 执行请求
   */
  private async executeRequest(clientId: string, request: LoadBalanceRequest): Promise<ApiResponse> {
    const instance = this.clients.get(clientId);
    if (!instance) {
      throw new Error(`客户端不存在: ${clientId}`);
    }
    
    try {
      // 这里应该调用EnhancedClient的相应方法
      // 暂时返回模拟响应
      return {
        success: true,
        data: {
          message: `请求由客户端 ${instance.name} 处理完成`,
          clientId,
          request
        },
        timestamp: Date.now()
      };
    } catch (error) {
      return {
        success: false,
        error: error instanceof Error ? error.message : '请求执行失败',
        timestamp: Date.now()
      };
    }
  }

  /**
   * 批量执行请求（并行处理）
   */
  async batchExecuteRequests(
    groupId: string,
    requests: LoadBalanceRequest[]
  ): Promise<LoadBalanceResult[]> {
    const group = this.groups.get(groupId);
    if (!group) {
      throw new Error(`客户端组不存在: ${groupId}`);
    }
    
    const availableClients = this.getAvailableClients(group.clientIds, {} as LoadBalanceRequest);
    
    if (availableClients.length === 0) {
      throw new Error('没有可用的客户端');
    }
    
    // 将请求分配给不同的客户端
    const assignments = this.assignRequestsToClients(requests, availableClients, group.strategy);
    
    // 并行执行所有请求
    const promises = assignments.map(async (assignment) => {
      const startTime = Date.now();
      const response = await this.executeRequest(assignment.clientId, assignment.request);
      const executionTime = Date.now() - startTime;
      
      return {
        clientId: assignment.clientId,
        response,
        executionTime
      };
    });
    
    return await Promise.all(promises);
  }

  /**
   * 将请求分配给客户端
   */
  private assignRequestsToClients(
    requests: LoadBalanceRequest[],
    clients: ClientInstance[],
    strategy: ClientGroup['strategy']
  ): Array<{clientId: string, request: LoadBalanceRequest}> {
    const assignments: Array<{clientId: string, request: LoadBalanceRequest}> = [];
    
    if (strategy === 'round-robin') {
      let clientIndex = 0;
      
      for (const request of requests) {
        const client = clients[clientIndex % clients.length];
        assignments.push({ clientId: client.id, request });
        clientIndex++;
      }
    } else {
      // 负载均衡策略：根据请求类型和客户端负载分配
      const clientLoads = new Map(clients.map(client => [client.id, { client, load: client.load }]));
      
      for (const request of requests) {
        // 选择负载最低的客户端
        const selectedClient = Array.from(clientLoads.values())
          .reduce((prev, current) => prev.load < current.load ? prev : current)
          .client;
        
        assignments.push({ clientId: selectedClient.id, request });
        
        // 更新负载（模拟）
        const currentLoad = clientLoads.get(selectedClient.id)!;
        clientLoads.set(selectedClient.id, {
          ...currentLoad,
          load: currentLoad.load + 10 // 每次请求增加10%负载
        });
      }
    }
    
    return assignments;
  }

  /**
   * 获取客户端状态
   */
  getClientStatus(clientId: string): ClientInstance | undefined {
    return this.clients.get(clientId);
  }

  /**
   * 获取所有客户端状态
   */
  getAllClientsStatus(): ClientInstance[] {
    return Array.from(this.clients.values());
  }

  /**
   * 获取组状态
   */
  getGroupStatus(groupId: string): ClientGroup | undefined {
    return this.groups.get(groupId);
  }

  /**
   * 移除客户端
   */
  async removeClient(clientId: string): Promise<void> {
    const instance = this.clients.get(clientId);
    if (instance) {
      await instance.client.stop();
      this.clients.delete(clientId);
      
      // 从所有组中移除
      for (const group of this.groups.values()) {
        group.clientIds = group.clientIds.filter(id => id !== clientId);
      }
      
      console.log(`客户端已移除: ${clientId}`);
    }
  }

  /**
   * 停止所有客户端
   */
  async stopAllClients(): Promise<void> {
    for (const instance of this.clients.values()) {
      try {
        await instance.client.stop();
      } catch (error) {
        console.error(`停止客户端失败: ${instance.id}`, error);
      }
    }
    
    this.clients.clear();
    this.groups.clear();
    this.roundRobinIndex.clear();
    
    console.log('所有客户端已停止');
  }

  /**
   * 生成唯一ID
   */
  private generateId(): string {
    return `client-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
  }
}

// 导出单例实例
export const clientManager = new ClientManager();