import { logger } from '../../utils/logger';

/**
 * [BE-P101] 采集器基类
 * 定义所有平台采集器的通用接口和行为
 */

// 采集结果
export interface CollectionResult {
  success: boolean;
  data?: any;
  error?: string;
  metadata: {
    platform: string;
    url: string;
    timestamp: string;
    duration: number;
  };
}

// 采集配置
export interface CollectorConfig {
  platform: string;
  timeout?: number;
  retries?: number;
  useProxy?: boolean;
  proxyConfig?: {
    host: string;
    port: number;
    username?: string;
    password?: string;
  };
  headers?: Record<string, string>;
}

// 采集器接口
export interface ICollector {
  collect(url: string): Promise<CollectionResult>;
  validateUrl(url: string): boolean;
  parseData(rawData: any): any;
}

export abstract class BaseCollector implements ICollector {
  protected config: CollectorConfig;

  constructor(config: CollectorConfig) {
    this.config = {
      timeout: 30000,
      retries: 3,
      useProxy: false,
      ...config,
    };
  }

  /**
   * 执行采集
   */
  abstract collect(url: string): Promise<CollectionResult>;

  /**
   * 验证URL是否属于该平台
   */
  abstract validateUrl(url: string): boolean;

  /**
   * 解析原始数据为标准格式
   */
  abstract parseData(rawData: any): any;

  /**
   * 记录采集日志
   */
  protected log(
    operation: string,
    details: {
      url?: string;
      success?: boolean;
      error?: string;
      duration?: number;
    }
  ): void {
    logger.info(`[${this.config.platform}Collector] ${operation}`, {
      platform: this.config.platform,
      ...details,
    });
  }

  /**
   * 延迟函数
   */
  protected async delay(ms: number): Promise<void> {
    return new Promise((resolve) => setTimeout(resolve, ms));
  }

  /**
   * 重试机制
   */
  protected async retry<T>(
    fn: () => Promise<T>,
    retries: number = this.config.retries || 3
  ): Promise<T> {
    let lastError: Error | undefined;

    for (let i = 0; i < retries; i++) {
      try {
        return await fn();
      } catch (error) {
        lastError = error instanceof Error ? error : new Error(String(error));
        logger.info(`[${this.config.platform}Collector] RETRY_ATTEMPT`, {
          platform: this.config.platform,
          attempt: i + 1,
          maxRetries: retries,
          error: lastError.message,
        });

        if (i < retries - 1) {
          // 指数退避
          await this.delay(Math.pow(2, i) * 1000);
        }
      }
    }

    throw lastError;
  }

  /**
   * 创建成功结果
   */
  protected createSuccessResult(
    url: string,
    data: any,
    duration: number
  ): CollectionResult {
    return {
      success: true,
      data,
      metadata: {
        platform: this.config.platform,
        url,
        timestamp: new Date().toISOString(),
        duration,
      },
    };
  }

  /**
   * 创建失败结果
   */
  protected createErrorResult(url: string, error: string, duration: number): CollectionResult {
    return {
      success: false,
      error,
      metadata: {
        platform: this.config.platform,
        url,
        timestamp: new Date().toISOString(),
        duration,
      },
    };
  }
}
