/**
 * 交易所适配器工厂
 * 统一管理适配器的创建、配置和初始化
 */

import { ExchangeAdapter } from './ExchangeAdapter'
import { BinanceAdapter } from './binance/BinanceAdapter'
import { FutureConnector } from './binance/FutureConnector'
import { PacificaAdapter } from './pacifica/PacificaAdapter'
import { PacificaClient } from './pacifica/PacificaClient'
import { AsterExchangeAdapter } from './aster/AsterExchangeAdapter'
import { AsterAdapter } from './aster/asterAdapter'

export type SupportedExchange = 'binance' | 'pacifica' | 'aster'

export interface ExchangeConfig {
  exchange: SupportedExchange
  apiKey?: string
  apiSecret?: string
  baseUrl?: string
  wsUrl?: string
  privateKey?: string
  accountId?: string
  [key: string]: any
}

export interface AdapterFactoryResult {
  adapter: ExchangeAdapter
  config: ExchangeConfig
  initialized: boolean
}

export class AdapterFactory {
  private static instances = new Map<string, AdapterFactoryResult>()

  /**
   * 创建适配器实例
   */
  static async create(config: ExchangeConfig): Promise<AdapterFactoryResult> {
    const key = this.getInstanceKey(config)

    if (this.instances.has(key)) {
      return this.instances.get(key)!
    }

    const result = await this.createAdapter(config)
    this.instances.set(key, result)

    return result
  }

  /**
   * 从环境变量创建适配器
   */
  static async createFromEnv(exchange: SupportedExchange, accountId?: string): Promise<AdapterFactoryResult> {
    const config = this.loadConfigFromEnv(exchange, accountId)
    return this.create(config)
  }

  /**
   * 创建具体的适配器实例
   */
  private static async createAdapter(config: ExchangeConfig): Promise<AdapterFactoryResult> {
    let adapter: ExchangeAdapter
    let initialized = false

    try {
      switch (config.exchange) {
        case 'binance':
          adapter = await this.createBinanceAdapter(config)
          break
        case 'pacifica':
          adapter = await this.createPacificaAdapter(config)
          break
        case 'aster':
          adapter = await this.createAsterAdapter(config)
          break
        default:
          throw new Error(`不支持的交易所: ${config.exchange}`)
      }

      // 执行初始化测试
      initialized = await this.testAdapter(adapter, config.exchange)

      if (!initialized && config.exchange === 'pacifica') {
        // Pacifica 可能有网络问题，但仍然允许创建适配器
        console.warn(`⚠️ ${config.exchange} 适配器测试失败，但仍然创建实例`)
        initialized = true
      }

      return { adapter, config, initialized }
    } catch (error) {
      console.error(`❌ 创建 ${config.exchange} 适配器失败:`, error)

      // 对 Pacifica 的特殊处理
      if (config.exchange === 'pacifica' && error.message.includes('HTTP 500')) {
        console.warn(`⚠️ Pacifica 可能存在临时网络问题，跳过严格验证`)
        try {
          const adapter = await this.createPacificaAdapter(config)
          return { adapter, config, initialized: true }
        } catch (retryError) {
          console.error('❌ Pacifica 重试失败:', retryError)
        }
      }

      throw error
    }
  }

  /**
   * 创建币安适配器
   */
  private static async createBinanceAdapter(config: ExchangeConfig): Promise<BinanceAdapter> {
    if (!config.apiKey || !config.apiSecret) {
      throw new Error('Binance 适配器需要 apiKey 和 apiSecret')
    }

    const futureConnector = new FutureConnector(config.apiKey, config.apiSecret)
    return new BinanceAdapter(futureConnector)
  }

  /**
   * 创建Pacifica适配器
   */
  private static async createPacificaAdapter(config: ExchangeConfig): Promise<PacificaAdapter> {
    if (!config.privateKey || !config.accountId) {
      throw new Error('Pacifica 适配器需要 privateKey 和 accountId')
    }

    const client = new PacificaClient({
      baseUrl: config.baseUrl || 'https://api.pacifica.fi',
      wsUrl: config.wsUrl || 'wss://ws.pacifica.fi',
      account: config.accountId,
      privateKey: config.privateKey,
      agentWallet: config.agentWallet,
      agentPrivateKey: config.agentPrivateKey,
    })

    return new PacificaAdapter(client)
  }

  /**
   * 创建Aster适配器
   */
  private static async createAsterAdapter(config: ExchangeConfig): Promise<AsterExchangeAdapter> {
    if (!config.user || !config.signer || !config.privateKey) {
      throw new Error('Aster 适配器需要 user、signer 和 privateKey')
    }

    const asterConfig = {
      httpBase: config.baseUrl || 'https://fapi.asterdex.com',
      defaultUser: config.user,
      defaultSigner: config.signer,
      apiKey: config.apiKey,
      apiSecret: config.apiSecret,
    }

    const asterClient = new AsterAdapter(asterConfig)
    return new AsterExchangeAdapter(asterClient)
  }

  /**
   * 从环境变量加载配置
   */
  private static loadConfigFromEnv(exchange: SupportedExchange, accountId?: string): ExchangeConfig {
    switch (exchange) {
      case 'binance':
        return {
          exchange: 'binance',
          apiKey: process.env.BINANCE_API_KEY,
          apiSecret: process.env.BINANCE_SECRET_KEY,
        }

      case 'pacifica':
        return {
          exchange: 'pacifica',
          accountId: accountId || process.env.PACIFICA_ACCOUNT,
          privateKey: process.env.PACIFICA_ACCOUNT_PRIVATE_KEY || process.env.PACIFICA_PRIVATE_KEY,
          baseUrl: process.env.PACIFICA_BASE_URL,
          wsUrl: process.env.PACIFICA_WS_URL,
          agentWallet: process.env.PACIFICA_AGENT_WALLET,
          agentPrivateKey: process.env.PACIFICA_AGENT_PRIVATE_KEY,
        }

      case 'aster':
        return {
          exchange: 'aster',
          user: process.env.ASTER_ORDER_USER,
          signer: process.env.ASTER_ORDER_SIGNER || process.env.ASTER_API_KEY,
          privateKey: process.env.PRIVATE_KEY || process.env.PRIVATE_KEY2 || process.env.ASTER_API_SECRET,
          apiKey: process.env.ASTER_API_KEY,
          apiSecret: process.env.ASTER_API_SECRET,
          baseUrl: process.env.ASTER_HTTP_BASE,
        }

      default:
        throw new Error(`不支持的交易所: ${exchange}`)
    }
  }

  /**
   * 测试适配器基本功能
   */
  private static async testAdapter(adapter: ExchangeAdapter, exchange: string): Promise<boolean> {
    try {
      console.info(`🧪 测试 ${exchange} 适配器连接...`)

      // 基础连接测试
      const time = await adapter.time()
      if (!time || time <= 0) {
        console.warn(`⚠️ ${exchange} 时间同步测试失败`)
        return false
      }

      // 符号列表测试
      const symbols = await adapter.symbols()
      if (!Array.isArray(symbols)) {
        console.warn(`⚠️ ${exchange} 符号列表获取失败`)
        return false
      }

      console.info(`✅ ${exchange} 适配器测试通过 (获取到 ${symbols.length} 个交易对)`)
      return true
    } catch (error) {
      console.error(`❌ ${exchange} 适配器测试失败:`, error)
      return false
    }
  }

  /**
   * 生成实例缓存键
   */
  private static getInstanceKey(config: ExchangeConfig): string {
    const keyParts = [config.exchange]

    if (config.accountId) keyParts.push(config.accountId)
    if (config.user) keyParts.push(config.user)

    return keyParts.join('::')
  }

  /**
   * 清理所有适配器实例
   */
  static clearInstances(): void {
    this.instances.clear()
  }

  /**
   * 获取所有已创建的适配器
   */
  static getAllAdapters(): AdapterFactoryResult[] {
    return Array.from(this.instances.values())
  }

  /**
   * 健康检查所有适配器
   */
  static async healthCheck(): Promise<{ [exchange: string]: boolean }> {
    const results: { [exchange: string]: boolean } = {}

    for (const [key, { adapter, config }] of this.instances) {
      try {
        const isHealthy = await this.testAdapter(adapter, config.exchange)
        results[key] = isHealthy
      } catch {
        results[key] = false
      }
    }

    return results
  }
}
