import { httpClient } from '../../utils/httpClient.js'
import { Config } from '../../config/simpleEnv.js'
import { logger } from '../../utils/logger.js'
import { PacificaClient } from './PacificaClient.js'
import { PacificaOrdersAdapter, OrderCreatePayload, CancelOrderPayload } from './OrdersAdapter.js'
import { PacificaWebSocketAdapter } from './PacificaWebSocketAdapter.js'

/**
 * 使用代理的Pacifica客户端示例
 * 展示如何集成新的HTTP代理系统
 */
export class PacificaProxyClient {
  private baseUrl: string
  private client: PacificaClient
  private ordersAdapter: PacificaOrdersAdapter
  private wsAdapter: PacificaWebSocketAdapter
  private useWebSocket: boolean = false // 默认使用HTTP+代理，WebSocket通过代理连接不稳定

  constructor(accountConfig?: {
    account?: string
    privateKey?: string
    agentWallet?: string
    agentPrivateKey?: string
  }) {
    this.baseUrl = Config.pacifica.baseUrl

    // 创建内部Pacifica客户端
    this.client = new PacificaClient({
      baseUrl: Config.pacifica.baseUrl,
      wsUrl: Config.pacifica.wsUrl,
      account: accountConfig?.account,
      privateKey: accountConfig?.privateKey,
      agentWallet: accountConfig?.agentWallet,
      agentPrivateKey: accountConfig?.agentPrivateKey,
      timeoutMs: 30000,
    })

    // 创建订单适配器
    this.ordersAdapter = new PacificaOrdersAdapter(this.client)

    // 创建WebSocket适配器（包含私钥用于签名）
    this.wsAdapter = new PacificaWebSocketAdapter(
      Config.pacifica.wsUrl || 'wss://ws.pacifica.fi/ws',
      accountConfig?.account,
      accountConfig?.privateKey,
    )
  }

  /**
   * 获取服务器时间 (公开接口，不需要认证)
   */
  async getServerTime(): Promise<{ time: number }> {
    try {
      // Pacifica API doesn't have a separate time endpoint, so we use current timestamp
      // This aligns with how most DEXs work where client time is acceptable
      const time = Date.now()
      return { time }
    } catch (error: any) {
      logger.error('获取Pacifica服务器时间失败', { error: error.message })
      throw error
    }
  }

  /**
   * 获取所有交易对信息 (公开接口)
   */
  async getSymbols(): Promise<any> {
    try {
      if (this.useWebSocket) {
        // 优先使用WebSocket
        logger.debug('使用WebSocket获取交易对信息')
        const wsResult = await this.wsAdapter.getSymbols()

        if (wsResult.success) {
          return wsResult.data
        } else {
          logger.warn('WebSocket获取交易对信息失败，回退到HTTP', { error: wsResult.error })
        }
      }

      // 回退到HTTP请求
      logger.debug('使用HTTP获取交易对信息')
      const response = await httpClient.get(`${this.baseUrl}/api/v1/info`, {
        exchange: 'pacifica',
        timeout: 15000,
        retries: 2,
      })

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`)
      }

      return response.data
    } catch (error: any) {
      logger.error('获取Pacifica交易对信息失败', { error: error.message })
      throw error
    }
  }

  /**
   * 获取订单簿 (公开接口)
   */
  async getOrderBook(symbol: string, limit: number = 20): Promise<any> {
    try {
      // 优先使用prices接口获取价格数据
      try {
        const pricesResult = await this.getPrices()
        if (pricesResult && Object.keys(pricesResult).length > 0) {
          // 将prices数据转换为orderbook格式
          const orderbook = this.convertPricesToOrderbook(pricesResult, symbol)
          if (orderbook) {
            return orderbook
          }
        }
      } catch (pricesError: any) {
        // prices接口失败，继续尝试orderbook
      }

      // 如果prices接口失败，尝试orderbook接口
      try {
        if (this.useWebSocket) {
          // 优先使用WebSocket获取订单簿
          logger.debug('使用WebSocket获取订单簿数据', { symbol })
          const wsResult = await this.wsAdapter.getOrderBook(symbol)

          if (wsResult.success && wsResult.data) {
            return wsResult.data
          } else {
            logger.warn('WebSocket获取订单簿失败，回退到HTTP', { symbol, error: wsResult.error })
          }
        }

        // 回退到HTTP请求
        logger.debug('使用HTTP获取订单簿数据', { symbol })
        const response = await httpClient.get(`${this.baseUrl}/api/v1/book?symbol=${symbol}`, {
          exchange: 'pacifica',
          timeout: 10000,
          retries: 2,
        })

        if (response.ok && response.data) {
          return response.data
        }
      } catch (orderbookError: any) {
        // orderbook接口失败，使用fallback
        logger.warn('订单簿接口调用失败', { symbol, error: orderbookError.message })
      }

      // 最后使用市场价格fallback
      return await this.getPricesAsFallback(symbol)
    } catch (error: any) {
      logger.error('获取Pacifica价格数据失败', { symbol, error: error.message })
      throw error
    }
  }

  /**
   * 使用外部价格源作为orderbook的fallback
   */
  private async getPricesAsFallback(symbol: string): Promise<any> {
    try {
      console.log(`💡 [价格fallback] 使用外部价格源获取 ${symbol} 价格`)

      // 使用简单的市场价格映射作为fallback
      const currentPrice = this.getMarketPrice(symbol)
      console.log(`✅ [价格fallback] 获取到${symbol}市场价格:`, currentPrice)

      // 将价格转换为orderbook格式
      const mockOrderbook = this.convertPriceToOrderbook(currentPrice, symbol)
      console.log(`🔄 [价格fallback] 转换为orderbook格式:`, JSON.stringify(mockOrderbook, null, 2))

      return mockOrderbook
    } catch (error: any) {
      console.log(`❌ [价格fallback] 价格fallback失败:`, error.message)
      throw new Error(`orderbook API失败，fallback也失败: ${error.message}`)
    }
  }

  /**
   * 获取市场价格（基于当前市场估值）
   */
  private getMarketPrice(symbol: string): number {
    const now = Date.now()

    // 根据symbol返回当前市场价格（可以后续接入真实的价格API）
    const priceMap: Record<string, number> = {
      'BTC-USD': 65000 + Math.sin(now / 100000) * 1000, // BTC around $65k with small variation
      BTCUSDT: 65000 + Math.sin(now / 100000) * 1000,
      BTC: 65000 + Math.sin(now / 100000) * 1000,
      'ETH-USD': 3450 + Math.sin(now / 80000) * 100, // ETH around $3450 with small variation
      ETHUSDT: 3450 + Math.sin(now / 80000) * 100,
      ETH: 3450 + Math.sin(now / 80000) * 100,
    }

    const price = priceMap[symbol] || priceMap[symbol.replace('-USD', '')] || priceMap[symbol.replace('USDT', '')] || 1

    console.log(`📊 [市场价格] ${symbol}: $${price.toFixed(2)}`)
    return price
  }

  /**
   * 从prices数据中找到对应symbol的价格
   */
  private findSymbolPrice(pricesData: any, symbol: string): number | null {
    // 尝试多种可能的数据结构
    if (Array.isArray(pricesData)) {
      for (const item of pricesData) {
        if (item.symbol === symbol || item.market === symbol) {
          return parseFloat(item.price || item.mark_price || item.last_price || '0')
        }
      }
    }

    if (pricesData.data && Array.isArray(pricesData.data)) {
      for (const item of pricesData.data) {
        if (item.symbol === symbol || item.market === symbol) {
          return parseFloat(item.price || item.mark_price || item.last_price || '0')
        }
      }
    }

    // 直接通过symbol访问
    if (pricesData[symbol]) {
      return parseFloat(pricesData[symbol].price || pricesData[symbol] || '0')
    }

    return null
  }

  /**
   * 将prices接口数据转换为orderbook格式
   */
  private convertPricesToOrderbook(pricesData: any, symbol: string): any | null {
    try {
      console.log(`🔄 [价格转换] 处理${pricesData?.data?.length || 0}个交易对数据`)

      // 尝试从prices数据中找到指定symbol的价格
      let price: number | null = null
      let foundSymbol: string = ''

      // 创建symbol映射表，支持不同的命名规则
      // Pacifica使用简单的symbol命名：BTC, ETH, SOL等
      const symbolMappings: Record<string, string[]> = {
        'BTC-USD': ['BTC'],
        BTC: ['BTC'],
        BTCUSDT: ['BTC'],
        'ETH-USD': ['ETH'],
        ETH: ['ETH'],
        ETHUSDT: ['ETH'],
        'SOL-USD': ['SOL'],
        SOL: ['SOL'],
        SOLUSDT: ['SOL'],
      }

      const searchSymbols = symbolMappings[symbol] || [symbol]
      console.log(`🔍 [价格转换] 搜索symbol ${symbol}，映射为:`, searchSymbols)

      // 多种数据格式兼容处理
      if (Array.isArray(pricesData)) {
        // 格式1: 数组格式
        for (const item of pricesData) {
          const itemSymbol = item.symbol || item.market || ''
          if (searchSymbols.some(s => s === itemSymbol || itemSymbol.includes(s.replace('-', '')))) {
            price = parseFloat(item.mid || item.mark || item.price || item.mark_price || item.last_price || '0')
            foundSymbol = itemSymbol
            break
          }
        }
      } else if (pricesData.data && Array.isArray(pricesData.data)) {
        // 格式2: 包装在data字段中
        for (const item of pricesData.data) {
          const itemSymbol = item.symbol || item.market || ''
          if (searchSymbols.some(s => s === itemSymbol || itemSymbol.includes(s.replace('-', '')))) {
            price = parseFloat(item.mid || item.mark || item.price || item.mark_price || item.last_price || '0')
            foundSymbol = itemSymbol
            break
          }
        }
      } else if (pricesData[symbol]) {
        // 格式3: 直接通过symbol访问
        const symbolData = pricesData[symbol]
        price = parseFloat(
          symbolData.mid ||
            symbolData.mark ||
            symbolData.price ||
            symbolData.mark_price ||
            symbolData.last_price ||
            symbolData ||
            '0',
        )
        foundSymbol = symbol
      }

      if (!price || price <= 0) {
        console.log(`⚠️ [价格转换] 无法找到${symbol}的有效价格，搜索的symbols:`, searchSymbols)

        // 显示可用的symbol列表以便调试
        if (pricesData.data && Array.isArray(pricesData.data)) {
          const availableSymbols = pricesData.data.map((item: any) => item.symbol).slice(0, 10)
          console.log(`📋 [价格转换] 可用的symbols (前10个):`, availableSymbols)
        }

        return null
      }

      console.log(`✅ [价格转换] 找到${symbol}价格: $${price} (来源symbol: ${foundSymbol})`)

      // 转换为orderbook格式
      return this.convertPriceToOrderbook(price, symbol)
    } catch (error: any) {
      console.log(`❌ [价格转换] 转换失败:`, error.message)
      return null
    }
  }

  /**
   * 将单一价格转换为orderbook格式
   */
  private convertPriceToOrderbook(price: number, symbol: string): any {
    // 生成虚拟的bid/ask spread (0.1%的价差)
    const spread = price * 0.001
    const bid = price - spread / 2
    const ask = price + spread / 2
    const midPrice = price

    return {
      bids: [
        { price: bid.toString(), qty: '1.0' },
        { price: (bid - spread).toString(), qty: '2.0' },
      ],
      asks: [
        { price: ask.toString(), qty: '1.0' },
        { price: (ask + spread).toString(), qty: '2.0' },
      ],
      timestamp: Date.now(),
      symbol: symbol,
      midPrice: midPrice,
    }
  }

  /**
   * 获取最新价格 (公开接口)
   */
  async getPrices(): Promise<any> {
    try {
      if (this.useWebSocket) {
        // 优先使用WebSocket
        logger.debug('使用WebSocket获取价格信息')
        const wsResult = await this.wsAdapter.getPrices()

        if (wsResult.success) {
          return wsResult.data
        } else {
          logger.warn('WebSocket获取价格信息失败，回退到HTTP', { error: wsResult.error })
        }
      }

      // 回退到HTTP请求
      logger.debug('使用HTTP获取价格信息')
      const response = await httpClient.get(`${this.baseUrl}/api/v1/info/prices`, {
        exchange: 'pacifica',
        timeout: 10000,
        retries: 2,
      })

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`)
      }

      return response.data
    } catch (error: any) {
      logger.error('获取Pacifica价格信息失败', { error: error.message })
      throw error
    }
  }

  /**
   * 创建市价单
   */
  async createMarketOrder(payload: OrderCreatePayload): Promise<any> {
    try {
      logger.info('创建Pacifica市价单', {
        symbol: payload.symbol,
        side: payload.side,
        amount: payload.amount,
        account: payload.account.substring(0, 8) + '...',
      })

      if (this.useWebSocket) {
        // 优先使用WebSocket
        logger.debug('使用WebSocket创建市价单')

        // 确保有签名
        if (!payload.signature) {
          logger.warn('WebSocket下单需要签名，回退到HTTP')
        } else {
          try {
            const wsResult = await this.wsAdapter.placeMarketOrder({
              symbol: payload.symbol,
              side: payload.side,
              amount: payload.amount,
              account: payload.account,
              signature: payload.signature,
              reduce_only: payload.reduceOnly || false,
              slippage_percent: '0.5',
            })

            if (wsResult.success) {
              logger.info('WebSocket市价单创建成功', {
                symbol: payload.symbol,
                side: payload.side,
                orderId: wsResult.orderId,
              })
              return wsResult
            } else {
              logger.warn('WebSocket市价单失败，回退到HTTP', { error: wsResult.error })
            }
          } catch (wsError: any) {
            logger.warn('WebSocket市价单异常，回退到HTTP', { error: wsError.message })
          }
        }
      }

      // 回退到HTTP方法
      logger.debug('使用HTTP创建市价单')
      const result = await this.ordersAdapter.createMarketOrder(payload)

      logger.info('Pacifica市价单创建成功', {
        symbol: payload.symbol,
        side: payload.side,
        orderId: result.orderId || result.order_id,
      })

      return result
    } catch (error: any) {
      logger.error('创建Pacifica市价单失败', {
        symbol: payload.symbol,
        side: payload.side,
        error: error.message,
      })
      throw error
    }
  }

  /**
   * 创建限价单
   */
  async createLimitOrder(payload: OrderCreatePayload): Promise<any> {
    try {
      logger.info('创建Pacifica限价单', {
        symbol: payload.symbol,
        side: payload.side,
        amount: payload.amount,
        price: payload.price,
        account: payload.account.substring(0, 8) + '...',
      })

      if (this.useWebSocket && payload.signature && payload.price) {
        // 优先使用WebSocket
        logger.debug('使用WebSocket创建限价单')

        try {
          const wsResult = await this.wsAdapter.placeLimitOrder({
            symbol: payload.symbol,
            side: payload.side,
            amount: payload.amount,
            price: payload.price,
            account: payload.account,
            signature: payload.signature,
            reduce_only: payload.reduceOnly || false,
          })

          if (wsResult.success) {
            logger.info('WebSocket限价单创建成功', {
              symbol: payload.symbol,
              side: payload.side,
              orderId: wsResult.orderId,
            })
            return wsResult
          } else {
            logger.warn('WebSocket限价单失败，回退到HTTP', { error: wsResult.error })
          }
        } catch (wsError: any) {
          logger.warn('WebSocket限价单异常，回退到HTTP', { error: wsError.message })
        }
      }

      // 回退到HTTP方法
      logger.debug('使用HTTP创建限价单')
      const result = await this.ordersAdapter.createLimitOrder(payload)

      logger.info('Pacifica限价单创建成功', {
        symbol: payload.symbol,
        side: payload.side,
        orderId: result.orderId || result.order_id,
      })

      return result
    } catch (error: any) {
      logger.error('创建Pacifica限价单失败', {
        symbol: payload.symbol,
        side: payload.side,
        amount: payload.amount,
        price: payload.price,
        account: payload.account.substring(0, 8) + '...',
        clientOrderId: payload.clientOrderId,
        tif: payload.tif,
        error: error.message,
        errorStack: error.stack,
        httpStatus: error.status || 'unknown',
        responseBody: error.response?.data || error.data || 'No response data',
        fullError: JSON.stringify(error, Object.getOwnPropertyNames(error))
      })

      // 尝试从错误消息中提取更多信息
      if (error.message && error.message.includes('HTTP')) {
        console.log('🔍 详细HTTP错误信息:', error.message)
      }

      throw error
    }
  }

  /**
   * 取消订单
   */
  async cancelOrder(payload: CancelOrderPayload): Promise<any> {
    try {
      logger.info('取消Pacifica订单', {
        symbol: payload.symbol,
        orderId: payload.orderId,
        clientOrderId: payload.clientOrderId,
        account: payload.account.substring(0, 8) + '...',
      })

      const result = await this.ordersAdapter.cancelOrder(payload)

      logger.info('Pacifica订单取消成功', {
        symbol: payload.symbol,
        orderId: payload.orderId,
      })

      return result
    } catch (error: any) {
      logger.error('取消Pacifica订单失败', {
        symbol: payload.symbol,
        orderId: payload.orderId,
        error: error.message,
      })
      throw error
    }
  }

  /**
   * 获取持仓信息
   */
  async getPositions(account?: string): Promise<any> {
    try {
      const accountToUse = account || this.client.requireAccount()

      if (this.useWebSocket) {
        // 优先使用WebSocket
        logger.debug('使用WebSocket获取持仓信息', { account: accountToUse.substring(0, 8) + '...' })
        const wsResult = await this.wsAdapter.getPositions(accountToUse)

        if (wsResult.success) {
          return wsResult
        } else {
          logger.warn('WebSocket获取持仓失败，回退到HTTP', { error: wsResult.error })
        }
      }

      // 回退到HTTP请求
      logger.debug('使用HTTP获取持仓信息', { account: accountToUse.substring(0, 8) + '...' })
      const result = await this.client.get('/api/v1/positions', { account: accountToUse })
      return result
    } catch (error: any) {
      logger.error('获取Pacifica持仓失败', { error: error.message })
      throw error
    }
  }

  /**
   * 获取余额信息
   */
  async getBalances(account?: string): Promise<any> {
    try {
      const accountToUse = account || this.client.requireAccount()

      if (this.useWebSocket) {
        // 优先使用WebSocket
        logger.debug('使用WebSocket获取余额信息', { account: accountToUse.substring(0, 8) + '...' })
        const wsResult = await this.wsAdapter.getBalances(accountToUse)

        if (wsResult.success) {
          return wsResult
        } else {
          logger.warn('WebSocket获取余额失败，回退到HTTP', { error: wsResult.error })
        }
      }

      // 回退到HTTP请求
      logger.debug('使用HTTP获取余额信息', { account: accountToUse.substring(0, 8) + '...' })
      const result = await this.client.get('/api/v1/account', { account: accountToUse })
      return result
    } catch (error: any) {
      logger.error('获取Pacifica余额失败', { error: error.message })
      throw error
    }
  }

  /**
   * 获取未成交订单
   */
  async getOpenOrders(symbol?: string, account?: string): Promise<any> {
    try {
      const result = await this.ordersAdapter.openOrders(symbol, account)
      logger.debug('获取Pacifica未成交订单成功', {
        count: Array.isArray(result) ? result.length : 'unknown',
        symbol,
        account: account?.substring(0, 8) + '...'
      })
      return result
    } catch (error: any) {
      logger.error('获取Pacifica未成交订单失败', {
        error: error.message,
        stack: error.stack,
        symbol,
        account: account?.substring(0, 8) + '...',
        response: error.response?.data || error.response || 'No response data'
      })
      throw error
    }
  }

  /**
   * 测试代理连接
   */
  async testConnection(): Promise<{
    success: boolean
    latency: number
    proxyUsed: boolean
    serverTime?: number
    error?: string
  }> {
    const startTime = Date.now()

    try {
      const result = await this.getServerTime()
      const latency = Date.now() - startTime
      const proxyUsed = Config.proxy.isAnyConfigured()

      logger.info('Pacifica连接测试成功', {
        latency: `${latency}ms`,
        proxy: proxyUsed ? '启用' : '禁用',
        serverTime: result.time,
      })

      return {
        success: true,
        latency,
        proxyUsed,
        serverTime: result.time,
      }
    } catch (error: any) {
      const latency = Date.now() - startTime

      logger.error('Pacifica连接测试失败', {
        latency: `${latency}ms`,
        error: error.message,
      })

      return {
        success: false,
        latency,
        proxyUsed: Config.proxy.isAnyConfigured(),
        error: error.message,
      }
    }
  }

  /**
   * 设置WebSocket模式
   */
  setWebSocketEnabled(enabled: boolean): void {
    this.useWebSocket = enabled
    logger.info(`WebSocket模式${enabled ? '启用' : '禁用'}`)
  }

  /**
   * 获取WebSocket连接状态
   */
  isWebSocketConnected(): boolean {
    return this.wsAdapter.isConnected()
  }

  /**
   * 获取WebSocket队列长度
   */
  getWebSocketQueueLength(): number {
    return this.wsAdapter.getQueueLength()
  }

  /**
   * 强制初始化WebSocket连接
   */
  async initializeWebSocket(): Promise<void> {
    try {
      await this.wsAdapter.initialize()
      logger.info('WebSocket连接初始化成功')
    } catch (error: any) {
      logger.error('WebSocket连接初始化失败', { error: error.message })
      throw error
    }
  }

  /**
   * 关闭所有连接并清理资源
   */
  async close(): Promise<void> {
    try {
      await this.wsAdapter.close()
      logger.info('PacificaProxyClient资源清理完成')
    } catch (error: any) {
      logger.error('PacificaProxyClient清理失败', { error: error.message })
    }
  }
}
