/**
 * 云服务器控制四层架构统一接口定义
 * 根据文档 ARCHIVE/01_Architecture/12_Operation_Agent.md 规范实现
 * 
 * 四层架构：
 * 1. API模拟层 - 主要方案
 * 2. WEB远程控制层 - 中间层
 * 3. 远程桌面层 - 第一层兜底
 * 4. 云服务商API层 - 第二层兜底
 */

// 统一控制命令接口
export interface ControlCommand {
  type: 'api' | 'web' | 'desktop' | 'cloud';
  target: string;
  action: string;
  parameters: Record<string, unknown>;
  priority: 'high' | 'medium' | 'low';
  timeout?: number;
}

// 统一控制结果接口
export interface ControlResult {
  success: boolean;
  data?: unknown;
  error?: string;
  layerUsed: string;
  duration: number;
  timestamp: number;
}

// 层级状态接口
export interface LayerStatus {
  layer: string;
  available: boolean;
  latency: number;
  lastUsed: number;
  errorCount: number;
  successRate: number;
}

// 四层架构统一接口
export interface ICloudControlLayer {
  /**
   * 连接控制层
   */
  connect(): Promise<boolean>;
  
  /**
   * 执行控制命令
   */
  execute(command: ControlCommand): Promise<ControlResult>;
  
  /**
   * 断开连接
   */
  disconnect(): Promise<void>;
  
  /**
   * 获取层级状态
   */
  getStatus(): Promise<LayerStatus>;
  
  /**
   * 检查是否可用
   */
  isAvailable(): boolean;
}

// 四层架构管理器
export class CloudControlLayerManager {
  private layers: Map<string, ICloudControlLayer> = new Map();
  private currentLayer: string = 'api';
  
  /**
   * 注册控制层
   */
  registerLayer(name: string, layer: ICloudControlLayer): void {
    this.layers.set(name, layer);
  }
  
  /**
   * 执行命令（自动故障转移）
   */
  async execute(command: ControlCommand): Promise<ControlResult> {
    const layers = this.getAvailableLayers();
    
    for (const layerName of layers) {
      const layer = this.layers.get(layerName);
      if (!layer || !layer.isAvailable()) continue;
      
      try {
        const startTime = Date.now();
        const result = await layer.execute(command);
        const duration = Date.now() - startTime;
        
        return {
          ...result,
          layerUsed: layerName,
          duration
        };
      } catch (error) {
        console.warn(`Layer ${layerName} failed:`, error);
        continue;
      }
    }
    
    throw new Error('All control layers failed');
  }
  
  /**
   * 获取可用层级列表（按优先级排序）
   */
  private getAvailableLayers(): string[] {
    const priorityOrder = ['api', 'web', 'desktop', 'cloud'];
    return priorityOrder.filter(layerName => {
      const layer = this.layers.get(layerName);
      return layer && layer.isAvailable();
    });
  }
  
  /**
   * 获取所有层级状态
   */
  async getAllStatus(): Promise<LayerStatus[]> {
    const statuses: LayerStatus[] = [];
    
    for (const [layerName, layer] of this.layers) {
      try {
        const status = await layer.getStatus();
        statuses.push(status);
      } catch (error) {
        statuses.push({
          layer: layerName,
          available: false,
          latency: -1,
          lastUsed: 0,
          errorCount: 1,
          successRate: 0
        });
      }
    }
    
    return statuses;
  }
}

// 具体层级实现基类
export abstract class BaseControlLayer implements ICloudControlLayer {
  protected connected: boolean = false;
  protected errorCount: number = 0;
  protected successCount: number = 0;
  protected lastUsed: number = 0;
  
  abstract connect(): Promise<boolean>;
  abstract execute(command: ControlCommand): Promise<ControlResult>;
  abstract disconnect(): Promise<void>;
  
  async getStatus(): Promise<LayerStatus> {
    const total = this.errorCount + this.successCount;
    const successRate = total > 0 ? this.successCount / total : 0;
    
    return {
      layer: this.constructor.name,
      available: this.isAvailable(),
      latency: await this.getLatency(),
      lastUsed: this.lastUsed,
      errorCount: this.errorCount,
      successRate
    };
  }
  
  isAvailable(): boolean {
    return this.connected && this.errorCount < 10;
  }
  
  protected async getLatency(): Promise<number> {
    // 默认实现，子类可以重写
    return 100;
  }
  
  protected recordSuccess(): void {
    this.successCount++;
    this.lastUsed = Date.now();
  }
  
  protected recordError(): void {
    this.errorCount++;
  }
}

// 错误处理类
export class CloudControlError extends Error {
  constructor(
    public layer: string,
    public operation: string,
    public originalError?: Error
  ) {
    super(`[${layer}] ${operation} failed`);
    this.name = 'CloudControlError';
  }
}