#!/usr/bin/env tsx

/**
 * 生产环境完整交易系统启动器
 * Production Complete Trading System Launcher
 *
 * 基于 main-complete.ts 的生产级部署版本
 */

import { CompleteTradingSystem } from './src/main-complete.js'
import { ProductionLogger } from './src/utils/ProductionLogger.js'
import * as fs from 'fs'
import * as http from 'http'

class ProductionSystemRunner {
  private system?: CompleteTradingSystem
  private logger: ProductionLogger
  private isShuttingDown = false
  private healthCheckServer?: http.Server
  private systemStartTime = Date.now()

  constructor() {
    this.logger = ProductionLogger.getInstance({
      level: (process.env.LOG_LEVEL as any) || 'info',
      enableFile: true,
      logDir: process.env.LOG_DIR || './logs',
      enableConsole: true,
      enableAudit: true,
    })
  }

  async start() {
    this.displayBanner()
    this.setupSignalHandlers()
    this.startHealthCheck()

    this.logger.info('🚀 启动生产级交易系统', {
      nodeEnv: process.env.NODE_ENV,
      pid: process.pid,
      memory: process.memoryUsage(),
      version: '1.0.0',
    })

    try {
      // 环境检查
      this.performEnvironmentCheck()

      // 创建并启动完整交易系统
      this.system = new CompleteTradingSystem()

      // 绑定生产环境监听器
      this.setupProductionEventHandlers()

      // 启动系统
      await this.system.start()

      this.logger.info('✅ 生产系统启动成功', {
        healthCheckUrl: 'http://localhost:3001/health',
        uptime: Date.now() - this.systemStartTime,
      })

      console.log(`
✅ 🚀 生产级交易系统已启动！

📊 监控地址:
   - 健康检查: http://localhost:3001/health
   - 系统状态: http://localhost:3001/status
   - 性能指标: http://localhost:3001/metrics

🔧 管理命令:
   - curl http://localhost:3001/health     # 检查系统健康
   - kill -TERM ${process.pid}            # 优雅关闭
   - kill -USR1 ${process.pid}            # 重载配置

📁 日志位置: ${process.env.LOG_DIR || './logs'}
`)

      // PM2 兼容性
      if (process.send) {
        process.send('ready')
      }

      // 保持运行并启动监控
      this.startSystemMonitoring()
    } catch (error: any) {
      this.logger.critical('❌ 生产系统启动失败', error)
      console.error('❌ 生产系统启动失败:', error.message)
      process.exit(1)
    }
  }

  private displayBanner() {
    console.log(`
██████  ██████   ██████  ██████  ██    ██  ██████ ████████ ██  ██████  ███    ██
██   ██ ██   ██ ██    ██ ██   ██ ██    ██ ██         ██    ██ ██    ██ ████   ██
██████  ██████  ██    ██ ██   ██ ██    ██ ██         ██    ██ ██    ██ ██ ██  ██
██      ██   ██ ██    ██ ██   ██ ██    ██ ██         ██    ██ ██    ██ ██  ██ ██
██      ██   ██  ██████  ██████   ██████   ██████    ██    ██  ██████  ██   ████

🌟 生产级完整交易系统 v1.0.0
🔥 多平台对冲 | 实时监控 | 自动化交易 | 风险控制

启动时间: ${new Date().toLocaleString('zh-CN')}
进程 ID: ${process.pid}
Node.js: ${process.version}
内存: ${Math.round(process.memoryUsage().rss / 1024 / 1024)}MB
    `)
  }

  private performEnvironmentCheck() {
    const required = ['NODE_ENV']

    const missing = required.filter(env => !process.env[env])
    if (missing.length > 0) {
      this.logger.warn('⚠️ 缺少环境变量', { missingVars: missing })
    }

    // 检查日志目录
    const logDir = process.env.LOG_DIR || './logs'
    if (!fs.existsSync(logDir)) {
      fs.mkdirSync(logDir, { recursive: true })
      this.logger.info('📁 创建日志目录', { logDir })
    }

    this.logger.info('✅ 环境检查完成', {
      nodeEnv: process.env.NODE_ENV,
      logDir,
    })
  }

  private startHealthCheck() {
    this.healthCheckServer = http.createServer((req, res) => {
      const url = req.url || ''

      // CORS 支持
      res.setHeader('Access-Control-Allow-Origin', '*')
      res.setHeader('Content-Type', 'application/json')

      if (url === '/health') {
        const health = {
          status: 'healthy',
          timestamp: new Date().toISOString(),
          uptime: process.uptime(),
          memory: process.memoryUsage(),
          pid: process.pid,
          system: this.system ? 'running' : 'starting',
          version: '1.0.0',
        }

        res.writeHead(200)
        res.end(JSON.stringify(health, null, 2))
      } else if (url === '/status' && this.system) {
        try {
          const stats = this.system.getSystemStats()
          res.writeHead(200)
          res.end(JSON.stringify(stats, null, 2))
        } catch (error: any) {
          res.writeHead(500)
          res.end(JSON.stringify({ error: error.message }))
        }
      } else if (url === '/metrics') {
        const metrics = {
          timestamp: new Date().toISOString(),
          uptime: process.uptime(),
          memory: process.memoryUsage(),
          cpu: process.cpuUsage(),
          startTime: this.systemStartTime,
          systemActive: !!this.system,
        }

        res.writeHead(200)
        res.end(JSON.stringify(metrics, null, 2))
      } else {
        res.writeHead(404)
        res.end(JSON.stringify({ error: 'Not Found' }))
      }
    })

    this.healthCheckServer.listen(3001, () => {
      console.log('🏥 健康检查服务器已启动: http://localhost:3001/health')
    })

    this.healthCheckServer.on('error', (error: any) => {
      this.logger.error('健康检查服务器错误', error)
    })
  }

  private setupProductionEventHandlers() {
    if (!this.system) return

    // 系统级事件
    this.system.on('error', (error: Error) => {
      this.logger.error('🚨 系统错误', error)

      if (error.message.includes('FATAL')) {
        this.logger.critical('💀 致命错误，准备重启', error)
        this.attemptSystemRestart()
      }
    })

    this.system.on('warning', (warning: string) => {
      this.logger.warn(`⚠️ 系统警告: ${warning}`)
    })

    // 交易事件
    this.system.on('trade_executed', (data: any) => {
      this.logger.trade('订单执行', {
        exchange: data.exchange,
        symbol: data.symbol,
        side: data.side,
        quantity: data.quantity,
        price: data.price,
        orderId: data.orderId,
      })
    })

    // 对冲事件
    this.system.on('hedge_executed', (data: any) => {
      this.logger.hedge('对冲执行', {
        sourceExchange: data.sourceExchange,
        targetExchange: data.targetExchange,
        symbol: data.symbol,
        quantity: data.quantity,
        reason: data.reason,
      })
    })
  }

  private startSystemMonitoring() {
    // 心跳检查 (每分钟)
    const heartbeatInterval = setInterval(async () => {
      if (this.isShuttingDown) {
        clearInterval(heartbeatInterval)
        return
      }

      try {
        if (this.system) {
          const stats = await this.system.getSystemStats()
          this.logger.info('💓 系统心跳', {
            accounts: stats.accounts.total,
            connections: stats.connections.active,
            dailyTrades: stats.trading.dailyTrades,
            uptime: Math.round(process.uptime()),
          })
        }
      } catch (error: any) {
        this.logger.warn(`心跳检查失败: ${error.message}`)
      }
    }, 60000)

    // 内存监控 (每30秒)
    const memoryInterval = setInterval(() => {
      if (this.isShuttingDown) {
        clearInterval(memoryInterval)
        return
      }

      const usage = process.memoryUsage()
      const memoryMB = Math.round(usage.rss / 1024 / 1024)

      this.logger.performance('内存使用', memoryMB, {
        heap: Math.round(usage.heapUsed / 1024 / 1024),
        external: Math.round(usage.external / 1024 / 1024),
      })

      // 内存警告
      if (memoryMB > 500) {
        this.logger.warn(`⚠️ 内存使用过高: ${memoryMB}MB`)
      }

      // 内存泄漏检测
      if (memoryMB > 1000) {
        this.logger.critical(`🚨 内存可能泄漏: ${memoryMB}MB`)
      }
    }, 30000)
  }

  private setupSignalHandlers() {
    // 优雅关闭信号
    ;['SIGTERM', 'SIGINT'].forEach(signal => {
      process.on(signal, () => {
        console.log(`\n🛑 收到 ${signal} 信号，开始优雅关闭...`)
        this.gracefulShutdown()
      })
    })

    // 重载配置信号 (生产环境热更新)
    process.on('SIGUSR1', () => {
      this.logger.info('🔄 收到重载配置信号')
      this.reloadConfiguration()
    })

    // 错误处理
    process.on('uncaughtException', error => {
      this.logger.critical('💥 未捕获异常', error)
      console.error('💥 未捕获异常:', error)
      this.gracefulShutdown()
    })

    process.on('unhandledRejection', reason => {
      this.logger.critical('💥 未处理的Promise拒绝', undefined, { reason })
      console.error('💥 未处理的Promise拒绝:', reason)
    })
  }

  private async attemptSystemRestart() {
    this.logger.info('🔄 尝试系统自动恢复...')

    try {
      if (this.system) {
        await this.system.shutdown()
        this.system = undefined
      }

      // 等待5秒
      await new Promise(resolve => setTimeout(resolve, 5000))

      // 重新创建系统
      this.system = new CompleteTradingSystem()
      this.setupProductionEventHandlers()
      await this.system.start()

      this.logger.info('✅ 系统自动恢复成功')
    } catch (error: any) {
      this.logger.critical('❌ 系统自动恢复失败', error)
      process.exit(1)
    }
  }

  private async reloadConfiguration() {
    try {
      this.logger.info('🔧 开始重载配置...')

      // 这里可以实现配置热更新逻辑
      // 例如重新读取环境变量、配置文件等

      this.logger.info('✅ 配置重载完成')
    } catch (error: any) {
      this.logger.error('❌ 配置重载失败', error)
    }
  }

  private async gracefulShutdown() {
    if (this.isShuttingDown) return
    this.isShuttingDown = true

    const shutdownStart = Date.now()

    try {
      this.logger.info('🛑 开始优雅关闭系统...')

      // 1. 停止接受新请求
      if (this.healthCheckServer) {
        this.healthCheckServer.close()
        this.logger.info('✅ 健康检查服务器已关闭')
      }

      // 2. 关闭交易系统
      if (this.system) {
        await this.system.shutdown()
        this.logger.info('✅ 交易系统已关闭')
      }

      // 3. 等待现有操作完成 (最多30秒)
      const maxWait = 30000
      const remaining = maxWait - (Date.now() - shutdownStart)
      if (remaining > 0) {
        this.logger.info(`⏱️ 等待现有操作完成... (最多${remaining}ms)`)
        await new Promise(resolve => setTimeout(resolve, Math.min(remaining, 5000)))
      }

      const shutdownTime = Date.now() - shutdownStart
      this.logger.info(`✅ 系统优雅关闭完成 (用时${shutdownTime}ms)`)

      // 关闭日志系统
      this.logger.close()

      process.exit(0)
    } catch (error: any) {
      this.logger.critical('❌ 优雅关闭失败', error)
      console.error('❌ 优雅关闭失败:', error)
      process.exit(1)
    }
  }
}

// 启动生产系统
if (import.meta.url === `file://${process.argv[1]}`) {
  // 设置默认环境变量
  process.env.NODE_ENV = process.env.NODE_ENV || 'production'

  const runner = new ProductionSystemRunner()
  runner.start().catch(error => {
    console.error('❌ 系统启动失败:', error)
    process.exit(1)
  })
}

export { ProductionSystemRunner }
