/**
 * 平台检测服务
 *
 * 提供智能平台识别功能，使用多重检测器和置信度机制
 * 满足<1ms检测性能要求
 */

import { Platform, DetectionResult, Credentials, CredentialManagerError, ErrorType } from './types';

/**
 * 平台检测器接口
 */
export interface IPlatformDetector {
  /**
   * 检测置信度 (0-1)
   */
  readonly confidence: number;

  /**
   * 检测平台类型
   */
  detect(credentials: any): Platform | null;
}

/**
 * 平台检测服务接口
 */
export interface IPlatformDetectionService {
  registerDetector(detector: IPlatformDetector): void;
  detectPlatform(credentials: any): DetectionResult;
}

/**
 * 平台检测服务实现
 */
export class PlatformDetectionService implements IPlatformDetectionService {
  private detectors: IPlatformDetector[] = [];

  /**
   * 注册平台检测器
   */
  public registerDetector(detector: IPlatformDetector): void {
    if (!detector || typeof detector !== 'object') {
      throw new CredentialManagerError(
        'Detector must be a valid object',
        ErrorType.PLATFORM_DETECTION_ERROR,
        { detector }
      );
    }

    if (typeof detector.detect !== 'function') {
      throw new CredentialManagerError(
        'Detector must implement detect method',
        ErrorType.PLATFORM_DETECTION_ERROR,
        { detector }
      );
    }

    if (typeof detector.confidence !== 'number' || detector.confidence < 0 || detector.confidence > 1) {
      throw new CredentialManagerError(
        'Detector confidence must be a number between 0 and 1',
        ErrorType.PLATFORM_DETECTION_ERROR,
        { confidence: detector.confidence }
      );
    }

    // 按置信度从高到低排序插入
    const insertIndex = this.detectors.findIndex(d => d.confidence < detector.confidence);
    if (insertIndex === -1) {
      this.detectors.push(detector);
    } else {
      this.detectors.splice(insertIndex, 0, detector);
    }
  }

  /**
   * 检测平台类型
   */
  public detectPlatform(credentials: any): DetectionResult {
    const startTime = Date.now();
    const detectionResults: Array<{
      detector: string;
      platform: Platform | null;
      confidence: number;
    }> = [];

    let bestMatch: Platform | null = null;
    let bestConfidence = 0;

    // 遍历所有检测器
    for (const detector of this.detectors) {
      try {
        const detectedPlatform = detector.detect(credentials);

        detectionResults.push({
          detector: detector.constructor.name,
          platform: detectedPlatform,
          confidence: detector.confidence,
        });

        // 如果检测到平台且置信度更高，更新最佳匹配
        if (detectedPlatform && detector.confidence > bestConfidence) {
          bestMatch = detectedPlatform;
          bestConfidence = detector.confidence;
        }

      } catch (error) {
        // 记录检测器错误但继续其他检测器
        detectionResults.push({
          detector: detector.constructor.name,
          platform: null,
          confidence: 0,
        });
      }
    }

    const detectionTime = Date.now() - startTime;

    // 确保检测时间满足性能要求 (<1ms)
    if (detectionTime >= 1) {
      console.warn(`Platform detection took ${detectionTime}ms, exceeding 1ms requirement`);
    }

    return {
      platform: bestMatch,
      confidence: bestConfidence,
      detectors: detectionResults,
    };
  }

  /**
   * 获取已注册的检测器数量
   */
  public getDetectorCount(): number {
    return this.detectors.length;
  }

  /**
   * 清除所有检测器
   */
  public clearDetectors(): void {
    this.detectors = [];
  }

  /**
   * 获取检测器列表
   */
  public getDetectors(): Array<{ name: string; confidence: number }> {
    return this.detectors.map(detector => ({
      name: detector.constructor.name,
      confidence: detector.confidence,
    }));
  }
}

/**
 * 抽象检测器基类
 */
export abstract class BaseDetector implements IPlatformDetector {
  public abstract readonly confidence: number;

  public abstract detect(credentials: any): Platform | null;

  /**
   * 辅助方法：检查对象是否有指定属性
   */
  protected hasProperty(obj: any, property: string): boolean {
    return obj && typeof obj === 'object' && obj.hasOwnProperty(property);
  }

  /**
   * 辅助方法：检查字符串是否匹配正则表达式
   */
  protected matchesPattern(value: any, pattern: RegExp): boolean {
    return typeof value === 'string' && pattern.test(value);
  }

  /**
   * 辅助方法：检查是否为非空字符串
   */
  protected isNonEmptyString(value: any): boolean {
    return typeof value === 'string' && value.trim().length > 0;
  }
}

/**
 * 通用平台检测器（作为示例和后备）
 */
export class GenericDetector extends BaseDetector {
  public readonly confidence = 0.1; // 最低置信度

  public detect(credentials: any): Platform | null {
    if (!credentials || typeof credentials !== 'object') {
      return null;
    }

    // 基于type字段的简单检测
    if (this.hasProperty(credentials, 'type')) {
      const type = credentials.type.toLowerCase();

      switch (type) {
        case 'pacifica':
          return Platform.PACIFICA;
        case 'aster':
          return Platform.ASTER;
        case 'binance':
          return Platform.BINANCE;
        default:
          return null;
      }
    }

    return null;
  }
}

/**
 * 复合检测器（组合多个检测器的结果）
 */
export class CompositeDetector extends BaseDetector {
  public readonly confidence = 0.95;
  private detectors: IPlatformDetector[] = [];

  constructor(detectors: IPlatformDetector[]) {
    super();
    this.detectors = detectors.sort((a, b) => b.confidence - a.confidence);
  }

  public detect(credentials: any): Platform | null {
    const results = new Map<Platform, number>();

    for (const detector of this.detectors) {
      try {
        const platform = detector.detect(credentials);
        if (platform) {
          const currentScore = results.get(platform) || 0;
          results.set(platform, currentScore + detector.confidence);
        }
      } catch (error) {
        // 忽略单个检测器的错误
        continue;
      }
    }

    if (results.size === 0) {
      return null;
    }

    // 返回得分最高的平台
    let bestPlatform: Platform | null = null;
    let bestScore = 0;

    for (const [platform, score] of results) {
      if (score > bestScore) {
        bestPlatform = platform;
        bestScore = score;
      }
    }

    return bestPlatform;
  }
}

/**
 * 创建默认的平台检测服务
 */
export function createDefaultPlatformDetectionService(): PlatformDetectionService {
  const service = new PlatformDetectionService();

  // 注册通用检测器作为后备
  service.registerDetector(new GenericDetector());

  return service;
}

/**
 * 平台检测工具函数
 */
export class PlatformDetectionUtils {
  /**
   * 快速检测平台（单次检测）
   */
  public static quickDetect(credentials: Credentials): Platform | null {
    if (!credentials || typeof credentials !== 'object') {
      return null;
    }

    // 基于凭证类型直接映射
    switch (credentials.type) {
      case 'pacifica':
        return Platform.PACIFICA;
      case 'aster':
        return Platform.ASTER;
      case 'binance':
        return Platform.BINANCE;
      default:
        return null;
    }
  }

  /**
   * 验证平台与凭证是否匹配
   */
  public static validatePlatformMatch(platform: Platform, credentials: Credentials): boolean {
    const expectedType = platform.toLowerCase();
    return credentials.type === expectedType;
  }

  /**
   * 获取平台支持的凭证类型
   */
  public static getSupportedCredentialTypes(platform: Platform): string[] {
    switch (platform) {
      case Platform.PACIFICA:
        return ['pacifica'];
      case Platform.ASTER:
        return ['aster'];
      case Platform.BINANCE:
        return ['binance'];
      default:
        return [];
    }
  }
}