import { StopLossOrder, TakeProfitOrder, TradingService, ServiceStatus } from '../types.js'
import { AccountManager } from '../account/AccountManager.js'
import { CacheManager } from '../cache/CacheManager.js'
import { logger } from '../../utils/logger.js'

/**
 * 止盈止损服务 - 管理止损订单和价格监控
 */
export class StopLossService implements TradingService {
  private activeStopLossOrders = new Map<string, StopLossOrder>()
  private activeTakeProfitOrders = new Map<string, TakeProfitOrder>()
  private lastPriceCheck = new Map<string, { price: number; timestamp: number }>()
  private monitoringIntervals = new Map<string, NodeJS.Timeout>()

  private stopLossConfig = {
    defaultStopLoss: 0.015, // 1.5% 止损
    defaultTakeProfit: 0.025, // 2.5% 止盈
    enableTrailing: true, // 启用追踪止损
    trailingPercent: 0.005, // 0.5% 追踪止损
  }

  constructor(
    private accountManager: AccountManager,
    private cacheManager: CacheManager,
  ) {}

  async initialize(): Promise<void> {
    logger.info('StopLossService初始化')
  }

  async start(): Promise<void> {
    logger.info('StopLossService启动')
  }

  async stop(): Promise<void> {
    logger.info('StopLossService停止')
    // 清理所有监控间隔
    this.monitoringIntervals.forEach(interval => clearInterval(interval))
    this.monitoringIntervals.clear()
    this.activeStopLossOrders.clear()
    this.activeTakeProfitOrders.clear()
  }

  getStatus(): ServiceStatus {
    return {
      name: 'StopLossService',
      status: 'running',
      lastUpdate: Date.now(),
      details: {
        activeStopLoss: this.activeStopLossOrders.size,
        activeTakeProfit: this.activeTakeProfitOrders.size,
        monitoringSymbols: this.monitoringIntervals.size,
      },
    }
  }

  /**
   * 设置止盈止损订单
   */
  async setupStopLossAndTakeProfit(params: {
    parentOrderId: string
    symbol: string
    amount: string
    side: 'buy' | 'sell'
    currentPrice: number
    clientId: string
    stopLoss?: number
    takeProfit?: number
    enableTrailing?: boolean
  }): Promise<void> {
    const {
      parentOrderId,
      symbol,
      amount,
      side,
      currentPrice,
      clientId,
      stopLoss,
      takeProfit,
      enableTrailing = false,
    } = params

    try {
      // 计算止损价格
      let stopLossPrice: number | undefined
      if (stopLoss) {
        stopLossPrice = stopLoss
      } else {
        const stopLossPercent = this.stopLossConfig.defaultStopLoss
        if (side === 'buy') {
          stopLossPrice = currentPrice * (1 - stopLossPercent)
        } else {
          stopLossPrice = currentPrice * (1 + stopLossPercent)
        }
      }

      // 计算止盈价格
      let takeProfitPrice: number | undefined
      if (takeProfit) {
        takeProfitPrice = takeProfit
      } else {
        const takeProfitPercent = this.stopLossConfig.defaultTakeProfit
        if (side === 'buy') {
          takeProfitPrice = currentPrice * (1 + takeProfitPercent)
        } else {
          takeProfitPrice = currentPrice * (1 - takeProfitPercent)
        }
      }

      // 创建止损订单
      if (stopLossPrice) {
        const stopLossOrder: StopLossOrder = {
          orderId: `sl_${parentOrderId}_${Date.now()}`,
          symbol,
          amount,
          stopPrice: stopLossPrice,
          side: side === 'buy' ? 'sell' : 'buy',
          accountId: clientId,
          timestamp: Date.now(),
          isActive: true,
        }

        this.activeStopLossOrders.set(stopLossOrder.orderId, stopLossOrder)
        logger.info('止损订单已设置', {
          orderId: stopLossOrder.orderId,
          stopPrice: stopLossPrice,
          enableTrailing,
        })
      }

      // 创建止盈订单
      if (takeProfitPrice) {
        const takeProfitOrder: TakeProfitOrder = {
          orderId: `tp_${parentOrderId}_${Date.now()}`,
          symbol,
          amount,
          targetPrice: takeProfitPrice,
          side: side === 'buy' ? 'sell' : 'buy',
          accountId: clientId,
          timestamp: Date.now(),
          isActive: true,
        }

        this.activeTakeProfitOrders.set(takeProfitOrder.orderId, takeProfitOrder)
        logger.info('止盈订单已设置', {
          orderId: takeProfitOrder.orderId,
          targetPrice: takeProfitPrice,
        })
      }

      // 启动价格监控
      if (stopLossPrice || takeProfitPrice) {
        this.startPriceMonitoring(symbol)
      }

      console.log(
        `🎯 止盈止损已设置: ${stopLossPrice ? `止损@$${stopLossPrice.toFixed(2)}` : ''} ${
          takeProfitPrice ? `止盈@$${takeProfitPrice.toFixed(2)}` : ''
        }`,
      )
    } catch (error: any) {
      logger.error('设置止盈止损失败', { error: error.message, params })
    }
  }

  /**
   * 启动价格监控
   */
  private startPriceMonitoring(symbol: string): void {
    // 避免重复启动监控
    if (this.monitoringIntervals.has(symbol)) {
      return
    }

    this.lastPriceCheck.set(symbol, { price: 0, timestamp: Date.now() })

    // 每5秒检查一次价格触发
    const monitoringInterval = setInterval(async () => {
      try {
        await this.checkStopLossAndTakeProfitTriggers(symbol)

        // 如果没有活跃的止盈止损订单，停止监控
        const hasActiveOrders =
          Array.from(this.activeStopLossOrders.values()).some(order => order.symbol === symbol && order.isActive) ||
          Array.from(this.activeTakeProfitOrders.values()).some(order => order.symbol === symbol && order.isActive)

        if (!hasActiveOrders) {
          clearInterval(monitoringInterval)
          this.monitoringIntervals.delete(symbol)
          this.lastPriceCheck.delete(symbol)
          logger.info(`价格监控已停止: ${symbol}`)
        }
      } catch (error: any) {
        logger.error('价格监控检查失败', { symbol, error: error.message })
      }
    }, 5000)

    this.monitoringIntervals.set(symbol, monitoringInterval)
    logger.info(`价格监控已启动: ${symbol}`)
  }

  /**
   * 检查止盈止损触发条件
   */
  private async checkStopLossAndTakeProfitTriggers(symbol: string): Promise<void> {
    try {
      const currentPrice = await this.getCurrentPrice(symbol)

      // 检查止损触发
      for (const [orderId, stopLossOrder] of this.activeStopLossOrders) {
        if (!stopLossOrder.isActive || stopLossOrder.symbol !== symbol) continue

        const shouldTrigger =
          stopLossOrder.side === 'sell'
            ? currentPrice <= stopLossOrder.stopPrice
            : currentPrice >= stopLossOrder.stopPrice

        if (shouldTrigger) {
          await this.executeTrigger('stop_loss', stopLossOrder, currentPrice)
        }
      }

      // 检查止盈触发
      for (const [orderId, takeProfitOrder] of this.activeTakeProfitOrders) {
        if (!takeProfitOrder.isActive || takeProfitOrder.symbol !== symbol) continue

        const shouldTrigger =
          takeProfitOrder.side === 'sell'
            ? currentPrice >= takeProfitOrder.targetPrice
            : currentPrice <= takeProfitOrder.targetPrice

        if (shouldTrigger) {
          await this.executeTrigger('take_profit', takeProfitOrder, currentPrice)
        }
      }

      // 更新价格检查记录
      this.lastPriceCheck.set(symbol, { price: currentPrice, timestamp: Date.now() })
    } catch (error: any) {
      logger.error('检查止盈止损触发失败', { symbol, error: error.message })
    }
  }

  /**
   * 执行止盈止损触发
   */
  private async executeTrigger(
    type: 'stop_loss' | 'take_profit',
    order: StopLossOrder | TakeProfitOrder,
    currentPrice: number,
  ): Promise<void> {
    try {
      const client = this.accountManager.getClient(order.accountId)
      if (!client) {
        logger.error(`客户端 ${order.accountId} 不可用，无法执行${type}`)
        return
      }

      const side = order.side === 'sell' ? 'ask' : 'bid'
      const triggerPrice = 'stopPrice' in order ? order.stopPrice : order.targetPrice

      logger.info(`执行${type}触发`, {
        orderId: order.orderId,
        symbol: order.symbol,
        triggerPrice,
        currentPrice,
        side: order.side,
      })

      // 执行平仓订单
      const accounts = this.accountManager.getAllAccountStates()
      const firstAccount = Array.from(accounts.keys())[0]
      const accountData = this.accountManager.getAccountState(firstAccount)

      if (!accountData) {
        logger.error('无法获取账户数据执行止损')
        return
      }

      const result = await client.createMarketOrder({
        account: accountData.toString(), // 需要实际的账户ID
        symbol: 'BTCUSDT',
        amount: order.amount,
        side: side,
        reduceOnly: true,
        slippagePercent: '5.0',
      })

      if (result.success) {
        // 标记订单为已执行
        if (type === 'stop_loss') {
          ;(order as StopLossOrder).isActive = false
        } else {
          ;(order as TakeProfitOrder).isActive = false
        }

        const emoji = type === 'stop_loss' ? '🛑' : '🎯'
        const typeText = type === 'stop_loss' ? '止损' : '止盈'

        console.log(
          `${emoji} ${typeText}触发成功: ${order.symbol} @ $${currentPrice.toFixed(2)} (目标: $${triggerPrice.toFixed(
            2,
          )})`,
        )

        // 更新账户状态
        this.accountManager.updateTradeState(order.accountId, {
          side: order.side,
          amount: order.amount,
          success: true,
        })
      } else {
        logger.error(`${type}执行失败`, { error: result.error, order })
      }
    } catch (error: any) {
      logger.error(`执行${type}触发失败`, { error: error.message, order })
    }
  }

  /**
   * 获取当前市场价格
   */
  private async getCurrentPrice(symbol: string): Promise<number> {
    try {
      // 使用缓存的价格数据
      const cachedPrice = this.cacheManager.get(`price_${symbol}`, this.cacheManager.getTTL('ticker'))

      if (cachedPrice && typeof cachedPrice === 'number') {
        return cachedPrice
      }

      // 缓存未命中，使用估算价格
      const estimatedPrice = symbol.includes('BTC') ? 65000 : 3500
      this.cacheManager.set(`price_${symbol}`, estimatedPrice, this.cacheManager.getTTL('ticker'))

      logger.warn(`无法获取${symbol}实时价格，使用估算价格: $${estimatedPrice}`)
      return estimatedPrice
    } catch (error: any) {
      logger.error('获取当前价格失败', { symbol, error: error.message })
      return symbol.includes('BTC') ? 65000 : 3500
    }
  }

  /**
   * 获取活跃订单统计
   */
  getActiveOrdersStats() {
    return {
      stopLossOrders: this.activeStopLossOrders.size,
      takeProfitOrders: this.activeTakeProfitOrders.size,
      monitoringSymbols: this.monitoringIntervals.size,
    }
  }
}
