/**
 * 统一多平台多账户管理器
 * 集成 AdapterFactory 和 UnifiedHedgingExecutor，提供完整的多账户交易解决方案
 */

import { EventEmitter } from 'events'
import { ExchangeAdapter, Order, Position, Balance } from '../exchanges/ExchangeAdapter'
import { AdapterFactory, ExchangeConfig } from '../exchanges/AdapterFactory'
import { UnifiedHedgingExecutor, ExecutionConfig, AdapterPair } from '../core/hedging/UnifiedHedgingExecutor'
import { PrecisionValidator, ExchangeSymbolInfo } from '../utils/precision'
import { AccountManager } from './accountManager'

export interface AccountConfig extends ExchangeConfig {
  alias?: string // 账户别名
  enabled: boolean // 是否启用
  priority: number // 优先级 (1-10, 数字越小优先级越高)
  tradingEnabled: boolean // 是否允许交易
  hedgingEnabled: boolean // 是否允许参与对冲
  maxPositionUsd: number // 最大仓位限制 (USD)
  maxDailyVolumeUsd: number // 最大日交易量限制 (USD)
}

export interface AccountSummary {
  accountKey: string
  exchange: string
  accountId: string
  alias?: string
  status: 'online' | 'offline' | 'error'
  balances: Balance[]
  positions: Position[]
  totalEquityUsd: number
  dailyVolumeUsd: number
  openOrders: number
  lastUpdateTime: number
  error?: string
}

export interface HedgingGroup {
  name: string
  accounts: string[] // 账户键列表
  strategy: 'delta_neutral' | 'arbitrage' | 'funding_rate'
  maxExposureUsd: number
  enabled: boolean
}

export interface TradingRule {
  name: string
  accounts: string[] // 应用的账户
  symbols: string[] // 应用的交易对
  maxOrderSizeUsd: number
  minOrderSizeUsd: number
  maxSlippage: number
  cooldownMs: number
  enabled: boolean
}

export class UnifiedAccountManager extends EventEmitter {
  private accountManager: AccountManager
  private hedgingExecutor: UnifiedHedgingExecutor
  private accountConfigs = new Map<string, AccountConfig>()
  private accountSummaries = new Map<string, AccountSummary>()
  private hedgingGroups = new Map<string, HedgingGroup>()
  private tradingRules: TradingRule[] = []
  private healthCheckInterval?: NodeJS.Timer
  private dailyVolumeTracking = new Map<string, { date: string; volume: number }>()

  constructor(executionConfig: ExecutionConfig = { enableFailover: true, maxRetries: 3, retryDelayMs: 1000 }) {
    super()
    this.accountManager = new AccountManager()
    this.hedgingExecutor = new UnifiedHedgingExecutor(executionConfig)

    // 转发账户管理器事件
    this.accountManager.ws().on('am:*', data => {
      this.emit('account_event', data)
    })

    // 转发对冲执行器事件
    this.hedgingExecutor.on('execution_completed', exec => {
      this.emit('hedge_completed', exec)
      this.updateDailyVolume(exec)
    })

    this.startHealthMonitoring()
  }

  /**
   * 从配置文件批量注册账户
   */
  async registerAccountsFromConfig(configs: AccountConfig[]): Promise<void> {
    console.info(`📝 批量注册 ${configs.length} 个账户...`)

    const results = await Promise.allSettled(configs.map(config => this.registerAccount(config)))

    const successful = results.filter(r => r.status === 'fulfilled').length
    const failed = results.filter(r => r.status === 'rejected').length

    console.info(`✅ 账户注册完成: 成功 ${successful}, 失败 ${failed}`)

    if (failed > 0) {
      const errors = results.filter((r): r is PromiseRejectedResult => r.status === 'rejected').map(r => r.reason)
      console.error('❌ 注册失败的账户:', errors)
    }
  }

  /**
   * 注册单个账户
   */
  async registerAccount(config: AccountConfig): Promise<void> {
    const accountKey = `${config.exchange}::${config.accountId || 'default'}`

    try {
      // 1. 创建适配器（从环境变量）
      const adapterResult = await AdapterFactory.createFromEnv(config.exchange as any, config.accountId)

      if (!adapterResult.initialized) {
        throw new Error(`适配器初始化失败: ${config.exchange}`)
      }

      // 2. 注册到账户管理器
      this.accountManager.register({
        exchange: config.exchange,
        accountId: config.accountId || 'default',
        adapter: adapterResult.adapter,
        meta: {
          alias: config.alias,
          priority: config.priority,
          tradingEnabled: config.tradingEnabled,
          hedgingEnabled: config.hedgingEnabled,
        },
      })

      // 3. 存储配置
      this.accountConfigs.set(accountKey, config)

      // 4. 初始化账户摘要
      await this.refreshAccountSummary(accountKey)

      // 5. 获取并更新精度配置
      await this.updatePrecisionConfig(config.exchange, adapterResult.adapter)

      console.info(`✅ 账户注册成功: ${accountKey} (${config.alias || config.exchange})`)
      this.emit('account_registered', { accountKey, config })
    } catch (error) {
      console.error(`❌ 账户注册失败: ${accountKey}`, error)
      this.emit('account_register_failed', { accountKey, config, error })
      throw error
    }
  }

  /**
   * 卸载账户
   */
  async unregisterAccount(accountKey: string): Promise<void> {
    const [exchange, accountId] = accountKey.split('::')

    this.accountManager.unregister(exchange, accountId)
    this.accountConfigs.delete(accountKey)
    this.accountSummaries.delete(accountKey)
    this.dailyVolumeTracking.delete(accountKey)

    console.info(`🗑️ 账户已卸载: ${accountKey}`)
    this.emit('account_unregistered', { accountKey })
  }

  /**
   * 获取所有账户摘要
   */
  async getAllAccountSummaries(refresh = false): Promise<AccountSummary[]> {
    if (refresh) {
      await Promise.all(
        Array.from(this.accountConfigs.keys()).map(
          key => this.refreshAccountSummary(key).catch(() => {}), // 忽略错误
        ),
      )
    }

    return Array.from(this.accountSummaries.values())
  }

  /**
   * 获取特定账户摘要
   */
  getAccountSummary(accountKey: string): AccountSummary | undefined {
    return this.accountSummaries.get(accountKey)
  }

  /**
   * 跨账户聚合余额
   */
  async getAggregatedBalances(): Promise<{
    [asset: string]: { total: number; accounts: Array<{ accountKey: string; amount: number }> }
  }> {
    const allBalances = await this.accountManager.balancesAll({ cacheMs: 30000 })
    const aggregated: { [asset: string]: { total: number; accounts: Array<{ accountKey: string; amount: number }> } } =
      {}

    for (const balance of allBalances) {
      const asset = balance.asset
      const accountKey = `${balance.exchange}::${balance.accountId}`
      const amount = parseFloat(balance.total)

      if (!aggregated[asset]) {
        aggregated[asset] = { total: 0, accounts: [] }
      }

      aggregated[asset].total += amount
      aggregated[asset].accounts.push({ accountKey, amount })
    }

    return aggregated
  }

  /**
   * 跨账户聚合仓位
   */
  async getAggregatedPositions(): Promise<{
    [symbol: string]: { netSize: number; accounts: Array<{ accountKey: string; size: number; side: string }> }
  }> {
    const allPositions = await this.accountManager.positionsAll({ cacheMs: 30000 })
    const aggregated: {
      [symbol: string]: { netSize: number; accounts: Array<{ accountKey: string; size: number; side: string }> }
    } = {}

    for (const position of allPositions) {
      const symbol = position.symbol
      const accountKey = `${position.exchange}::${position.accountId}`
      const size = parseFloat(position.qty)
      const sideMultiplier = position.side === 'LONG' ? 1 : -1
      const signedSize = size * sideMultiplier

      if (!aggregated[symbol]) {
        aggregated[symbol] = { netSize: 0, accounts: [] }
      }

      aggregated[symbol].netSize += signedSize
      aggregated[symbol].accounts.push({
        accountKey,
        size: signedSize,
        side: position.side,
      })
    }

    return aggregated
  }

  /**
   * 智能订单路由 - 选择最佳账户执行订单
   */
  async smartOrderRouting(
    symbol: string,
    side: 'BUY' | 'SELL',
    quantity: string,
    type: 'MARKET' | 'LIMIT' = 'MARKET',
    price?: string,
  ): Promise<{ accountKey: string; order: Order }> {
    // 1. 筛选可用账户
    const availableAccounts = await this.getAvailableAccountsForTrading(symbol)

    if (availableAccounts.length === 0) {
      throw new Error(`没有可用账户交易 ${symbol}`)
    }

    // 2. 根据优先级、余额、延迟等因素选择最佳账户
    const selectedAccount = this.selectOptimalAccount(availableAccounts, symbol, quantity)

    // 3. 执行订单
    const [exchange, accountId] = selectedAccount.split('::')
    const order = await this.accountManager.placeOrderOn(exchange, accountId, {
      symbol,
      side,
      type,
      quantity,
      price,
      clientOrderId: `smart_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
    })

    console.info(`🎯 智能路由执行: ${selectedAccount} - ${symbol} ${side} ${quantity}`)

    return { accountKey: selectedAccount, order }
  }

  /**
   * 创建对冲组
   */
  createHedgingGroup(group: HedgingGroup): void {
    // 验证账户存在
    for (const accountKey of group.accounts) {
      if (!this.accountConfigs.has(accountKey)) {
        throw new Error(`对冲组中的账户不存在: ${accountKey}`)
      }

      const config = this.accountConfigs.get(accountKey)!
      if (!config.hedgingEnabled) {
        throw new Error(`账户未启用对冲功能: ${accountKey}`)
      }
    }

    this.hedgingGroups.set(group.name, group)
    console.info(`🔗 对冲组已创建: ${group.name} (${group.accounts.length} 个账户)`)
    this.emit('hedging_group_created', group)
  }

  /**
   * 执行跨账户对冲
   */
  async executeHedging(groupName: string, symbol: string, targetExposure = 0): Promise<void> {
    const group = this.hedgingGroups.get(groupName)
    if (!group || !group.enabled) {
      throw new Error(`对冲组不存在或未启用: ${groupName}`)
    }

    // 获取当前净敞口
    const positions = await this.getAggregatedPositions()
    const currentExposure = positions[symbol]?.netSize || 0
    const hedgeAmount = targetExposure - currentExposure

    if (Math.abs(hedgeAmount) < 0.001) {
      console.info(`🎯 ${symbol} 净敞口已达到目标: ${currentExposure}`)
      return
    }

    console.info(
      `🔄 执行对冲: ${symbol}, 当前敞口: ${currentExposure}, 目标: ${targetExposure}, 对冲数量: ${hedgeAmount}`,
    )

    // 选择主账户和备用账户
    const primaryAccountKey = group.accounts[0] // 简化选择逻辑
    const secondaryAccountKey = group.accounts[1]

    const [primaryExchange, primaryAccountId] = primaryAccountKey.split('::')
    const primaryAdapter = this.accountManager.getAdapter(primaryExchange, primaryAccountId)

    let secondaryAdapter: ExchangeAdapter | undefined
    if (secondaryAccountKey) {
      const [secondaryExchange, secondaryAccountId] = secondaryAccountKey.split('::')
      secondaryAdapter = this.accountManager.getAdapter(secondaryExchange, secondaryAccountId)
    }

    if (!primaryAdapter) {
      throw new Error(`主账户适配器不可用: ${primaryAccountKey}`)
    }

    const adapterPair: AdapterPair = {
      primary: primaryAdapter,
      primaryId: primaryExchange,
      secondary: secondaryAdapter,
      secondaryId: secondaryAccountKey?.split('::')[0],
    }

    // 构造对冲请求
    const hedgeRequest = {
      symbol,
      perpPosition: {
        symbol,
        size: Math.abs(hedgeAmount),
        side: hedgeAmount > 0 ? 'long' : 'short',
        entryPrice: 0, // 简化
        unrealizedPnl: 0,
        isOpen: true,
      } as any,
      prices: {
        perpPrice: 50000, // 需要从市场数据获取
        hedgePrice: 50000,
        correlation: 1,
      },
      funding: { fundingRate: 0.0001 },
      config: {
        preferredMethod: 'spot' as const,
        thresholds: {
          maxSlippage: 0.005,
          deltaDeviationPct: 0.01,
          minFundingRate: 0.00001,
          minNotionalUSD: 10,
        },
      },
    }

    await this.hedgingExecutor.execute(hedgeRequest, adapterPair)
  }

  /**
   * 强制所有账户净零
   */
  async forceAllAccountsNetZero(): Promise<void> {
    const positions = await this.getAggregatedPositions()

    for (const [symbol, positionData] of Object.entries(positions)) {
      if (Math.abs(positionData.netSize) > 0.001) {
        console.info(`🎯 强制净零: ${symbol}, 净敞口: ${positionData.netSize}`)

        // 简化版：使用第一个可用账户
        const availableAccounts = await this.getAvailableAccountsForTrading(symbol)
        if (availableAccounts.length > 0) {
          const accountKey = availableAccounts[0]
          const [exchange, accountId] = accountKey.split('::')
          const adapter = this.accountManager.getAdapter(exchange, accountId)!

          const adapterPair: AdapterPair = {
            primary: adapter,
            primaryId: exchange,
          }

          await this.hedgingExecutor.forceNetZero(symbol, adapterPair)
        }
      }
    }
  }

  /**
   * 获取系统统计信息
   */
  getSystemStats() {
    const accounts = Array.from(this.accountSummaries.values())
    const onlineAccounts = accounts.filter(a => a.status === 'online')
    const totalEquity = accounts.reduce((sum, a) => sum + a.totalEquityUsd, 0)
    const totalDailyVolume = accounts.reduce((sum, a) => sum + a.dailyVolumeUsd, 0)
    const hedgingStats = this.hedgingExecutor.getExecutionStats()

    return {
      accounts: {
        total: accounts.length,
        online: onlineAccounts.length,
        offline: accounts.filter(a => a.status === 'offline').length,
        error: accounts.filter(a => a.status === 'error').length,
      },
      equity: {
        totalUsd: totalEquity,
        byExchange: this.groupBy(accounts, 'exchange', a => a.totalEquityUsd),
      },
      volume: {
        totalDailyUsd: totalDailyVolume,
        byExchange: this.groupBy(accounts, 'exchange', a => a.dailyVolumeUsd),
      },
      hedging: hedgingStats,
      hedgingGroups: this.hedgingGroups.size,
    }
  }

  // ========== 私有方法 ==========

  private async refreshAccountSummary(accountKey: string): Promise<void> {
    const config = this.accountConfigs.get(accountKey)
    if (!config) return

    const [exchange, accountId] = accountKey.split('::')

    try {
      const adapter = this.accountManager.getAdapter(exchange, accountId)
      if (!adapter) {
        throw new Error('适配器不可用')
      }

      const [balances, positions] = await Promise.all([
        adapter.balances().catch(() => []),
        adapter.positions().catch(() => []),
      ])

      const totalEquityUsd = this.calculateTotalEquity(balances, positions)
      const dailyVolume = this.getDailyVolume(accountKey)

      const summary: AccountSummary = {
        accountKey,
        exchange,
        accountId,
        alias: config.alias,
        status: 'online',
        balances,
        positions,
        totalEquityUsd,
        dailyVolumeUsd: dailyVolume,
        openOrders: 0, // 需要实现
        lastUpdateTime: Date.now(),
      }

      this.accountSummaries.set(accountKey, summary)
      this.emit('account_summary_updated', summary)
    } catch (error) {
      const errorSummary: AccountSummary = {
        accountKey,
        exchange,
        accountId: accountId,
        alias: config.alias,
        status: 'error',
        balances: [],
        positions: [],
        totalEquityUsd: 0,
        dailyVolumeUsd: 0,
        openOrders: 0,
        lastUpdateTime: Date.now(),
        error: (error as Error).message,
      }

      this.accountSummaries.set(accountKey, errorSummary)
      this.emit('account_summary_error', errorSummary)
    }
  }

  private async updatePrecisionConfig(exchange: string, adapter: ExchangeAdapter): Promise<void> {
    try {
      const symbols = await adapter.symbols()

      // 模拟精度配置（实际应从交易所API获取）
      const mockConfigs: ExchangeSymbolInfo[] = symbols.slice(0, 10).map(symbol => ({
        symbol,
        status: 'TRADING',
        baseAsset: symbol.replace(/USDT$|USD$/, ''),
        quoteAsset: 'USDT',
        precision: {
          tickSize: '0.01',
          stepSize: '0.00001',
          minQty: '0.00001',
          maxQty: '1000',
          minNotional: '10',
        },
      }))

      PrecisionValidator.updateExchangeConfig(exchange, mockConfigs)
      console.info(`📏 精度配置已更新: ${exchange} (${mockConfigs.length} 个交易对)`)
    } catch (error) {
      console.warn(`⚠️ 精度配置更新失败: ${exchange}`, error)
    }
  }

  private async getAvailableAccountsForTrading(_symbol: string): Promise<string[]> {
    const available: string[] = []

    for (const [accountKey, config] of this.accountConfigs) {
      if (!config.enabled || !config.tradingEnabled) continue

      const summary = this.accountSummaries.get(accountKey)
      if (!summary || summary.status !== 'online') continue

      // 检查日交易量限制
      if (summary.dailyVolumeUsd >= config.maxDailyVolumeUsd) continue

      available.push(accountKey)
    }

    return available
  }

  private selectOptimalAccount(accounts: string[], _symbol: string, _quantity: string): string {
    // 简化选择逻辑：选择优先级最高的账户
    let bestAccount = accounts[0]
    let bestPriority = Number.MAX_SAFE_INTEGER

    for (const accountKey of accounts) {
      const config = this.accountConfigs.get(accountKey)
      if (config && config.priority < bestPriority) {
        bestPriority = config.priority
        bestAccount = accountKey
      }
    }

    return bestAccount
  }

  private calculateTotalEquity(balances: Balance[], positions: Position[]): number {
    // 简化计算：假设所有资产以USD计价
    let total = 0

    for (const balance of balances) {
      total += parseFloat(balance.total) || 0
    }

    for (const position of positions) {
      total += parseFloat(position.unrealizedPnl) || 0
    }

    return total
  }

  private getDailyVolume(accountKey: string): number {
    const today = new Date().toISOString().split('T')[0]
    const tracking = this.dailyVolumeTracking.get(accountKey)

    if (tracking && tracking.date === today) {
      return tracking.volume
    }

    return 0
  }

  private updateDailyVolume(execution: any): void {
    // 从执行结果更新日交易量
    if (!execution.primaryOrder) return

    const today = new Date().toISOString().split('T')[0]
    const accountKey = `${execution.request.exchange || 'unknown'}::${execution.request.accountId || 'default'}`
    const volume = parseFloat(execution.primaryOrder.origQty) * parseFloat(execution.primaryOrder.price || '0')

    const current = this.dailyVolumeTracking.get(accountKey)
    if (current && current.date === today) {
      current.volume += volume
    } else {
      this.dailyVolumeTracking.set(accountKey, { date: today, volume })
    }
  }

  private startHealthMonitoring(): void {
    this.healthCheckInterval = setInterval(async () => {
      for (const accountKey of this.accountConfigs.keys()) {
        await this.refreshAccountSummary(accountKey)
      }
    }, 60000) // 每分钟检查一次
  }

  private groupBy<T>(array: T[], key: keyof T, valueExtractor: (item: T) => number): { [key: string]: number } {
    const result: { [key: string]: number } = {}
    for (const item of array) {
      const groupKey = String(item[key])
      result[groupKey] = (result[groupKey] || 0) + valueExtractor(item)
    }
    return result
  }

  /**
   * 清理资源
   */
  destroy(): void {
    if (this.healthCheckInterval) {
      clearInterval(this.healthCheckInterval)
    }

    this.accountManager = null as any
    this.hedgingExecutor = null as any
  }
}
